MyBatis
MyBatis
1. 什么是MyBatis
-
MyBatis是一款优秀的持久层框架,用于简化JDBC开发
1.1 持久层
- 负责将数据保存到数据库的一层代码
- JavaEE三层架构:表现层、业务层、持久层
1.2 框架
- 框架就是一个半成品软件,是一套可重用的、通用的、软件基础代码模型
- 在框架基础之上构架软件编写更加高效、规范、通用、可扩展
1.3 JDBC缺点
- 硬编码
- 注册驱动,获取连接
- SQL语句
- 操作繁琐
- 手动设置参数
- 手动封装结果集
1.4 MyBatis简化
2. MyBatis快速入门
查询user表中所有数据
-
创建user表,添加数据
-
创建模块,导入坐标
-
编写MyBatis核心配置文件 --> 替换连接信息,解决硬编码问题
-
编写SQL映射文件 --> 统一管理sql语句,解决硬编码问题
-
编码
// 1. 定义POJO类 public class User{} // 2. 加载核心配置文件,获取SqlSeesionFactory对象 String resource = "mybatis-config.xml"; InputStream in = Resources.getResourceAsStream(resource); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); // 3. 获取SqlSession对象,执行SQL语句 SqlSession session = factory.openSession(); List<User> users = session.selectList("test.selectAll"); // 4. 释放资源
2.1 解决SQL映射文件的警告提示
- 产生原因:Idea和数据库没有建立连接,不识别表信息
- 解决方式:在Idea中配置MySQL数据库连接
3. Mapper代理开发
- 解决原生方式中的硬编码
- 简化后期执行SQL
// 3. 获取接口代理对象
UserMppaer userMapper = sqlSession.getMapper(userMapper.class);
// 4. 执行方法,其实就是执行sql语句
List<User> users = userMapper.selectAll();
3.1 入门案例
- 定义与SQL映射文件同名的Mapper接口,并且将Mapper接口与SQL映射文件放置同一目录下
- 设置SQL映射文件的namespace属性为Mapper接口全限定名
- 在Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致
- 编码
- 通过SqlSession的getMapper()方法获取Mapper接口的代理对象
- 调用对应方法完成sql执行
细节:如果Mapper接口名称与SQL映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载。
4. MyBatis核心配置文件
https://mybatis.org/mybatis-3/zh/index.html
- configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- environment(环境变量)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
细节:注意遵守各个标签的前后顺序
5. 配置文件完成增删改查
- 编写接口方法:Mapper接口
- 编写SQL语句:SQL映射文件
- 执行方法,测试
数据库的字段名称和实体类的属性名称不一样导致不能自动封装:
-
起别名:对不一样的列名起别名,让别名和实体类的属性名一样。
-
缺点:每次查询都要定义一次别名
-
解决:sql片段brand_column
<sql id="xxx"> id, brand_name as bradName </sql>
-
-
resultMap:
<!--id:唯一标识;type:映射类型,支持别名--> <resultMap id="xxxResultMap" type="xxx"> <!--id:主键映射;result:一般自动映射;cilumn表的列名,property实体类的属性名--> <result column="xxx_xxx" property="xxxXxx"/> </resultMap>
5.1 参数占位符
-
{}:会将其替换为?,防止SQL注入
- ${}:拼sql,存在SQL诸如问题
- 使用时机:
- 参数传递时:#{}
- 表名或列名不固定的情况下:${}
5.2 参数类型:parameterType(可省略)
SQL语句设置多个参数的几种方式?
- 散装参数:需要使用@Param("SQL中参数占位符名称")
- 实体类封装参数:只需要保证SQL中参数名与实体类属性名对应上
- map集合:只需要保证SQL中参数名和map集合的键的名称对应上
5.3 查询 - 动态条件查询
SQL语句会随着用户输入或外部条件变化而变化。
- if 用于判断参数是否有值,使用test属性进行条件判断
- 问题:第一个条件不需要逻辑运算符 and/or
- 恒等式
替换where关键字
- choose(when ptherwise)
- trim(where set)
- foreach
5.4 添加 - 主键返回
数据添加成功后,需要获取插入数据库数据的主键的值
<insert useGeneratedKeys="true" keyProperty="id">
</insert>
5.5 修改 - 动态字段修改
<update id="update">
update xx from xx
<set>
<if test="name!=null and name!=''">
name = #{name}
</if>
</set>
</update>
5.6 删除 - 批量删除
<!--mybtis会将数组参数封装为一个Map集合,默认:array=数组;使用@Param注解改变map集合的默认key名称-->
<delete id="deleteByIds">
delete from xx
where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
5.7 MyBatis事务
- openSession():默认开启事务,进行增删改的操作后使用sqlSession.commite()手动提交事务
- openSession(true):可以设置为自动提交事务(关闭事务)
5.8 特殊字符处理:
- 转义字符 <
- CDATA区 <![CDATA[ 内容 ]]
5.9 参数传递
MyBatis接口方法中可以接收各种各样的参数,MyBatis底层会对这些参数进行不同的封装处理方式
单个参数:
-
POJO类型:直接使用,属性名和参数占位符名称一致
-
Map集合:直接使用,属性名和参数占位符名称一致
-
Collection:封装为Map集合
map.put("agr0", collection集合); map.put("collection",colection集合);
-
List:封装为Map集合
map.put("agr0",list集合); map.put("collection",list集合); map.put("list",list集合);
-
Array:封装为Map集合
map.put("agr0",数组); map.put("collection",数组); map.put("list",数组);
-
其他类型:直接使用
多个参数:可以使用@Param注解替换Map集合中arg键名
map.put("arg0",参数1);
map.put("param1",参数1);
map.put("param2",参数2);
map.put("arg1",参数2);
MyBatis提供了ParamNameResolveer类进行参数封装
建议:使用@Param注解替换Map集合中arg键名,并用修改后的名称获取值
6. 注解完成增删改查
注解完成简单功能,配置文件完成复杂功能
@Select("select * from tb_user where id=#{id}")
public User selectById(int id);
- 查询:@Select
- 添加:@Insert
- 修改:@Update
- 删除:@Delete
7. 动态SQL
见第五章节CRUD动态语句内容。