MyBatis

MyBatis

MyBatis

1. 什么是MyBatis

1.1 持久层

  • 负责将数据保存到数据库的一层代码
  • JavaEE三层架构:表现层、业务层、持久层

1.2 框架

  • 框架就是一个半成品软件,是一套可重用的、通用的、软件基础代码模型
  • 在框架基础之上构架软件编写更加高效、规范、通用、可扩展

1.3 JDBC缺点

e779b2f492ba9b50

  1. 硬编码
    • 注册驱动,获取连接
    • SQL语句
  2. 操作繁琐
    • 手动设置参数
    • 手动封装结果集

1.4 MyBatis简化

073d8939d1325cf5

2. MyBatis快速入门

查询user表中所有数据

  1. 创建user表,添加数据

  2. 创建模块,导入坐标

  3. 编写MyBatis核心配置文件 --> 替换连接信息,解决硬编码问题

  4. 编写SQL映射文件 --> 统一管理sql语句,解决硬编码问题

  5. 编码

    // 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 入门案例

  1. 定义与SQL映射文件同名的Mapper接口,并且将Mapper接口与SQL映射文件放置同一目录下
  2. 设置SQL映射文件的namespace属性为Mapper接口全限定名
  3. 在Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致
  4. 编码
    1. 通过SqlSession的getMapper()方法获取Mapper接口的代理对象
    2. 调用对应方法完成sql执行

细节:如果Mapper接口名称与SQL映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载。

36b8ab54b3e2537a

4. MyBatis核心配置文件

https://mybatis.org/mybatis-3/zh/index.html

细节:注意遵守各个标签的前后顺序

5. 配置文件完成增删改查

  1. 编写接口方法:Mapper接口
  2. 编写SQL语句:SQL映射文件
  3. 执行方法,测试

数据库的字段名称和实体类的属性名称不一样导致不能自动封装:

  1. 起别名:对不一样的列名起别名,让别名和实体类的属性名一样。

    • 缺点:每次查询都要定义一次别名

    • 解决:sql片段brand_column

      <sql id="xxx">
      id, brand_name as bradName
      </sql>
      
  2. resultMap:

    <!--id:唯一标识;type:映射类型,支持别名-->
    <resultMap id="xxxResultMap" type="xxx">
    	<!--id:主键映射;result:一般自动映射;cilumn表的列名,property实体类的属性名-->
    	<result column="xxx_xxx" property="xxxXxx"/>
    </resultMap>
    

5.1 参数占位符

  1. {}:会将其替换为?,防止SQL注入

  2. ${}:拼sql,存在SQL诸如问题
  3. 使用时机:
    • 参数传递时:#{}
    • 表名或列名不固定的情况下:${}

5.2 参数类型:parameterType(可省略)

SQL语句设置多个参数的几种方式?

  1. 散装参数:需要使用@Param("SQL中参数占位符名称")
  2. 实体类封装参数:只需要保证SQL中参数名与实体类属性名对应上
  3. 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 特殊字符处理:

  1. 转义字符 &lt
  2. CDATA区 <![CDATA[ 内容 ]]

5.9 参数传递

MyBatis接口方法中可以接收各种各样的参数,MyBatis底层会对这些参数进行不同的封装处理方式

单个参数

  1. POJO类型:直接使用,属性名和参数占位符名称一致

  2. Map集合:直接使用,属性名和参数占位符名称一致

  3. Collection:封装为Map集合

    map.put("agr0", collection集合);
    map.put("collection",colection集合);
    
  4. List:封装为Map集合

    map.put("agr0",list集合);
    map.put("collection",list集合);
    map.put("list",list集合);
    
  5. Array:封装为Map集合

    map.put("agr0",数组);
    map.put("collection",数组);
    map.put("list",数组);
    
  6. 其他类型:直接使用

多个参数:可以使用@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动态语句内容。

皖ICP备2023003517号-1