Mybatis总结

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 1、MyBatis简介1.1 MyBatis历史1.2 MyBatis特性2、搭建MyBatis2.1 MySQL不同版本的注意事项2.2 创建MyBatis的映射文件3、核心配置文件详解4、MyBatis获取参数值的两种方式4.1 单个字面量类型的参数4.2 多个字面量类型的参数4.3 map集合类型的参数4.4 实体类类型的参数4.5 使用@Param标识参数5、MyBatis特殊的SQL执行




1、MyBatis简介


1.1 MyBatis历史


(1)MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁

移到了Google Code。随着开发团队转投Google Code旗下, iBatis3.x正式更名为MyBatis。代码于

2013年11月迁移到Github。


(2)iBatis一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。 iBatis提供的持久层框架

包括SQL Maps和Data Access Objects(DAO)。


1.2 MyBatis特性


1)MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架

2)MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集

3)MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java

Objects,普通的Java对象)映射成数据库中的记录

4)MyBatis 是一个 半自动的ORM(Object Relation Mapping)框架


2、搭建MyBatis


2.1 MySQL不同版本的注意事项


(1)驱动类driver-class-name

①MySQL 5版本使用jdbc5驱动,驱动类使用:com.mysql.jdbc.Driver

②MySQL 8版本使用jdbc8驱动,驱动类使用:com.mysql.cj.jdbc.Driver

(2)连接地址url

①MySQL 5版本的url:jdbc:mysql://localhost:3306/ssm

②MySQL 8版本的url:jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC


2.2 创建MyBatis的映射文件


(1)相关概念:ORM(Object Relationship Mapping)对象关系映射。

①对象:Java的实体类对象

②关系:关系型数据库

③映射:二者之间的对应关系


e6a8ebc781ba41ca80a5108a6350cb83.png


(2)映射文件的命名规则:

①表所对应的实体类的类名+Mapper.xml

例如:表t_user,映射的实体类为User,所对应的映射文件为UserMapper.xml

因此一个映射文件对应一个实体类,对应一张表的操作

②MyBatis映射文件用于编写SQL,访问以及操作表中的数据

③MyBatis映射文件存放的位置是src/main/resources/mappers目录下

(3) MyBatis中可以面向接口操作数据,要保证两个一致:

①mapper接口的全类名和映射文件的命名空间(namespace)保持一致

②mapper接口中方法的方法名和映射文件中编写SQL的标签的id属性保持一致

(4)测试实例


//获取MyBatis的核心配置文件的输入流
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//通过核心配置文件所对应的字节输入流创建工厂类SqlSessionFactory,生产SqlSession对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
//创建SqlSession对象,此时通过SqlSession对象所操作的sql都必须手动提交或回滚事务
//SqlSession sqlSession = sqlSessionFactory.openSession();
//创建SqlSession对象,此时通过SqlSession对象所操作的sql都会自动提交
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//通过代理模式创建UserMapper接口的代理实现类对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//调用UserMapper接口中的方法,就可以根据UserMapper的全类名匹配元素文件,通过调用的方法名匹配
//映射文件中的SQL标签,并执行标签中的SQL语句
int result = userMapper.insertUser();
//sqlSession.commit();提交事务,默认是回滚的;所以看不到结果,开启提交事务才可以看到结果
System.out.println("结果:"+result);


①SqlSession:代表Java程序和数据库之间的会话(HttpSession是Java程序和浏览器之间的会话)

②SqlSessionFactory:是“生产”SqlSession的“工厂”。

工厂模式:如果创建某一个对象,使用的过程基本固定,那么我们就可以把创建这个对象的

相关代码封装到一个“工厂类”中,以后都使用这个工厂类来“生产”我们需要的对象。


3、核心配置文件详解


(1)核心配置文件中的标签必须按照固定的顺序:

properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,

reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <!--引入properties文件-->
  <properties resource="jdbc.properties" />
  <!--设置类型别名-->
  <typeAliases>
    <!--
      typeAlias:设置某个类型的别名
      属性:
        type:设置需要设置别名的类型
        alias:设置某个类型的别名,若不设置该属性,那么该类型拥有默认的别名,
        即类名,且不区分大小写
    -->
    <!--<typeAlias type="com.atguigu.mybatis.pojo.User"></typeAlias>-->
    <!--以包为单位,将包下所有的类型设置默认的类型别名,即类名且不区分大小写-->
    <package name="com.atguigu.mybatis.pojo"/>
  </typeAliases>
  <!--
    environments:配置多个连接数据库的环境
    属性:
      default:设置默认使用的环境的id
  -->
  <environments default="development">
  <!--
    environment:配置某个具体的环境
    属性:
      id:表示连接数据库的环境的唯一标识,不能重复
  -->
    <environment id="development">
      <!--
        transactionManager:设置事务管理方式
        属性:type="JDBC|MANAGED"
        JDBC:表示当前环境中,执行SQL时,使用的是JDBC中原生的事务管理方式,事
        务的提交或回滚需要手动处理
        MANAGED:被管理,例如Spring
      -->
      <transactionManager type="JDBC"/>
      <!--
        dataSource:配置数据源
        属性:
          type:设置数据源的类型
          type="POOLED|UNPOOLED|JNDI"
          POOLED:表示使用数据库连接池缓存数据库连接
          UNPOOLED:表示不使用数据库连接池
          JNDI:表示使用上下文中的数据源
      -->
      <dataSource type="POOLED">
        <!--设置连接数据库的驱动-->
        <property name="driver" value="${jdbc.driver}"/>
        <!--设置连接数据库的连接地址-->
        <property name="url" value="${jdbc.url}"/>
        <!--设置连接数据库的用户名-->
        <property name="username" value="${jdbc.username}"/>
        <!--设置连接数据库的密码-->
        <property name="password" value="${jdbc.password}"/>
      </dataSource>
    </environment>
  </environments>
    <!--引入映射文件-->
    <mappers>
    <!--<mapper resource="mappers/UserMapper.xml"/>-->
    <!--
    以包为单位引入映射文件
    要求:
    1、mapper接口所在的包要和映射文件所在的包一致
    2、mapper接口要和映射文件的名字一致
    -->
      <package name="com.atguigu.mybatis.mapper"/>
    </mappers>
</configuration>


4、MyBatis获取参数值的两种方式


MyBatis获取参数值的两种方式:${}和#{}

(1)${}的本质就是字符串拼接,#{}的本质就是占位符赋值

