文章目录
- 一、什么是MyBatis
- 二、Mybatis入门案例
- 三、配置SQL提示
- 四、数据库连接池
- 四、lombok
- 五、mybatis基础操作
- 5.1 根据id删除
- 5.2 预编译SQL
- 5.3 新增员工
- 5.4 更新员工
- 5.5 查询员工(用于页面回显)
- 5.6 条件查询
 
- 七、XML映射文件
- 八、动态SQL
- 8.1 if语句
- 8.2 foreach语句
- 8.3 sql/include语句
 
- 小结
一、什么是MyBatis
MyBatis是一款优秀的持久层框架,用于简化JDBC的开发
 
二、Mybatis入门案例
使用MyBatis查询所有用户的数据
 
三、配置SQL提示

四、数据库连接池
数据库连接池是个容器,负责分配,管理数据库连接(Connection)
 它允许应用程序重复使用一个现有的数据库连接,而不是在重新建立一个
 释放空间时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏

- 如果没有连接池,每次访问数据库时候,需要开启一个新的连接,用完需要关闭,比较浪费资源
- 有了数据库连接池,程序在初始化的时候,会在这个容器中创建一定量的连接对象,后面客户端在访问数据库时候,会在连接池中来获取连接,用完之后再归还,就可以做到连接的复用,而不用每次都新建一个在关闭
数据库连接池的优势:
- 资源重用
- 提升系统响应速度
- 避免数据库连接遗漏
标准接口:DataSource
- 官方提供的数据库连接池接口,由第三方组织实现此接口
- 功能:获取连接
Connection getConnection() throws SQLException;

 Springboot默认Hikari(追光者)
Druid(德鲁伊):
- Druid连接池是阿里巴巴开源的数据库连接池项目
- 功能强大,性能优秀,是Java语言最好的数据库连接池之一
四、lombok
lombok是一个使用的Java类库,能够通过注解的形式自动生成构造器,getter/setter,equals,hashcode,tostring等方法,并可以自动化生成日志变量,简化Java开发,提高效率
| 注解 | 作用 | 
|---|---|
| @Getter/Setter | 为所有的属性提供get/set方法 | 
| @ToString | 给雷自动生成toString方法。 | 
| @EqualsAndHashCode | 根据类所拥有的非静态字段自动重写equals方法和hashCode方法 | 
| @Data | 注解在类,生成setter/getter、equals、canEqual、hashCode、toString方法,如为final属性,则不会为该属性生成setter方法。 | 
| @NoArgsConstructor | 生成无参的构造方法。 | 
| @AllArgsConstructor | 生成包含类中所有字段的构造方法。 | 

 需要在pom.xml中加入lombok依赖
五、mybatis基础操作
准备工作
- 准备数据表emp
- 创建一个新的springboot工程,引入起步依赖(mybatis,mysql驱动,lombok)
- 配置文件中引入数据库的连接信息
- 创建Emp实体类(采用驼峰命名法)
- 准备Mapper接口EmpMapper
  
5.1 根据id删除
在mapper接口中写入代码如下:
@Mapper
public interface EmpMapper {
//    根据id删除@Delete("delete from mybatis.emp where id = #{id}")public void  delect(Integer id);
}
在测试类中调用如下:
@SpringBootTest //整合单元测试的类
class SpringbootMybatisApplicationTests {@Autowiredprivate EmpMapper empMapper;@Testpublic void test(){int delete = empMapper.delect(17);System.out.println(delect)}
}
返回值为1(受影响的行数):
 

5.2 预编译SQL

 性能更高
 更安全(防止SQL注入)
 
只需要编译一次,后面直接把参数传进去就可以执行,所以性能更高,

5.3 新增员工
在mapper接口中写入代码如下:
//    新增员工@Insert("insert mybatis.emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) " +"values (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})")public void insert(Emp emp);
在测试类中测试如下:

 
 useGeneratedKeys:是否要获取到返回来的数据
 keyProperty:返回来的数据往那个地方封装
5.4 更新员工
在mapper接口中写入代码如下:
//    更新员工@Update("update mybatis.emp set username = #{username},name = #{name},gender = #{gender},image = #{image}" +",job = #{job},entrydate = #{entrydate},dept_id = #{dept_id},create_time = #{createTime},update_time = #{updateTime}")public void update(Emp emp);
在测试类中测试如下:

5.5 查询员工(用于页面回显)
在mapper接口中写入代码如下:
//    根据id查询员工@Select("select * from mybatis.emp where id = #{}")public Emp getById(Integer id);
在测试类中测试如下:
 
 运行结果如下:
 
 但是运行结果中,其中dept_id,creat_time,update_time 并没有结果
原因是因为没有进行数据封装
 
 开启mybatis自动映射开关
 在application配置文件中
 
5.6 条件查询
//    条件查询员工@Select("select * from mybatis.emp where name like concat('%','#{name}','%') and gender = #{gender} and" +" entrydate between #{begin} and #{end} order by update_time desc " )public List<Emp> list(String name , Short gender , LocalDate begin , LocalDate end);
运行结果
 
