网站建设社会效益/企业管理培训班哪个好
👌 棒棒有言:也许我一直照着别人的方向飞,可是这次,我想要用我的方式飞翔一次!人生,既要淡,又要有味。凡事不必太在意,一切随缘,缘深多聚聚,缘浅随它去。凡事看淡点看开些,顺其自然,无意于得,就无所谓失。人生,看轻看淡多少,痛苦就远离你多少。
👌 本章简介:MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。2013年11月迁移到Github。iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)。
当前,最新版本是MyBatis 3.5.11,其发布时间是2022年09月18日。
👍 作者:get棒棒给个关注呗
👍非常重要 :
如果不介意麻烦动动你们的小手点个关注
Mybatis框架
MyBatis简介
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录
2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
回顾JDBC的使用步骤:
-
1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
-
2.获取连接对象
DiverManerger.getConnection(url,username,password)
-
3.获取执行sql的Statement对象
connection.CreateStatement();
-
4.执行sql语句
-
5.处理结果集
-
6.释放连接
connection.Close()
与JDBC相比:
-
Mybatis通过参数映射方式,可以将参数灵活的配置在SQL语句中的配置文件中,避免在Java类中配置参数
-
Mybatis通过输出映射机制,将结果集的检索自动映射成相应的Java对象,避免对结果集手工检索
-
Mybatis可以通过Xml配置文件对数据库连接进行管理
MyBatis整体架构及运行流程
Mybatis整体构造由 数据源配置文件、Sql映射文件、会话工厂、会话、执行器和底层封装对象组成
1.数据源配置文件
通过配置的方式将数据库的配置信息从应用程序中独立出来,由独立的模块管理和配置。Mybatis的数据源配置文件包含数据库驱动、数据库连接地址、用户名密码、事务管理等,还可以配置连接池的连接数、空闲时间等
一个MapConfig.xml基本的配置信息如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><environments default="development"><environment id="development"><!-- 事务的管理 JDBC MANAGED--><transactionManager type="JDBC"/><!-- 数据源 POOLED UNPOOLED JNDI --><dataSource type="POOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment></environments><mappers><mapper resource="org/mybatis/example/BlogMapper.xml"/></mappers>
</configuration>
mybatis mapper文件映射
<!-- 使用相对于类路径的资源引用 -->
<mappers><mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
</mappers>
<!-- 使用映射器接口实现类的完全限定类名mybais去加载class对应的接口,然后还会去加载该接口同目录下的同名xml文件 -->
<mappers><mapper class="org.mybatis.builder.AuthorMapper"/>
</mappers>
<!-- 将包内的映射器接口实现全部注册为映射器 使用package元素批量注册Mapper接口1.包名和接口所在的包名字一致2.mapper文件的名字和接口的名字一致3.创建包是使用/分割 -->
<mappers><package name="org.mybatis.builder"/>
</mappers>
设置资源文件路径
Maven中默认是只会打包
resource下的资源文件。如果我们的文件不放在
resource, 则需要通过配置告知
Maven
<resources><resource><directory>src/main/java</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>false</filtering></resource><resource><directory>src/main/resources</directory><includes><include>**/*.properties</include><include>**/*.xml</include><include>**/*.tld</include></includes><filtering>false</filtering></resource>
</resources>
2.Sql映射文件
Mybatis中所有数据库的操作都会基于该映射文件和配置的sql语句,在这个配置文件中可以配置任何类型的sql语句。框架会根据配置文件中的参数配置,完成对sql语句以及输入输出参数的映射配置。
Mapper.xml配置文件大致如下:
<?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="命名空间">
<select id="方法名" resultMap="返回值类型" parameterType="参数类型">
-- sql语句
</select>
</mapper>
3.会话工厂与会话
Mybatis中会话工厂SqlSessionFactory类可以通过加载资源文件,读取数据源配置MapConfig.xml信息,从而产生一种可以与数据库交互的会话实例SqlSession,会话实例SqlSession根据Mapper.xml文件中配置的sql,对数据库进行操作。
4.运行流程
会话工厂SqlSessionFactory通过加载资源文件获取MapConfig.xml配置文件信息,然后生成可以与数据库交互的会话实例SqlSession。会话实例可以根据Mapper配置文件中的Sql配置去执行相应的增删改查操作
执行流程图:
mybatis实现增删改查
public class TestStudent {
@Testpublic void test01(){
try {//加载配置文件InputStream in = Resources.getResourceAsStream("config/mybatis-config.xml");//获取sqlSession对象SqlSession sqlSession = new SqlSessionFactoryBuilder().build(in).openSession();//查询所有学生信息List<Student> students = sqlSession.selectList("cn.kgc.mybatis.dao.StudentDao.getAll"); students.forEach(student -> System.out.println(student) );} catch (IOException e) {e.printStackTrace();}}
@Testpublic void test02(){//查询一个学生信息
try {//加载配置文件InputStream in = Resources.getResourceAsStream("config/mybatis-config.xml");//获取sqlSession对象SqlSession sqlSession = new SqlSessionFactoryBuilder().build(in).openSession();//根据用户名查询一个学生信息Student student = sqlSession.selectOne("cn.kgc.mybatis.dao.StudentDao.findOne","tom");System.out.println(student);sqlSession.close();} catch (IOException e) {e.printStackTrace();}}@Testpublic void test03() {//添加一个学生信息
try {//加载配置文件InputStream in = Resources.getResourceAsStream("config/mybatis-config.xml");//获取sqlSession对象SqlSession sqlSession = new SqlSessionFactoryBuilder().build(in).openSession();//添加一个学生信息Student student = Student.builder().stuBirth(new Date()).stuName("lilei").stuNo("2021073001").stuSex("男").build();int i = sqlSession.insert("cn.kgc.mybatis.dao.StudentDao.addOne", student);System.out.println(i);sqlSession.commit();sqlSession.close();
} catch (IOException e) {e.printStackTrace();}
}@Testpublic void test04() {//删除一个学生信息
try{InputStream in = Resources.getResourceAsStream("config/mybatis-config.xml");//获取sqlSession对象 同时可设置事务的自动提交 openSession(true)SqlSession sqlSession = new SqlSessionFactoryBuilder().build(in).openSession();int delete = sqlSession.delete("cn.kgc.mybatis.dao.StudentDao.delOne","lilei" );sqlSession.commit();sqlSession.close();System.out.println(delete);}catch (Exception e){e.printStackTrace();}
}
@Testpublic void test05() {//修改一个学生信息
try{InputStream in = Resources.getResourceAsStream("config/mybatis-config.xml");//获取sqlSession对象SqlSession sqlSession = new SqlSessionFactoryBuilder().build(in).openSession();
Student student = Student.builder().stuBirth(new Date()).stuName("lili").stuNo("2021073001").stuSex("女").build();int delete = sqlSession.update("cn.kgc.mybatis.dao.StudentDao.updateStudent",student);sqlSession.commit();sqlSession.close();System.out.println(delete);}catch (Exception e){e.printStackTrace();}
}
}
mybatis中使用log4j日志工具
1.配置mybatis-config.xml
<!-- 开启日志--><setting name="logImpl" value="LOG4J"/>
开启驼峰命名
<!-- 设置驼峰命名--><setting name="mapUnderscoreToCamelCase" value="true"/>
设置别名
<typeAliases><!--设置别名--><package name="cn.kgc.mybatis.pojo"/>
</typeAliases>
2.配置log4j.properties文件,放置在resources目录下
log4j.rootLogger=DEBUG,Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.org.apache=ERROR
log4j.logger.org.mybatis=ERROR
log4j.logger.org.springframework=ERROR
#这个需要
log4j.logger.log4jdbc.debug=ERROR
log4j.logger.com.gk.mapper=ERROR
log4j.logger.jdbc.audit=ERROR
log4j.logger.jdbc.resultset=ERROR
#这个打印SQL语句非常重要
log4j.logger.jdbc.sqlonly=DEBUG
log4j.logger.jdbc.sqltiming=ERROR
log4j.logger.jdbc.connection=FATAL
使用mapper代理对象实现增删改查
public class TestStudentMapper {SqlSessionFactory factory;@Beforepublic void init(){try {InputStream in = Resources.getResourceAsStream("config/mybatis-config.xml");SqlSessionFactoryBuilder sfb = new SqlSessionFactoryBuilder();factory = sfb.build(in);} catch (IOException e) {e.printStackTrace();}
}@Testpublic void test01(){//开启事务自动提交SqlSession sqlSession = factory.openSession(true);//获取dao层的代理对象StudentDao studentDao = sqlSession.getMapper(StudentDao.class);List<Student> students = studentDao.getAll();students.forEach(student -> System.out.println(student));}
@Testpublic void test02(){ //添加数据
SqlSession sqlSession = factory.openSession(true);Student student = Student.builder().stuSex("男").stuNo("2021073100").stuName("李四").stuBirth(new Date()).build();StudentDao studentDao = sqlSession.getMapper(StudentDao.class);Integer line = studentDao.addOne(student);System.out.println(line);}
@Testpublic void test03(){//删除一条数据SqlSession sqlSession = factory.openSession(true);StudentDao studentDao = sqlSession.getMapper(StudentDao.class);Integer line = studentDao.delOne("李四");System.out.println(line);}
@Testpublic void test04() { //修改数据SqlSession sqlSession = factory.openSession(true);StudentDao studentDao = sqlSession.getMapper(StudentDao.class);Student student = Student.builder().stuSex("女").stuNo("2021073100").stuName("李四").stuBirth(new Date()).build();Integer line = studentDao.updateOne(student);System.out.println(line);
}@Testpublic void test06(){//模糊查询一个学生信息 一个参数SqlSession sqlSession = factory.openSession(true);StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
List<Student> students = studentDao.selectLikeName("li");System.out.println(students.toString());
}
@Testpublic void test07(){//模糊查询一个学生信息 两个参数SqlSession sqlSession = factory.openSession(true);StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
List<Student> students = studentDao.selectLikeName2("li", "2021072902");System.out.println(students.toString());
}@Testpublic void test08(){//模糊查询一个学生信息 一个集合参数 mapper文件中按照key取值SqlSession sqlSession = factory.openSession(true);StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
HashMap<String, String> map = new HashMap<>();map.put("stuname","li");map.put("stuno", "2021072902");List<Student> students = studentDao.selectLikeName3(map);System.out.println(students.toString());}
}
Mybatis的获取参数的方式
方式1:${} 字符串拼接
方式2:#{} 占位符
1.Mapper接口参数为单个参数
<delete id="delUserById" parameterType="int">delete from user where id = #{id}</delete><delete id="delUserById" parameterType="int">delete from user where id = ${id}</delete>
注:如何参数是String类型使用${}获取参数是需要手动添加引号 ''
2.Mapper接口参数是多个参数的获取
mybatis在处理多个参数时,会将多个参数保存到map集合中会 以 agr0 ,agr1或param1 param2为键 以参数位置进行存储
User selectUserByUserNameAndPassword(String username,String password);<select id="selectUserByUserNameAndPassword" resultType="user">select * from user where user_name = #{arg0} and password = #{arg1}</select>
3.将参数设为map集合进行数据的传递
User selectUserByMap(Map map);
<select id="selectUserByMap" resultType="cn.kgc.mybatis.entity.User">select * from user where user_name = #{username} and password = #{password}
</select>
4.通过注解@param("键名")设置参数的获取名字
User selectUserByUserNameAndPassword(@param("username")String username,(@param("password")String password);
<select id="selectUserByUserNameAndPassword" resultType="user">select * from user where user_name = #{username} and password = #{password}
</select>
或者
<select id="selectUserByUserNameAndPassword" resultType="user">select * from user where user_name = #{param1} and password = #{param2}
</select>
5.将多个参数设置成对象进行数据的传递
int insertUser(User user);<insert id="insertUser" parameterType="user" useGeneratedKeys="true" keyProperty="id" >insert into user values ( #{id},#{userName},#{password})</insert>
Mybatis中的模糊查询
方式1:
SELECT * FROM tableName WHERE name LIKE #{text}
-- 传递的参数需要拼接 ‘%text%’
方式2:
SELECT * FROM tableName WHERE name LIKE '%${text}%';
-- 使用$替代# 参数无需在拼接% 存在sql注入
方式3
SELECT * FROM tableName WHERE name LIKE CONCAT('%', #{text}), '%');
-- 使用mysql的函数 实现拼接
6.批量删除
int deleteMore(String ids);<delete id="deleteMore">delete from user where id in(${ids})</delete>
mapper中自定义映射
自定义映射的用法之一,解决表格查询的字段名和实体类中不一致的情况
<resultMap id="userMap" type="user"><id column="id" property="id"></id><result column="user_name" property="userName"></result><result column="password" property="password"></result>
</resultMap>
mybatis对象的关联关系
一对多关系处理(一方)
<resultMap id="selectByEIdMap" type="cn.kgc.mybatis.entity.Emp"><result column="id" property="dept.id" ></result><result column="dname" property="dept.dName"></result></resultMap>
<resultMap id="selectByEIdMap2" type="cn.kgc.mybatis.entity.Emp"><id column="eid" property="eId"></id><result column="ename" property="EName"></result><result column="age" property="age"></result><result column="deptno" property="deptNo"></result><!--实体对象标识--><association property="dept" javaType="dept"><id column="id" property="id"></id><result column="dname" property="dName"></result></association></resultMap>
<!-- 分步查询 --><resultMap id="selectByEIdMap3" type="cn.kgc.mybatis.entity.Emp"><id column="eid" property="eId"></id><result column="ename" property="EName"></result><result column="age" property="age"></result><result column="deptno" property="deptNo"></result><association property="dept" select="cn.kgc.mybatis.mapper.DeptMapper.selectById" column="deptno" fetchType="eager"></association></resultMap>
注:延迟加载设置 :1. <setting name="lazyLoadingEnabled" value="true"/> 2. <setting name="aggressiveLazyLoading" value="false"/> 3.4.1之前的版本需要设置
<select id="selectByEId" resultMap="selectByEIdMap2">select * from emp left join dept on emp.deptno = dept.id where eid = #{eid}</select>
<select id="selectByEId2" resultMap="selectByEIdMap3">select * from emp where eid = #{eid}</select>
一对多关系处理(多方)
<resultMap id="BaseResultMap" type="cn.kgc.mybatis.entity.Dept"><id property="id" column="id" /><result property="dName" column="dname" /><collection property="emps" ofType="emp"><id column="eid" property="eId"></id><result column="ename" property="EName"></result><result column="age" property="age"></result><result column="deptno" property="deptNo"></result></collection></resultMap>
<resultMap id="BaseResultMap2" type="cn.kgc.mybatis.entity.Dept"><id property="id" column="id" /><result property="dName" column="dname" /><collection property="emps" select="cn.kgc.mybatis.mapper.EmpMapper.selectByDeptId" column="id"></collection></resultMap>
<select id="selectById" resultType="dept">select * from dept where id = #{id}</select>
<select id="selectById2" resultMap="BaseResultMap">select emp.* ,dept.* from dept left join emp on dept.id = emp.deptno where id = #{id}</select>
<select id="selectById3" resultMap="BaseResultMap2">select dept.* from dept where id = #{id}</select>
mybatis动态sql
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦
动态SQL:if 语句
根据 stu_name 和 stu_sex 来查询数据。如果stu_name为空,那么将只根据stu_sex来查询;反之只根据stu_name来查询
首先不使用 动态SQL 来书写
<select id="selectStudent" resultType="student" parameterType="cn.kgc.mybatis.pojo.Student">select * from user where stu_name=#{stu_name} and stu_sex=#{stu_sex}
</select>
可以发现,如果 #{stu_name} 为空,那么查询结果也是空,如何解决这个问题呢?使用 if 来判断
<select id="selectStudent" resultType="student" parameterType="cn.kgc.mybatis.pojo.Student">select * from student where <if test="stu_name != null">stu_name=#{stu_name}</if><if test="stu_sex!= null">and stu_sex=#{stu_sex}</if>
</select>
这样写我们可以看到,如果 sex 等于 null,那么查询语句为 select * from student where stu_name=#{stu_name},但是如果stu_name 为空呢?那么查询语句为 select * from user where and stu_sex=#{sex},这是错误的 SQL 语句,如何解决呢?
if+where 语句
<select id="selectStudent" resultType="student" parameterType="cn.kgc.mybatis.pojo.Student">select * from student <where> <if test="stu_name != null">stu_name=#{stu_name}</if><if test="stu_sex!= null">and stu_sex=#{stu_sex}</if></where>
</select>
这个where标签会知道如果它包含的标签中有返回值的话,它就插入一个where。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉
动态SQL:if+set 语句
上面的对于查询 SQL 语句包含 where 关键字,如果在进行更新操作的时候,含有 set 关键词
<update id="updateStudentById" parameterType="cn.kgc.mybatis.pojo.Student">update student stu<set><if test="stuname != null and stuname != ''">stu.stu_name = #{stuName},</if><if test="stusex != null and stusex != ''">stu.stu_sex = #{stuSex}</if></set>where id=#{id}
</update>
-
如果第一个条件 username 为空,那么 sql 语句为:update user u set u.sex=? where id=?
-
如果第一个条件不为空,那么 sql 语句为:update user u set u.username = ? ,u.sex = ? where id=?
动态SQL:choose(when,otherwise) 语句
有时候,我们不想用到所有的查询条件,只想选择其中的一个,查询条件有一个满足即可,使用 choose 标签可以解决此类问题,类似于 Java 的 switch 语句
<select id="selectStudentByChoose" resultType="com.ys.po.User" parameterType="com.ys.po.User">select * from student<where><choose><when test="id !='' and id != null">id=#{id}</when><when test="username !='' and username != null">and username=#{username}</when><otherwise>and sex=#{sex}</otherwise></choose></where></select>
这里我们有三个条件,id,username,sex,只能选择一个作为查询条件
-
如果 id 不为空,那么查询语句为:select * from user where id=?
-
如果 id 为空,那么看username 是否为空,如果不为空,那么语句为 select * from user where username=?;
-
如果 username 为空,那么查询语句为 select * from user where sex=?
动态SQL:trim 语句
trim标记是一个格式化的标记,可以完成set或者是where标记的功能
用 trim 改写上面的 if+where 语句
<select id="selectStudent" resultType="student" parameterType="cn.kgc.mybatis.pojo.Student">select * from user <trim prefix="where" prefixOverrides=" and | or"><if test="stu_name != null">stu_name=#{stu_name}</if><if test="stu_sex!= null">and stu_sex=#{stu_sex}</if></trim>
</select>
-
prefix:前缀
-
prefixoverride:去掉第一个and或者是or
用 trim 改写上面的 if+set 语句
<update id="updateStudentById" parameterType="cn.kgc.mybatis.pojo.Student">update student stu<trim prefix="set" suffixOverrides=","><if test="stuname != null and stuname != ''">stu.stu_name = #{stuName},</if><if test="stusex != null and stusex != ''">stu.stu_sex = #{stuSex}</if></trim>where id=#{id}
</update>
-
suffix:后缀
-
suffixoverride:去掉最后一个逗号(也可以是其他的标记,就像是上面前缀中的and一样)
动态SQL: foreach 语句
需求:我们需要查询 user 表中 id 分别为1,2,3的用户,sql语句:
select * from user where id=1 or id=2 or id=3
select * from user where id in (1,2,3)
用 foreach 来改写 select * from user where id=1 or id=2 or id=3
<select id="selectUserByListId" parameterType="com.ys.vo.UserVo" resultType="com.ys.po.User">select * from user<where><!--collection:指定输入对象中的集合属性item:每次遍历生成的对象open:开始遍历时的拼接字符串close:结束时拼接的字符串separator:遍历对象之间需要拼接的字符串select * from user where 1=1 and (id=1 or id=2 or id=3)--><foreach collection="ids" item="id" separator="or">id=#{id}</foreach></where>
</select>
用 foreach 来改写 select * from user where id in (1,2,3)
<select id="selectUserByListId" parameterType="com.ys.vo.UserVo" resultType="com.ys.po.User">select * from user <where><!--collection:指定输入对象中的集合属性item:每次遍历生成的对象open:开始遍历时的拼接字符串close:结束时拼接的字符串separator:遍历对象之间需要拼接的字符串select * from user where1=1 and id in (1,2,3)--><foreach collection="ids" item="id" open="id in ("separator="," close=") " >#{id}</foreach></where></select>
动态SQL: SQL 片段
有时候可能某个 sql 语句我们用的特别多,为了增加代码的重用性,简化代码,我们需要将这些代码抽取出来,然后使用时直接调用。
假如我们需要经常根据用户名和性别来进行联合查询,那么我们就把这个代码抽取出来,如下:
<sql id="selectUserByUserNameAndSexSQL"><if test="username != null and username != ''">AND username = #{username}</if> <if test="sex != null and sex != ''">AND sex = #{sex}</if>
</sql>
<select id="selectUserByUsernameAndSex" resultType="user" parameterType="com.ys.po.User">select * from user<trim prefix="where" prefixOverrides="and | or"><!-- 引用 sql 片段,如果refid 指定的不在本文件中,那么需要在前面加上 namespace --><include refid="selectUserByUserNameAndSexSQL"></include><!-- 在这里还可以引用其他的 sql 片段 --></trim>
</select>
注意:
①、最好基于 单表来定义 sql 片段,提高片段的可重用性
②、在 sql 片段中最好不要包括 where
mybatis注解开发
public interface StudentDao2 {
@Select("select * from student where stu_no = #{stu_no}")@Results({@Result(property = "stuNo" ,column="stu_no"),@Result(property = "stuSex",column = "stu_sex"),@Result(property = "birth",column = "stu_birth")})List<Student> getAll(String stu_no);
@Insert("insert into student (stu_no,stu_name,stu_sex,stu_birth)values(#{stuNo},#{stuName},#{stuSex},#{birth})")int addStudent(Student student);
@Delete("delete from student where stu_no = #{stu_no}")int delOne(String stu_no);
@Update("update student set stu_name = #{stuName} where stu_no = #{stuNo}")int uptStudent(Student student);
}
mybatis缓存
MyBatis 中的缓存就是说 MyBatis 在执行一次SQL查询或者SQL更新之后,这条SQL语句并不会消失,而是被MyBatis 缓存起来,当再次执行相同SQL语句的时候,就会直接从缓存中进行提取,而不是再次执行SQL命令。
mybatis的缓存机制有两级:
(1)一级缓存:一级缓存mybatsi已经为我们自动开启,不用我们手动操作,而且我们是关闭不了的!!但是我们可以手动清除缓存。(SqlSession级别.提交事务,缓存清空)
一级缓存失效的情况:
1.不同的SqlSession对应不同的缓存 2.同一个SqlSession但是查询条件不同 3.同一个SqlSession执行两次相同查询之间做了增删改的操作 4.同一个SqlSession执行两次相同查询之间手动清空缓存
(2)二级缓存:二级缓存需要我们手动开启。(全局级别 SqlSessionFactory)
<!--开启二级缓存--> 开启二级缓存需要两个步骤,第一步在mybatis的全局配置文件中配置Setting属性,设置名为cacheEnabled的属性值为true即可 <settings><!-- (1):开启二级缓存,这个全局的配置二级缓存默认是开启的,但是还是需要写上,防止版本的更新 --><setting name="cacheEnabled" value="true"/> </settings> 第二步:在具体需要二级缓存的mapeer映射文件中开启二级缓存,值需要在相应的映射文件中添加一个cache标签即可 2):在相应的映射文件中开启二级缓存 <!-- 开启二级缓存 --><cache></cache> 3)查询数据封装的实体类要实现序列化的接口 4)二级缓存需要在一级缓存关闭或者提交后生效 二级缓存失效的条件: 1.在两次查询之间进行了任意的增删改操作,一级二级缓存同时失效
@Testpublic void test02(){//验证mybatis的缓存机制 一级缓存 默认开启 sqlsession级别
try {InputStream resource = Resources.getResourceAsStream("config/mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resource);SqlSession sqlSession = factory.openSession(true);StudentDao mapper1 = sqlSession.getMapper(StudentDao.class);StudentDao mapper2 = sqlSession.getMapper(StudentDao.class);System.out.println(mapper1);System.out.println(mapper2);List<Student> a1 = mapper1.getAll();System.out.println(a1);//手动提交事务 清空缓存sqlSession.commit();List<Student> a2 = mapper2.getAll();System.out.println(a2);
sqlSession.close();} catch (IOException e) {e.printStackTrace();}}
@Testpublic void test03(){//验证mybatis的缓存机制 二级缓存 需要配置mybatis-config.xml 和mapper文件
try {InputStream resource = Resources.getResourceAsStream("config/mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resource);SqlSession sqlSession1 = factory.openSession(true);SqlSession sqlSession2 = factory.openSession(true);SqlSession sqlSession3 = factory.openSession(true);
StudentDao mapper1 = sqlSession1.getMapper(StudentDao.class);StudentDao mapper2 = sqlSession2.getMapper(StudentDao.class);StudentDao mapper3 = sqlSession3.getMapper(StudentDao.class);List<Student> a1 = mapper1.getAll();System.out.println(a1);//关闭session将查询结果写入二级缓存sqlSession1.close();
//当对同一张表进行增删改操作后 二级缓存清除mapper3.delStudent("2021072901");// sqlSession3.close();
List<Student> a2 = mapper2.getAll();System.out.println(a2);
} catch (IOException e) {e.printStackTrace();}}
mybatis分页插件
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.2.1</version>
</dependency>
<!--在mybatis配置文件中 配置mybatis插件 -->
<plugins><plugin interceptor="com.github.pagehelper.PageInterceptor"><!-- 配置mysql方言 --><property name="helperDialect" value="mysql" /><!-- 设置为true时,如果pageSize=0就会查询出全部的结果 --><property name="pageSizeZero" value="true" /><!-- 3.3.0版本可用,分页参数合理化,默认false禁用 --><!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 --><!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 --><property name="reasonable" value="true" /></plugin></plugins>
实例
// 测试分页插件的使用
@Testpublic void test06(){SqlSession session = factory.openSession(true);StudentDao mapper = session.getMapper(StudentDao.class);PageHelper.startPage(5, 3);List<Student> all = mapper.findAll();PageInfo<Student> pageInfo = new PageInfo<>(all);
//获取分页的相关数据System.out.println(pageInfo);//获取总条数long total = pageInfo.getTotal();System.out.println(total);//获取当前页的显示数据List<Student> list = pageInfo.getList();list.forEach(student-> System.out.println(student));
}
相关文章:

Mybatis框架(全部基础知识)
👌 棒棒有言:也许我一直照着别人的方向飞,可是这次,我想要用我的方式飞翔一次!人生,既要淡,又要有味。凡事不必太在意,一切随缘,缘深多聚聚,缘浅随它去。凡事…...

pixhawk2.4.8使用调试记录—APM固件
目录一、硬件准备二、APM固件、MP地面站下载三、地面站配置1 刷固件2 机架选择3 加速度计校准4 指南针校准5 遥控器校准6 飞行模式7 紧急断电&无头模式8 基础参数设置9 电流计校准10 电调校准11 起飞前检查(每一项都非常重要)12 飞行经验四、遇到的问…...

终于进了字节,记录一下我作为一名测试员磕磕碰碰的三个月找工作经历...
我是裸辞后重新找工作的,从去年到今年,前前后后花了大概三个月,大大小小参加了几百场面试。不是我说,作为一名测试员是真的挺难的,不过很庆幸自己最后拿到了字节的offer,今天在这里做一下记录吧,…...

基于PYTHON django四川旅游景点推荐系统
摘 要基于四川旅游景点推荐系统的设计与实现是一个专为四川旅游景点为用户打造的旅游网站。该课题基于网站比较流行的Python 语言系统架构,B/S三层结构模式,通过Maven项目管理工具进行Jar包版本的控制。本系统用户可以发布个人游记,查看景点使用户达到良…...

MySql服务多版本之间的切换
从网上总结的经验,然后根据自己所遇到的问题合并记录一下,方便日后再次需要用到 MySql服务多版本同时运行 步骤 1、如果你电脑上已经有一个mysql版本,例如mysql-5.7.39-winx64,它占据了3306端口。此时如果你想下仔另一版本&…...

嵌入式开发:通过嵌入式虚
嵌入式虚拟化为实现多核处理能力的优势提供了一种可扩展的机制。嵌入式应用中的虚拟化与其企业和桌面应用有许多共同之处。独特的嵌入式使用案例和专业的底层技术为嵌入式开发人员提供了优化性能和响应设计的新机会。在台式机、数据中心以及现在的嵌入式设计中采用多核技术可以…...

广州穗雅医院杨济安:了解症状表现 有效防治口腔黏膜下纤维化
“医生,我出现口干大半年时间,最近两月张嘴费劲,吃点辣的,嘴就刺疼刺疼的,这是怎么回事?”半年前,家住南沙的文先生走进广州穗雅医院口腔黏膜科如是说到。在科室杨济安主任的详细问诊与检查后&a…...

[数据分析] 数据指标体系搭建
在数据分析的学习过程中,我们通常会要求掌握以下两点: 1.理解数据,懂得从数据中发现业务指标(学会如何去看懂数据) 2.使用相关指标去分析数据,同时使用多个指标去分析一个问题(了解常见的指标) 当我们拿到数据(通常以Excel或者数据库方式去…...

Dubbo 源码分析 – 集群容错之 Cluster
3.2.2 FailbackClusterInvoker FailbackClusterInvoker 会在调用失败后,返回一个空结果给服务提供者。并通过定时任务对失败的调用进行重传,适合执行消息通知等操作。下面来看一下它的实现逻辑。 public class FailbackClusterInvoker<T> extend…...

Spring学习20230208-09
IOC底层原理 IOC概念 :面向对象编程中的一种设计原则,用来降低耦合度 通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象引用传递给他。可以说,依赖被注入到对象中。控制反转&…...

tomcat10部署报错WebStatFilter cannot be cast to jakarta.servlet.Filter
异常信息09-Feb-2023 23:08:49.946 严重 [main] org.apache.catalina.core.StandardContext.filterStart 启动过滤器异常[DruidWebStatFilter]java.lang.ClassCastException: com.alibaba.druid.support.http.WebStatFilter cannot be cast to jakarta.servlet.Filterat org.ap…...

Linux修改文件时间或创建新文件:touch
每个文件在Linux下面都记录了许多的时间参数,其实是三个主要的变动时间 修改时间(modification time,mtime):当该文件的【内容数据】变更时,就会更新这个时间,内容数据是指文件的内容ÿ…...

原生微信小程序按需引入vant
vant Vant Weapp - 轻量、可靠的小程序 UI 组件库 1.npm安装 找到项目根目录 安装 # 通过 npm 安装 npm i vant/weapp -S --production# 通过 yarn 安装 yarn add vant/weapp --production# 安装 0.x 版本 npm i vant-weapp -S --production 2 .修改 app.json 将 app.jso…...

高性能IO模型:为什么单线程Redis能那么快?
我们通常说Redis是单线程,主要是指Redis的网络IO和键值对读写是由一个线程来完成的。这也是Redis对外提供键值存储服务的主要流程。 但redis的其他功能,比如持久化、异步删除、集群数据同步等,其实是由额外的线程执行的。 Redis为什么用单线…...

【数据集】中国各类水文专业常用数据集合集
1 水文气象数据 1.1 中国站点尺度天然径流量估算数据集(1961~2018年) 论文: J2022-High-quality reconstruction of China’s natural streamflow-缪驰远(北京师范大学地理科学学部) 研究内容:…...

落枕、肩颈酸痛,用磁疗就可缓解!
睡觉之前还是好好的,一觉醒来脖子莫名疼痛,转都转不了,有时候连肩膀和上肢都难受,很可能是“落枕”了。 落枕引起的肩颈疼痛与多种因素有关,如颈肩部肌肉的过度使用、不良的睡眠姿势或颈肩部受寒湿空气的侵袭ÿ…...

一文教会你如何选择远程桌面(五大主流远程软件全面讲解)
写在前面 作为程序员的我们,随时随地写代码改代码是我们的日常。刚回到家,就被老板、产品经理cue是常有的事。基于这种情况,一般都会随身携带电脑,随时备战,不过每天背着电脑上下班非常不方便。因此资深程序员的解决方…...

【yolov5】yolov5训练自己的数据集全流程----包含本人设计的快速数据处理脚本
关于yolo应用时能用到的脚本集合,推荐收藏: https://chenlinwei.blog.csdn.net/article/details/127299428 1. 工程化快速yolo训练流程指定版(无讲解) 1.1 抽样数据集xml转txt输出量化分析 python make_dataset.pymake_dataset…...

leaflet 加载CSV数据,显示图形(代码示例046)
第046个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中加载CSV文件,将图形显示在地图上。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果; 注意如果OpenStreetMap无法加载,请加载其他来练习 文章目录 示例效果配置方式示例源代码(共74…...

百趣代谢组学资讯:槟榔的基因组为雌雄同株植物的性别决定提供见解
文章标题:The genome of Areca catechu provides insights into sex determination of monoecious plants 发表期刊:New Phytologist 影响因子:10.323 作者单位:海南大学 百趣生物提供服务:植物激素高通量靶标定…...

SSO单点登录 - 多系统,单一位置登录,实现多系统同时登录 学习笔记
(1)单点登录 多系统的前提下,单一位置的登录,会实现多系统同时登录的一种技术。 常出现在互联网应用和企业级平台中 如:京东 单点登录一般是用于互相授信的系统,实现单一位置登录,全系统有效的。 注意:…...

图解LeetCode——剑指 Offer 32 - III. 从上到下打印二叉树 III
一、题目 请实现一个函数按照之字形顺序打印二叉树,即:第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。 二、示例 2.1> 示例1 提示: …...

【快排与归并排序算法】
作者:指针不指南吗 专栏:算法篇 🐾或许会很慢,但是不可以停下🐾 文章目录一、快速排序 ( Quick Sort )二、归并排序 ( Merge Sort )总结一、快速排序 ( Quick Sort ) 1.思路 找出一个分界点,随机的调整区间…...

面试官问我:说说你对JMM内存模型的理解?为什么需要JMM?
点个关注,必回关 随着CPU和内存的发展速度差异的问题,导致CPU的速度远快于内存,所以现在的CPU加入了高速 缓存,高速缓存一般可以分为L1、L2、L3三级缓存。基于上面的例子我们知道了这导致了缓存一致 性的问题,所以加入…...

工程管理系统源码之提高工程项目管理软件的效率
高效的工程项目管理软件不仅能够提高效率还应可以帮你节省成本提升利润 在工程行业中,管理不畅以及不良的项目执行,往往会导致项目延期、成本上升、回款拖后,最终导致项目整体盈利下降。企企管理云业财一体化的项目管理系统,确保…...

SpringBoot集成xxl-job实现
SpringBoot集成xxl-job实现 一、xxl-job介绍 xxl-job是一个分布式任务调度平台,核心设计目标是开发迅速、学习简单、轻量级、易扩展。源码:下载地址编译环境:Maven3、Jdk1.8、MySQL5.7 二、调度中心 初始化调度数据库,执行指定…...

欧几里得度量和余弦度量的可取消生物识别方案
欧几里得度量和余弦度量的可取消生物识别方案 便捷的生物识别数据是一把双刃剑,在为生物识别认证系统的繁荣铺平道路的同时,也带来了个人隐私问题。为了缓解这种担忧,提出了各种生物特征模板保护方案来保护生物特征模板免于信息泄露。现有提案…...

平板作为主机扩展屏的实现
网上有许多教程使用平板作为电脑的拓展屏,但是多数都是需要在电脑和平板上都装上服务器和客户端的软件才行,而且有些系统还没有对应的软件。 那有没有一种方法只需要在主机上运行一个软件,而平板上只需要扫个码就行呢? 答案是当然…...

HTTP和HTTPS有什么区别?如何实现网站的HTTPS?
细心的朋友会发现,我们在浏览网站时,有的网址以http开头,而有的网站却以https开头,那这两者之间有什么区别吗?http的网站如何能变成https呢?本文中科三方针对这个问题做下简单介绍。 什么是http࿱…...

Rockstar Games遭黑客攻击,《侠盗猎车手6》90个开发视频外泄
当地时间9月19日,视频游戏开发商Rockstar Games证实,其 热门游戏《侠盗猎车手6》(Grand Theft Auto)开发片段遭到黑客大规模窃取 ,这一泄露事件立即在游戏圈迅速传播。 据报道, 上周末黑客至少泄露了90个游…...