MyBatis

一、基础介绍

介绍

MyBatis是一款支持定制化 SQL、存储过程以及高级映射的半自动化持久化层框架。 其可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO映射成数据库中的记录。

使用流程

使用MyBatis的流程:MySQL表——实体类——Mapper接口——xml映射文件

全局配置

可以在properties配置文件中配置数据库信息,包括driver、url、username、password

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/ceshi?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
spring.datasource.username=root
spring.datasource.password=****

二、xml映射文件

(一)<select>标签

注意:查询功能的标签必须设置resultType或resultMap之一

  • resultType:设置默认的映射关系,即将查询到的字段,根据字段名自动匹配类属性,存在就赋值,不存在就不赋值;
  • resultMap:设置自定义的映射关系,用于查询到的字段名和映射属性名不一致的情况;

(二)MyBatis获取参数值

1、获取方式

(1)${}

本质:以字符串拼接方式拼接SQL。此时如果是字符串类型或日期类型的字段进行赋值时,需要手动加单引号。

注意:

  • 字符串拼接会导致SQL注入,并且要考虑加单引号,麻烦,一般不用
  • 只有在特殊SQL,无法使用#{}时,包括模糊查询、批量删除、动态设置表名、添加自增主键等情况,不能添加单引号,必须使用${}

举例:

  • 模糊查询:select * from t_user where username like "%"#{mohu}"%"或'%${mohu}%'或concat('%',#{mohu},'%');
  • 批量删除:delete from t_user where id in (${ids});
  • 动态设置表名:select * from ${tableName};

(2)#{}

本质:以占位符赋值方式拼接SQL,会自动添加单引号

注意:使用该种方式获取实际内容时,只和值以及位置有关,和参数名称无关。

2、需要获取参数值的情况

(1)mapper接口中的方法参数为单个的字面量类型

使用#{xxx}或'${xxx}'即可

(2)多个字面量类型的参数

该情况不能直接用参数名进行获取,可以用arg和param+编号的形式获取

注意:arg从0开始,param从1开始

(3)map集合类型的参数

用于多个参数情况,手动创建map集合,可通过#{map键名}的形式获取对应的值

(4)实体类类型的参数

访问形式和(3)相同,直接通过类的属性名(全小写)作为键名进行访问

(5)使用@Param标识参数

会默认将@Param标注的参数放在map集合中,可以通过(2)访问,也可以根据注解的命名来作为键名访问

(三)<insert>标签

属性包括:

  • useGeneratedKeys:设置是否使用自增主键,true表示使用;
  • keyProperty:设定作为自增主键的列名,将自增的主键的值赋值给某个属性;

示例:

<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
  insert into t_user values (null,#{username},#{password})
</insert>

(四)自定义映射resultMap

1、本质

相当于给字段设置别名,用于解决类属性名和数据库表字段名不一致的情况

2、基础标签:

主键id,普通属性result。通过映射关系中的属性名property和字段名column来配置映射关系

3、多对一映射关系:

  • 在result中对property设置为xxx.xxx级联属性;
  • 使用association,property:需要处理的属性名,javaType:该属性的Java类类型
  • 分布查询
    • 分步查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息settings:
      • lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载
      • aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。 否则,每个属性会按需加载
  • 延迟加载的配置项:
    • select:设置分布查询的sql的唯一标识,一般为mapper接口的全类名.方法名;
    • column:设置分布查询的条件字段;
    • fetchType:当开启了全局延迟加载之后,控制延迟加载的效果,lazy表示延迟加载,eager表示立即加载

4、一对多映射关系:

  • 在resultMap中使用collection;
  • 分布查询

三、动态SQL

1、if标签

用法:<if test="......">...</if>

2、where标签

与其他标签结合使用,没有满足条件的项,where失效不会添加到sql中

3、trim标签

  • prefix/suffix:前缀/后缀标签,将标签属性的内容添加到trim标签前/后
  • prefixOverrides/suffixOverrides:在trim标签中每个标签的前面或后面去除属性内容

4、choose、when、otherwise组合标签

相当于Java中的if、if else、else

5、foreach标签

属性:

  • collection:设置要循环的数组或集合
  • item:表示集合或数组中的每一个数据
  • separator:设置循环体之间的分隔符,分隔符前后默认有一个空格
  • open:设置foreach标签中的内容的开始符
  • close:设置foreach标签中的内容的结束符

6、sql标签

作用:可以记录一段公共sql片段,在使用的地方通过include标签进行引入

引入方式:<include refid="sql标签的id"></include>

四、MyBatis缓存原理

1、一级缓存

  • 默认开启,一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问
  • 失效的四种情况:
    • (1) 不同的SqlSession对应不同的一级缓存
    • (2) 同一个SqlSession但是查询条件不同
    • (3) 同一个SqlSession两次查询期间执行了任何一次增删改操作
    • (4) 同一个SqlSession两次查询期间手动清空了缓存

2、二级缓存

  • 默认不开启,二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取
  • 开启条件:
    • (1)在核心配置文件中,设置全局配置属性cacheEnabled="true",默认为true,不需要设置
    • (2)在映射文件中设置标签
    • (3)二级缓存必须在SqlSession关闭或提交之后有效
    • (4)查询的数据所转换的实体类类型必须实现序列化的接口
  • 失效情况:
    • 两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效

3、三级缓存

三级缓存需要整合第三方的缓存插件才能使用。

五、具体案例:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.springboot.mapper.CeshiMapper">
  <resultMap id="BaseResultMap" type="com.example.springboot.model.Ceshi">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
  </resultMap>
  <sql id="Base_Column_List">
    id, name
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from ceshi1
    where id = #{id,jdbcType=INTEGER}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
    delete from ceshi1
    where id = #{id,jdbcType=INTEGER}
  </delete>
  <insert id="insert" parameterType="com.example.springboot.model.Ceshi">
    insert into ceshi1 (id, name)
    values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR})
  </insert>
  <insert id="insertSelective" parameterType="com.example.springboot.model.Ceshi">
    insert into ceshi1
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="name != null">
        name,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=INTEGER},
      </if>
      <if test="name != null">
        #{name,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.example.springboot.model.Ceshi">
    update ceshi1
    <set>
      <if test="name != null">
        name = #{name,jdbcType=VARCHAR},
      </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.example.springboot.model.Ceshi">
    update ceshi1
    set name = #{name,jdbcType=VARCHAR}
    where id = #{id,jdbcType=INTEGER}
  </update>
</mapper>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值