(2)${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单

引号;

(3)但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动

添加单引号


4.1 单个字面量类型的参数


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

此时可以使用${}和#{}以任意的名称获取参数的值,注意${}需要手动加单引号


4.2 多个字面量类型的参数


若mapper接口中的方法参数为多个时此时MyBatis会自动将这些参数放在一个map集合中,

(1)以arg0,arg1…为键,以参数为值;

(2)以param1,param2…为键,以参数为值;

因此只需要通过${}和#{}访问map集合的键就可以获取相对应的值

注意${}需要手动加单引号


4.3 map集合类型的参数


若mapper接口中的方法需要的参数为多个时,此时可以手动创建map集合,将这些数据放在map中。

只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号

(1)UserMapper.java


User checkLoginByMap(Map<String,Object> map);


(2)UserMapper.xml


<select id="checkLoginByMap" resultType="User">
  select * from t_user where username = #{username} and password = #{password}
</select>


(3) 测试


Map<String,Object> map = new HashMap<>();
map.put("username","admin");
map.put("password","123456");
User user = mapper.checkLoginByMap(map);


4.4 实体类类型的参数


若mapper接口中的方法参数为实体类对象时

此时可以使用${}和#{},通过访问实体类对象中的属性名获取属性值,注意${}需要手动加单引号


4.5 使用@Param标识参数


可以通过@Param注解标识mapper接口中的方法参数

此时,会将这些参数放在map集合中,以@Param注解的value属性值为键,以参数为值;

只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号


5、MyBatis特殊的SQL执行


5.1 查询多条数据为map集合


(1)方式一

将表中的数据以map集合的方式查询,一条数据对应一个map;若有多条数据,就会产生多个map集合,此

时可以将这些map放在一个list集合中获取

①Mapper.java


List<Map<String, Object>> getAllUserToMap();


②Mapper.xml


<select id="getAllUserToMap" resultType="map">
  select * from t_user
</select>


(2)方式二

将表中的数据以map集合的方式查询,一条数据对应一个map;若有多条数据,就会产生多个map集合,并

且最终要以一个map的方式返回数据,此时需要通过@MapKey注解设置map集合的键,值是每条数据所对

应的map集合

①Mapper.java


@MapKey("id")
Map<String, Object> getAllUserToMap();


②Mapper.xml


<select id="getAllUserToMap" resultType="map">
  select * from t_user
</select>


③结果如下


{
1={password=123, sex=男, id=1, age=23, username=admin},
2={password=416, sex=男, id=2, age=24, username=张三},
3={password=341, sex=男, id=3, age=25, username=李四}
}


5.2 模糊查询


<select id="testMohu" resultType="User">
  <!-- 方式一 -->
  select * from t_user where username like '%${mohu}%'
  <!-- 方式二 -->
  select * from t_user where username like concat('%',#{mohu},'%')
  <!-- 方式三 -->
  select * from t_user where username like "%"#{mohu}"%"
</select>


5.3 批量删除


(1)Mapper.java


/**
* 批量删除
* @param ids
* @return
*/
int deleteMore(@Param("ids") String ids);


(2)Mapper.xml


<!--int deleteMore(@Param("ids") String ids);-->
<delete id="deleteMore">
  delete from t_user where id in (${ids})
</delete>


5.4 动态设置表名


(1)Mapper.java


/**
* 动态设置表名,查询所有的用户信息
* @param tableName
* @return
*/
List<User> getAllUser(@Param("tableName") String tableName);


(2)Mapper.xml


<select id="getAllUser" resultType="User">
  select * from ${tableName}
</select>


5.5 添加功能获取自增的主键


(1)Mapper.java


/**
* useGeneratedKeys:设置使用自增的主键
* keyProperty:因为增删改有统一的返回值是受影响的行数,因此只能将获取的自增的主键放在传输的参
数user对象的某个属性中
*/
int insertUser(User user);


(2)Mapper.xml


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


6、自定义映射resultMap


6.1 当字段名和属性名不一致的时候,如何处理映射关系?


(1)为查询的字段设置别名,和属性名保持一致


<select id="getEmpById" resultType="Emp">
  select emp_id empId,emp_name empName,age,gender from t_emp where emp_id = #{empId}
</select> 


(2)当字段符合Mysql的要求使用下划线“_”,而实体类的属性符合Java的要求使用驼峰;

此时可以在mybatis的核心配置文件中设置一个全局配置,可以自动将下划线映射为驼峰


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <!-- 将下划线映射为驼峰 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
</configuration>


(3)通过resultMap设置自定义映射


<!--  resultMap: 设置自定义的映射关系
        id:唯一标识
        type: 处理映射关系的实体类的类型
      常用的标签:
      id:处理主键和实体类中属性的映射关系
      result:处理普通字段和实体类中属性的映射关系
      column:设置映射关系中的字段名,必须是SQL查询出的某个字段
      property:设置映射关系中的属性的属性名,必须是处理的实体类类型中的属性名
-->
    <resultMap id="AddressEntityMap" type="com.cy.store.entity.Address">
        <id column="aid" property="aid"/>
        <result column="province_code" property="provinceCode"/>
        <result column="province_name" property="provinceName"/>
        <result column="city_code" property="cityCode"/>
        <result column="city_name" property="cityName"/>
        <result column="area_code" property="areaCode"/>
        <result column="area_name" property="areaName"/>
        <result column="is_default" property="isDefault"/>
        <result column="created_user" property="createdUser"/>
        <result column="created_time" property="createdTime"/>
        <result column="modified_user" property="modifiedUser"/>
        <result column="modified_time" property="modifiedTime"/>
    </resultMap>
<select id="findByAid" resultMap="AddressEntityMap">
        SELECT * FROM t_address WHERE aid = #{aid}
 </select>


6.2 多对一映射处理


6.2.1 级联方式处理映射关系


<resultMap id="empDeptMap" type="Emp">
  <id column="emp_id" property="empId"></id>
  <result column="emp_name" property="empName"></result>
  <result column="age" property="age"></result>
  <result column="sex" property="sex"></result>
  <result column="dept_id" property="dept.deptId"></result>
  <result column="dept_name" property="dept.deptName"></result>
</resultMap>
<!--EmpgetEmpAndDeptByEid(@Param("eid")int eid);-->
<select id="getEmpAndDeptByEid" resultMap="empDeptMap">
  select emp.*,dept.* from t_emp emp left join t_dept dept on
  emp.dept_id=dept.dept_id where emp.emp_id= #{empId}
</select>

6.2.2 使用association处理映射关系


(1)association:处理多对一的映射关系(处理实体类类型的属性)

(2)property:设置需要处理映射关系的属性的属性名

(3)JavaType:设置要处理的属性的类型


<resultMap id="empDeptMap" type="Emp">
  <id column="emp_id" property="empId"></id>
  <result column="emp_name" property="empName"></result>
  <result column="age" property="age"></result>
  <result column="sex" property="sex"></result>
  <association property="dept" javaType="Dept">
    <id column="dept_id" property="deptId"></id>
    <result column="dept_name" property="deptName"></result>
  </association>
</resultMap>


6.2.3 分步查询


分步查询员工和对应的部门


@Data
public class Emp{
  private Integer empId;
  private String empName;
  private Integer age;
  private String gender;
  private Dept dept;
}


(1)通过分步查询员工以及对应的部门信息的第一步

①EmpMapper.java


Emp getEmpAndDeptByStepOne(Integer empId);


②EmpMapper.xml


<resultMap id="empAndDeptByStepResultMap" type="Emp">
  <id column="emp_id" property="empId" ></id>
  <result column="emp_name" property="empName" ></result>
  <result column="age" property="age"></result>
  <result column="gender" property="gender"></result>
  <!--
    property: 设置需要处理映射关系的属性的属性名
    select: 设置分步查询的sql的唯一标识
    column: 将查询出的某个字段作为分步查询的sql的条件
  -->
  <association property="dept" 
        select="com.spring.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
        column="dept_id"></association>
</cresultMap>
<select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">
  select * from t_emp where emp_id = #{empId}
</select>


(2)通过分步查询员工以及对应的部门信息的第二步

①DeptMapper.java


Dept getEmpAndDeptByStepTwo(Integer deptId);


②DeptMapper.xml


<mapper namespace="com.spring.mybatis.mapper.DeptMapper">
  <select id="getEmpAndDeptByStepTwo"  resultType="Dept">
    select * from t_dept where dept_id = #{deptId}
  </select>
</mapper>


(3)分步查询的优点:

可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息;

①lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载

②aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则,

每个属性会按需加载


<settings>
<!-- 开启延迟加载 -->
  <setting name="lazyLoadingEnabled" value="true">
<!--按需加载,默认就是false--> 
  <setting name="aggressiveLazyLoading" value="false">
</settings> 


注意:以上是全局配置,通过association和collection中的fetchType属性设置当前的分步查询是否使用

延迟加载, fetchType="lazy(延迟加载)|eager(立即加载)


6.3 一对多映射处理


一个Dept部门有多个emp员工


public class Dept {
  private Integer deptId;
  private String deptName;
  private List<Emp> emps;
}


6.3.1 collection


<resultMap id="deptAndEmpResultMap" type="Dept">
  <id column="dept_id" property="deptId"></id>
  <result column="dept_name" property="deptName"></result>
  <collection property="emps" ofType="Emp">
    <id column="emp_id" property="empId"></id>
    <result column="emp_name" property="empName"></result>
    <result column="age" property="age"></result>
    <result column="gender" property="gender">
  </collection>
</resultMap>
<selcet id="getDeptAndEmpByDeptId" resultMap="deptAndEmpResultMap">
  select *
  from t_dept
  left join t_emp
  on t_dept.dept_id = t_emp.dept_id
  where t_dept.dept_id = #{deptId} 
</select>


6.3.2 分步查询


(1)第一步


<resultMap id="deptAndEmpResultMapByStep" type="Dept">
  <id column="dept_id" property="deptId"></id>
  <result column="dept_name" property="deptName">
  <collection property="emps"
        select="com.spring.myatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"
        column="dept_id"></collection>
</resultMap>
<selcet id="getDeptAndEmpByStepOne" resultMap="deptAndEmpResultMapByStep">
  select * from t_dept where dept_id = #{deptId}
</selcet>


(2)第二步


<select id="getDeptAndEmpByStepTwo" resultType="Emp">
  select * from t_emp where dept_id = #{deptId}
</select>


7.动态SQL


Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了

解决 拼接SQL语句字符串时的痛点问题。


7.1 if


if标签可通过test属性的表达式进行判断,若表达式的结果为true,则标签中的内容会执行;反之,

标签中的内容不会执行


<!--List<Emp> getEmpListByCondition(Emp emp);-->
<select id="getEmpListByMoreTJ" resultType="Emp">
  select * from t_emp where 1=1
  <if test="ename != '' and ename != null">
    and ename = #{ename}
  </if>
  <if test="age != '' and age != null">
    and age = #{age}
  </if>
  <if test="sex != '' and sex != null">
    and sex = #{sex}
  </if>
</select>


7.2 where


where和if一般结合使用:

(1)若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字

(2)若where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余

的and去掉

注意:where标签不能去掉条件最后多余的and


<select id="getEmpListByMoreTJ2" resultType="Emp">
  select * from t_emp
  <where>
    <if test="ename != '' and ename != null">
      ename = #{ename}
    </if>
    <if test="age != '' and age != null">
      and age = #{age}
    </if>
    <if test="sex != '' and sex != null">
      and sex = #{sex}
    </if>
  </where>
</select>


7.3 trim


trim用于去掉或添加标签中的内容

常用属性:

(1)prefix:在trim标签中的内容的前面添加某些内容

(2)prefixOverrides:在trim标签中的内容的前面去掉某些内容

(3)suffix:在trim标签中的内容的后面添加某些内容

(4)suffixOverrides:在trim标签中的内容的后面去掉某些内容


<select id="getEmpListByMoreTJ" resultType="Emp">
  select * from t_emp
  <trim prefix="where" suffixOverrides="and">
    <if test="ename != '' and ename != null">
      ename = #{ename} and
    </if>
    <if test="age != '' and age != null">
      age = #{age} and
    </if>
    <if test="sex != '' and sex != null">
      sex = #{sex}
    </if>
  </trim>
</select>


7.4 choose、when、otherwise


choose、when、 otherwise相当于if…else if…else

when至少设置一个,otherwise最多设置一个


<select id="getEmpListByChoose" resultType="Emp">
  select * from t_emp
  <where>
    <choose>
      <when test="empName != null and empName != ''">
        emp_name = #{empName}
      </when>
      <when test="age != null and age != ''">
        age = #{age}
      </when>
      <when test="gender != null and gender != ''">
        gender = #{gender} 
      </when>
    </choose> 
  </where>  
</select> 


7.5 foreach


(1)collection:设置要循环的数组或集合;该属性是必须指定的,在不同的情况下,该属性的值是不一样的,

主要有以下3种情况:

①如果传入的是单参数且参数类型是一个List集合的时候,collection的属性值为list

②如果传入的是单参数且参数类型是一个Array数组的时候,collection的属性值为array

③如果传入的参数是多个的时候,我们就需要把它封装成一个Map了,当然单参数也可以

(2)item:用一个字符串表示数组或集合中的每一个数据

(3)separator:设置每次循环的数据之间的分隔符

(4)open:循环的所有内容以什么开始

(5)close:循环的所有内容以什么结束


<!-- 批量添加 void insertMoreEmp(@Param("emps") List<Emp> emps); -->
<insert id="insertMoreEmp">
  insert into t_emp values
  <foreach collection="emps" item="emp" separator=",">
    (null,#{emp.empName},#{emp.age},#{emp.gender})
  </foreach>
</insert>
<!-- 批量删除 void deleteMoreEmp(@Param("empIds") Integer[] empIds); -->
<delete id="deleteMoreEmp">
  delete from t_emp where emp_id in 
  <foreach collection="empIds" item="empId" separator=",",open="(",close=")">
    #{empId}
  </foreach>
</delete>


7.6 SQL片段


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


<sql id="empColumns">
  eid,ename,age,sex,did
</sql>
select <include refid="empColumns"></include> from t_emp


8.MyBatis的缓存


8.1 MyBatis的一级缓存


一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就

会从缓存中直接获取,不会从数据库重新访问。一级缓存默认是开启的

使一级缓存失效的四种情况:

(1) 不同的SqlSession对应不同的一级缓存

(2) 同一个SqlSession但是查询条件不同

(3) 同一个SqlSession两次查询期间执行了任何一次增删改操作

(4) 同一个SqlSession两次查询期间手动清空了缓存


SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.clearCache();


8.2 MyBatis的二级缓存


(1)二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被

缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取

(2)二级缓存开启的条件:

①在核心配置文件中,设置全局配置属性cacheEnabled=“true”,默认为true,不需要设置

②在映射文件中设置标签

③二级缓存必须在SqlSession关闭或提交之后有效

④查询的数据所转换的实体类类型必须实现序列化的接口

(3)使二级缓存失效的情况:

两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效


8.3 二级缓存的相关配置


在mapper配置文件中添加的cache标签可以设置一些属性:

(1)eviction属性:缓存回收策略,默认的是 LRU。

①LRU(Least Recently Used)最近最少使用的:移除最长时间不被使用的对象。

②FIFO(First in First out)先进先出:按对象进入缓存的顺序来移除它们。

③SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。

④WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

(2)flushInterval属性:刷新间隔,单位毫秒

默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新

(3)size属性:引用数目,正整数

代表缓存最多可以存储多少个对象,太大容易导致内存溢出

(4)readOnly属性:只读,true/false

①true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重

要的性能优势。

②false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。


8.4 MyBatis缓存查询的顺序


(1)先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。

(2)如果二级缓存没有命中,再查询一级缓存

(3)如果一级缓存也没有命中,则查询数据库

(4)SqlSession关闭之后,一级缓存中的数据才会写入二级缓存


9、MyBatis的逆向工程


(1)正向工程:先创建Java实体类,由框架负责根据实体类生成数据库表。 Hibernate是支持正向

工程的。

(2)逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成如下资源:

①Java实体类

②Mapper接口

③Mapper映射文件

(3) 创建步骤

①添加依赖和插件


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.atmybatis</groupId>
    <artifactId>mybatis_hpu</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <!-- 依赖MyBatis核心包 -->
    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>
        <!-- junit测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- log4j日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>
    </dependencies>
    <!-- 控制Maven在构建过程中相关配置 -->
    <build>
    <!-- 构建过程中用到的插件 -->
    <plugins>
        <!-- 具体插件,逆向工程的操作是以构建过程中插件形式出现的 -->
        <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.3.0</version>
            <!-- 插件的依赖 -->
            <dependencies>
                <!-- 逆向工程的核心依赖 -->
                <dependency>
                    <groupId>org.mybatis.generator</groupId>
                    <artifactId>mybatis-generator-core</artifactId>
                    <version>1.3.2</version>
                </dependency>
                <!-- MySQL驱动 -->
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>8.0.16</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
    </build>
</project>


②创建逆向工程的配置文件(文件名必须是:generatorConfig.xml)


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <!--
    targetRuntime: 执行生成的逆向工程的版本
        MyBatis3Simple: 生成基本的CRUD(清新简洁版)
        MyBatis3: 生成带条件的CRUD(奢华尊享版)
    -->
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <!-- 数据库的连接信息 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/hnlg?
serverTimezone=UTC"
                        userId="root"
                        password="root">
        </jdbcConnection>
        <!-- javaBean的生成策略-->
        <javaModelGenerator targetPackage="com.ssm.mybatis.pojo"
                            targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!-- SQL映射文件的生成策略 -->
        <sqlMapGenerator targetPackage="com.ssm.mybatis.mapper"
                         targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>
        <!-- Mapper接口的生成策略 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.ssm.mybatis.mapper" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>
        <!-- 逆向分析的表 -->
        <!-- tableName设置为*号,可以对应所有表,此时不写domainObjectName -->
        <!-- domainObjectName属性指定生成出来的实体类的类名 -->
        <table tableName="emp" domainObjectName="Emp"/>
        <table tableName="dept" domainObjectName="Dept"/>
        <table tableName="student" domainObjectName="Student"/>
        <table tableName="t_clazz" domainObjectName="Clazz"/>
        <table tableName="t_user" domainObjectName="User"/>
<!--        <table tableName="*"/>-->
    </context>
</generatorConfiguration>


10、分页插件


10.1 分页插件的使用步骤


(1)添加依赖


<dependency>
  <groupId>com.github.pagehelper</groupId>
  <artifactId>pagehelper</artifactId>
  <version>5.2.0</version>
</dependency>


(2)配置分页插件(在MyBatis的核心配置文件中配置插件)


<plugins>
  <!--设置分页插件-->
  <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins


10.2 分页插件的使用


(1)在查询功能之前使用PageHelper.startPage(int pageNum, int pageSize)开启分页功能


Page<Object> page = PageHelper.startPage(1,4);


①pageNum:当前页的页码

②pageSize:每页显示的条数

(2)在查询获取list集合之后,使用

PageInfo pageInfo = new PageInfo<>(List list, int navigatePages)获取分页相关数据

①list:分页之后的数据

②navigatePages:导航分页的页码数

(3)分页相关数据

PageInfo{

pageNum=8, pageSize=4, size=2, startRow=29, endRow=30, total=30, pages=8,

list=Page{count=true, pageNum=8, pageSize=4, startRow=28, endRow=32, total=30,

pages=8, reasonable=false, pageSizeZero=false},

prePage=7, nextPage=0, isFirstPage=false, isLastPage=true, hasPreviousPage=true,

hasNextPage=false, navigatePages=5, navigateFirstPage4, navigateLastPage8,

navigatepageNums=[4, 5, 6, 7, 8]

}

pageNum:当前页的页码

pageSize:每页显示的条数

size:当前页显示的真实条数

total:总记录数

pages:总页数

prePage:上一页的页码

nextPage:下一页的页码

isFirstPage/isLastPage:是否为第一页/最后一页

hasPreviousPage/hasNextPage:是否存在上一页/下一页

navigatePages:导航分页的页码数

navigatepageNums:导航分页的页码,[1,2,3,4,5]

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
SQL XML 存储
Mybatis知识点全总结(二)
Mybatis知识点全总结
121 1
Mybatis知识点全总结(二)
|
XML SQL Java
Mybatis知识点全总结(四)
Mybatis知识点全总结
168 0
Mybatis知识点全总结(四)
|
SQL 存储 缓存
Mybatis知识点全总结(三)
Mybatis知识点全总结
227 0
Mybatis知识点全总结(三)
|
SQL XML Java
Mybatis知识点全总结(一)
Mybatis知识点全总结
241 0
Mybatis知识点全总结(一)
|
缓存 Java 数据库连接
mybatis的缓存总结
mybatis的缓存总结
128 0
|
SQL XML 存储
Java面试——MyBatis系列总结
Java面试——MyBatis系列总结
Java面试——MyBatis系列总结
|
SQL XML 存储
mybatis系列总结(一)
mybatis系列总结(一)
271 0
|
XML SQL 安全
Mybatis传参的方式总结
mybatis传参的几种方式?
182 0
|
SQL XML 存储
Mybatis 面试常问问题总结(附答案)
Mybatis 面试常问问题总结(附答案)
216 0
Mybatis 面试常问问题总结(附答案)