七、XML映射文件
规范:
- XML映射文件的名称与Mapper接口名称保持一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)
- XML映射文件的namespace属性为Mapper接口全限定名一致
- XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致


以xml定义sql语句例如:
 先加上xml约束
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--     nampespace 绑定Mapper接口的全名-->
<mapper namespace="com.itzhangxx.mapper.EmpMapper"><!--     条件查询员工--><select id="list" resultType="com.itzhangxx.Pojo.Emp">select * from mybatis.emp where name like concat('%','#{name}','%') and gender = #{gender} andentrydate between #{begin} and #{end} order by update_time desc</select>
</mapper>
八、动态SQL
8.1 if语句
随着用户的输入或外部条件的变化而变化的SQL语句,称为动态SQL
<mapper namespace="com.itzhangxx.mapper.EmpMapper"><!--     条件查询员工--><select id="list" resultType="com.itzhangxx.Pojo.Emp">select *from mybatis.emp<where><if test="name != null">name like concat('%', '#{name}', '%')</if><if test="gender != null">and gender = #{gender}</if><if test="begin != null and end != null">and entrydate between #{begin} and #{end}</if><where>order by update_time desc</select>
</mapper>
这样就可以动态的满足需求的再进行SQL的查找
优化上面更新员工代码:
 原SQL:
@Update("update mybatis.emp set username = #{username},name = #{name},gender = #{gender},image = #{image}" +",job = #{job},entrydate = #{entrydate},dept_id = #{dept_id},create_time = #{createTime},update_time = #{updateTime}")public void update(Emp emp);
改造后如下
    <update id="update2">update mybatis.emp<set><if test="username != null">username = #{username},</if><if test="name != null">name = #{name},</if><if test="gender != null">gender = #{gender},</if><if test="image != null">image = #{image},</if><if test="job != null">job = #{job},</if><if test="entrydate != null">entrydate = #{entrydate},</if><if test="deptId != null">dept_id = #{dept_id},</if><if test="updateTime != null">update_time = #{updateTime},</if> </set></update>
- <if>:用于判断条件是否成立,使用test属性进行条件判断,如果条件为true,则拼接SQL
- <where>:只用于在子元素有内容的情况下才插入where子句,而且会自动取出子句的开头的AND 或 OR
- <set>:动态的在行首插入set关键字,会删除额外的逗号(用于update中)
8.2 foreach语句
如果想要删除多个员工数据的话,就可以使用foreach语句进行遍历
 例如:
    <delete id="deleteById">delete from mybatis.emp where id in<foreach collection="ids" item="id"  open="(" separator="," close=")">#{id}</foreach></delete>
测试如下:传入11,12,13,14
    @Testpublic void testDeleteById(){List<Integer> ids = Arrays.asList(11,12,13,14);empMapper.deleteById(ids);return ;}
然后实际执行的sql语句如下:
delete from mybatis.emp where id in(11,12,13,14)
| 属性 | 含义 | 
|---|---|
| collection | 要遍历的集合 | 
| item | 遍历出来的元素 | 
| separator | 分隔符 | 
| open | 遍历开始前拼接的片段 | 
| close | 遍历结束后的拼接的片段 | 
8.3 sql/include语句
在查找中不建议使用select * ,会降低代码效率,但是输入全部字段的话,也会有大量重复的,所以 使用<sql>定义相同的SQL,并且设定唯一标识,使用<include>调用这个唯一标识即可
 

 实现效果如下:
    <sql id="selectAll">select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_timefrom mybatis.emp</sql><!--     条件查询员工--><select id="list" resultType="com.itzhangxx.Pojo.Emp"><include refid="selectAll"></include><where><if test="name != null">name like concat('%', '#{name}', '%')</if><if test="gender != null">and gender = #{gender}</if><if test="begin != null and end != null">and entrydate between #{begin} and #{end}</if></where>order by update_time desc</select>
重点规范:
- XML映射文件的名称与Mapper接口名称保持一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)
- XML映射文件的namespace属性为Mapper接口全限定名一致
- XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致
| 语句 | 含义 | 
|---|---|
| <if> | 用于判断条件是否成立,使用test属性进行条件判断,如果条件为true,则拼接SQL | 
| <where> | 只用于在子元素有内容的情况下才插入where子句,而且会自动取出子句的开头的AND 或 OR | 
| <set> | 动态的在行首插入set关键字,会删除额外的逗号(用于update中) | 
| <foreach> | 按照规范进行遍历 | 
| <sql> | 使用<sql>定义相同的SQL,并且设定唯一标识 | 
| <include> | 使用中按照唯一标识进行调用定义的SQL | 
小结
写本文主要是为了分享我的学习过程,也是给自己记个笔记,哪里忘记了,回来再看一眼,也可以很快的回想起来