目录
概述
那么什么是持久层呢?
什么是ORM?
MyBatis的环境搭建
第一步.创建一张表和表对应的实体类
这里我创建了一个Student类和student表来举例
package com.ffyc.mybatis.model;
import java.io.Serializable;
public class Student implements Serializable {
private Integer id;
private Integer num;//建议不使用基本类型 建议使用包装类型 默认值是null
private String name;
private String gender;
private Major major;//类与类之间的关联关系 has-a 什么有什么
public Major getMajor() {
return major;
}
public void setMajor(Major major) {
this.major = major;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", num=" + num +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", major=" + major +
'}';
}
}
第二步.导入MyBatis jar包和mysql数据驱动包
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
这里建议大家可以将这些常用的jar包整理起来,方便以后得使用。
第三步.创建MyBatis全局配置文件
需要将其放在一个名为mybatis.xml的文件中
<?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"><!--dtd文件是用来制定xml标签规范的-->
<configuration>
<environments default="development">
<environment id="development">
<!--
事务管理方式:就是一次对数据库操作过程中,执行多条sql管理
把所有的操作都成功执行后,再提交事务,让数据库最终执行本次提交的所有sql
-->
<!--事务管理方式-->
<transactionManager type="JDBC"/><!--使用jdbc事务管理-->
<!--数据库连接池配置
频繁地创建销毁与数据库的连接对象是比较占用时间和空间
可以在池子中默认创建若干个连接对象,有请求使用时,直接从连接池中取出一个对象,用完再还回去,
减少了创建和销毁的时间开销
-->
<dataSource type="POOLED">
<!--数据库连接-->
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/ssmdb?serverTimezone=Asia/Shanghai" />
<property name="username" value="root" />
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
</configuration>
第四步.创建sql映射文件
sql映射文件放在resources目录下创建一个mapper目录 创建一个StudentMapper.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"><!--dtd文件 叫xml的约束文件,定义xml标签-->
<mapper namespace="定义接口地址">
sql语句
</mapper>
在我们搭建好MyBatis环境后,我们需要测试一下。
定义一个接口StudentDao
package com.ffyc.mybatis.dao;
import com.ffyc.mybatis.model.Student;
import java.util.List;
public interface StudentDao {
List<Student> findStudents(Student student);
}
测试
我们可以查询一下我们在数据库中存储的学生信息
可以使用以下的代码来测试一下
package com.ffyc.mybatis.test;
import com.ffyc.mybatis.dao.AdminDao;
import com.ffyc.mybatis.model.Admin;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import javax.xml.ws.soap.Addressing;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
public class Test1 {
public static void main(String[] args) throws IOException {
//读入mybatis核心配置文件
Reader reader = Resources.getResourceAsReader("mybatis.xml");
//创建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
//创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//为接口创建一个代理对象
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
//调用我们自己的方法
List<Student> studentList = studentDao.findStudents();
System.out.println(studentList);
sqlSession.commit();//提交数据库事务 事务只针对新增 修改 删除操作 查询不需要提交事务的
//关闭与数据库的会话对象
sqlSession.close();
}
}
API接口说明
由于SqlSessionFactory接口在整个过程中只会创建一次,所以为了简化我们在项目中的代码,我们可以把其创建过程放在一个静态代码块里。
具体的代码如下 我们可以创建一个MybatisUtil的Class文件
package com.ffyc.mybatis.util;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.Reader;
public class MybatisUtil {
static SqlSessionFactory sqlSessionFactory = null;
static {
//读入mybatis核心配置文件
Reader reader = null;
try {
reader = Resources.getResourceAsReader("mybatis.xml");
} catch (IOException e) {
e.printStackTrace();
}
/*
创建SqlSessionFactory对象
SqlSessionFactory对象是用来创建SqlSession对象的
由于SqlSessionFactory对象创建的开销较大,所以一个项目中只创建一个SqlSessionFactory对象,不用关闭
*/
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
}
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
在以后得测试代码中,我们就可以向以下的代码这样写
package com.ffyc.mybatis.test;
import com.ffyc.mybatis.dao.StudentDao;
import com.ffyc.mybatis.model.Student;
import com.ffyc.mybatis.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class Test3 {
public static void main(String[] args) {
/*
SqlSession对象是与数据库交互的,每次与数据库连接都需要创建一个新的连接对象
用完关闭即可
*/
SqlSession sqlSession = MybatisUtil.getSqlSession();
//获取接口的代理对象,由代理对象调用接口中对应方法所匹配的sql
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
/*Student student = studentDao.findStudentById(1);
System.out.println(student);*/
/* List<Student> students = studentDao.findStudents();
System.out.println(students);*/
/* Student student = studentDao.findStudentById1(1);
System.out.println(student);*/
sqlSession.commit();
sqlSession.close();
}
}
这样的代码会更加简洁一些。
面向接口开发需要遵循的规范
Mybatis日志
配置方法
这个需要放在我们创建的StudentMapper文件中。
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/><!--打印执行日志-->
</settings>
参数传递
参数传递分为单个参数直接传递和多个参数使用@Param("id")绑定
具体代码如下
单个参数直接传递
<select id="findAdminById" parameterType="int" resultType="Admin">
select * from admin where id = #{id}
</select>
多个参数使用@Param("id")绑定
<select id="login" resultType="Admin">
select * from admin where account = #{account} and password = #{password}
</select>
如果传入一个复杂的对象,就需要使用paramterType参数进行类型定义:
例如:
void updateAdmin(Admin admin);
结果处理
对象映射
#{}和${}区别
特殊处理使用resultMap
定义resultMap
<resultMap id="adminmap" type="Admin">
<id property="id" column="id"></id><!--映射主键的-->
<result property="account" column="account"></result>
<result property="password" column="password"></result>
<result property="gender" column="gender"></result>
<result property="adminAge" column="admin_age"></result>
</resultMap>
使用resultMap
<select id="findAdminByAccount" parameterType="string" resultMap="adminmap">
select * from admin where account = #{account}
</select>
注意事项
多表关联处理结果集
此处需要用到resultMap元素中association,collection元素
Collection元素处理一对多关联
这里我用学生和专业的关系来举例
专业与学生一对多关系
专业一方,配置多方集合
public class Major {
private Integer id;
private String name;
private List<Student> students;
}
学生多方,在多方配置一方
public class Student implements Serializable {
private Integer id;
private Integer num;//建议不使用基本类型 建议使用包装类型 默认值是null
private String name;
private String gender;
private Major major;//类与类之间的关联关系 has-a 什么有什么
}
使用resultMap组装查询结果
<!--自定义结果映射关系-->
<resultMap id="studentMap" type="Student"><!--最终返回一个学生对象 将学生信息封装学生对象-->
<id property="id" column="id"></id><!--映射主键的-->
<result property="num" column="num"></result>
<result property="name" column="name"></result>
<result property="gender" column="gender"></result>
<association property="major" javaType="Major">
<result property="name" column="mname"></result>
</association>
</resultMap>
<select id="findStudentById" parameterType="int" resultMap="studentMap">
SELECT
s.id,
s.num,
s.name,
s.gender,
m.name mname
FROM
student s LEFT JOIN major m ON s.majorid = m.id
WHERE
s.id = #{id}
</select>
嵌套查询
将一个多表关联查询拆分为多次查询 先查询主表数据,然后查询关联表数据。
<!--嵌套查询 把一个关联查询分成两个单表查询,然后通过学生专业外键,查询关联专业信息-->
<resultMap id="studentMap1" type="Student">
<association property="major" javaType="Major" select="findMajorById" column="majorid"></association>
</resultMap>
<select id="findStudentById1" parameterType="int" resultMap="studentMap1">
SELECT
s.id,
s.num,
s.name,
s.gender,
s.majorid
FROM
student s
WHERE
s.id = #{id}
</select>
<select id="findMajorById" parameterType="int" resultType="Major">
SELECT
*
FROM
major
WHERE
id = #{id}
</select>
注解方式
常用注解标签
使用案例
Mybatis动态SQL
if元素
if标签可以对传入的条件进行判断
<if test="name!=null">
name = #{name},
</if>
<if test="num!=null">
num = #{num},
</if>
<if test="gender!=null">
gender = #{gender}
</if>
where元素
where元素会进行判断,如果他包含的标签中有返回值的话,它就插入一个'where'
此外,如果标签返回的内容是以AND 或 OR开头,它会剔除掉AND 或 OR
<select id="findStudents" resultType="Student">
select * from student
<where>
<if test="name!=null">
name = #{name}
</if>
<if test="num!=0">
and num = #{num}
</if>
<if test="gender!=null">
and gender = #{gender}
</if>
</where>
</select>
我们可以测试一下 看看运行时候的sql语句
package com.ffyc.mybatis.test;
import com.ffyc.mybatis.dao.StudentDao;
import com.ffyc.mybatis.model.Student;
import com.ffyc.mybatis.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.ArrayList;
import java.util.List;
public class Test5 {
public static void main(String[] args) {
/*
SqlSession对象是与数据库交互的,每次与数据库连接都需要创建一个新的连接对象
用完关闭即可
*/
SqlSession sqlSession = MybatisUtil.getSqlSession();
//获取接口的代理对象,由代理对象调用接口中对应方法所匹配的sql
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setName("张泽兴");
student.setGender("男");
student.setNum(20221808);
List<Student> students = studentDao.findStudents(student);
System.out.println(students);
sqlSession.commit();
sqlSession.close();
}
}
我们可以看到运行时的sql语句为
trim元素
让我们添加一个指定的前缀关键字,让我们去除指定的关键字
<!--trim 让我们添加一个指定的前缀关键字
让我们去除指定的关键字-->
<select id="findStudents" resultType="Student">
select * from student
<trim prefix="where" prefixOverrides="and|or">
<if test="name!=null">
name = #{name}
</if>
<if test="num!=0">
and num = #{num}
</if>
<if test="gender!=null">
and gender = #{gender}
</if>
</trim>
</select>
测试代码
package com.ffyc.mybatis.test;
import com.ffyc.mybatis.dao.StudentDao;
import com.ffyc.mybatis.model.Student;
import com.ffyc.mybatis.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.ArrayList;
import java.util.List;
public class Test5 {
public static void main(String[] args) {
/*
SqlSession对象是与数据库交互的,每次与数据库连接都需要创建一个新的连接对象
用完关闭即可
*/
SqlSession sqlSession = MybatisUtil.getSqlSession();
//获取接口的代理对象,由代理对象调用接口中对应方法所匹配的sql
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setName("张泽兴");
student.setGender("男");
student.setNum(20221808);
List<Student> students = studentDao.findStudents(student);
System.out.println(students);
sqlSession.commit();
sqlSession.close();
}
}
sql语句
choose元素
有时候我们不想使用所有的条件,而只是想从多个条件中选择一个使用。
choose元素有点像我们在JavaSE中学到的switch语句
<select id="findStudents" resultType="Student">
select * from student
<where>
<choose>
<when test="name!=null">
name = #{name}
</when>
<when test="num!=0">
and num = #{num}
</when>
<otherwise>
name = '李钰轩'
</otherwise>
</choose>
</where>
</select>
测试代码:
package com.ffyc.mybatis.test;
import com.ffyc.mybatis.dao.StudentDao;
import com.ffyc.mybatis.model.Student;
import com.ffyc.mybatis.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.ArrayList;
import java.util.List;
public class Test5 {
public static void main(String[] args) {
/*
SqlSession对象是与数据库交互的,每次与数据库连接都需要创建一个新的连接对象
用完关闭即可
*/
SqlSession sqlSession = MybatisUtil.getSqlSession();
//获取接口的代理对象,由代理对象调用接口中对应方法所匹配的sql
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setNum(20221807);
List<Student> students = studentDao.findStudents(student);
System.out.println(students);
sqlSession.commit();
sqlSession.close();
}
}
这里我们传入的student对象里有学生的学号,所以我们查询的结果就是为此学号的学生信息
如果我们传入的student对象里的学生学号或者学生姓名为null 这时就会查询<otherwise></otherwise> 里设置的条件
package com.ffyc.mybatis.test;
import com.ffyc.mybatis.dao.StudentDao;
import com.ffyc.mybatis.model.Student;
import com.ffyc.mybatis.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.ArrayList;
import java.util.List;
public class Test5 {
public static void main(String[] args) {
/*
SqlSession对象是与数据库交互的,每次与数据库连接都需要创建一个新的连接对象
用完关闭即可
*/
SqlSession sqlSession = MybatisUtil.getSqlSession();
//获取接口的代理对象,由代理对象调用接口中对应方法所匹配的sql
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setNum(0);
student.setName(null);
List<Student> students = studentDao.findStudents(student);
System.out.println(students);
sqlSession.commit();
sqlSession.close();
}
}
以下为运行结果:
set元素
set元素可以把最后一个逗号去掉
这个功能trim元素也可以实现
set元素实现代码
<!--
<set> 动态添加set关键字 还可以去掉最后的逗号
-->
<update id="updateStudent" parameterType="student">
update student
<set>
<if test="name!=null">
name = #{name},
</if>
<if test="num!=null">
num = #{num},
</if>
<if test="gender!=null">
gender = #{gender}
</if>
</set>
where id = #{id}
</update>
测试代码
<update id="updateStudent" parameterType="student">
update student
<trim prefix="set" suffixOverrides=",">
<if test="name!=null">
name = #{name},
</if>
<if test="num!=null">
num = #{num},
</if>
<if test="gender!=null">
gender = #{gender}
</if>
</trim>
where id = #{id}
</update>
sql语言
trim元素实现代码
<update id="updateStudent" parameterType="student">
update student
<trim prefix="set" suffixOverrides=",">
<if test="name!=null">
name = #{name},
</if>
<if test="num!=null">
num = #{num},
</if>
<if test="gender!=null">
gender = #{gender}
</if>
</trim>
where id = #{id}
</update>
测试代码
package com.ffyc.mybatis.test;
import com.ffyc.mybatis.dao.StudentDao;
import com.ffyc.mybatis.model.Student;
import com.ffyc.mybatis.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.ArrayList;
import java.util.List;
public class Test5 {
public static void main(String[] args) {
/*
SqlSession对象是与数据库交互的,每次与数据库连接都需要创建一个新的连接对象
用完关闭即可
*/
SqlSession sqlSession = MybatisUtil.getSqlSession();
//获取接口的代理对象,由代理对象调用接口中对应方法所匹配的sql
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setId(3);
student.setName("李四");
sqlSession.commit();
sqlSession.close();
}
}
sql语言
foreach元素
测试代码
<select id="findStudentsByColumn" resultType="Student">
select
<foreach collection="list" item="c" separator=",">
${c}
</foreach>
from student
</select>
特殊符号处理
演示代码
<!--
xml 中特殊符号的处理
解决方式1:使用转义字符代替
解决方式2:<![CDATA[ 特殊符号]]>
-->
<select id="findStudents1" parameterType="int" resultType="Student">
select * from student where num <![CDATA[<]]> #{num}
</select>
MyBatis的一级缓存和二级缓存
为什么使用缓存
缓存的作用是为了减轻数据库的压力,提高查询性能。缓存实现的原理是从数据库中查询出来的对象在使用完后不要销毁,而是存储在内存(缓存)中,当再次需要获取该对象时,直接从内存(缓存)中直接获取,不再向数据库 执行 select 语句,从而减少了对数据库的查询次数,因此提高了数据库的性能。
Mybatis 有一级缓存和二级缓存。一级缓存的作用域是同一个 SqlSession,在同一个 sqlSession 中两次执行相同的 sql 语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个 sqlSession 结束后该 sqlSession 中的一级缓存也就不存在了。Mybatis 默认开启一级缓存。
二级缓存是多个 SqlSession 共享的,其作用域是同一个 namespace,不同的 sqlSession 两次执行相同 namespace 下的 sql 语句且向 sql 中传递参数也相同即最终执行相同的 sql 语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率,Mybatis 默认没有开启二级缓存需要在 setting 全局参数中配置开启二级缓存。
一级缓存
Mybatis 对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个 SqlSession 而言。所以在参数和 SQL 完全一样的情况下,我们使用同一个 SqlSession 对象调用一个 Mapper 方法,往往只执行一次 SQL,因为使用 SelSession 第一次查询后MyBatis 会将其放在缓存中,以后再查询的时候,如果没有声明需要刷新,并且缓存没有超时的情况下,SqlSession 都会取出当前缓存的数据,而不会再次发送 SQL 到数据库。
一级缓存工作模式
一级缓存演示代码
package com.ffyc.mybatis.test;
import com.ffyc.mybatis.dao.StudentDao;
import com.ffyc.mybatis.model.Student;
import com.ffyc.mybatis.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.ArrayList;
public class Test6 {
public static void main(String[] args) {
/*
mybatis 框架也是提供了缓存功能
一级缓存:是SqlSession级别的,在同一个Sqlsession中相同的两次查询,只查询一次数据库
将第一次查询的数据存储在SqlSession对象中,第二次查询直接获取即可
一级缓存失效
1.执行增删改操作后,当前的一级缓存会清空
2.sqlSession.clearCache();强制清空一级缓存
3.sqlSession.close(); 关闭连接对象,清空一级缓存
*/
/*
SqlSession对象是与数据库交互的,每次与数据库连接都需要创建一个新的连接对象
用完关闭即可
*/
SqlSession sqlSession = MybatisUtil.getSqlSession();
//获取接口的代理对象,由代理对象调用接口中对应方法所匹配的sql
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
studentDao.findStudents1(1);//在同一个sqlSession中,再次查询相同的内容,会从一级缓存中查询,不会查询数据库
//执行删除操作,修改 新增操作后 会清空以及缓存数据
//sqlSession.clearCache();//强制清空一级缓存
studentDao.findStudents1(1);
sqlSession.commit();
sqlSession.close();
}
}
我们执行两次一样的查询操作,会发现在最后的输出结果中显示只会进行一次数据库的连接操作,因为以及缓存会将第一次查询的数据存储在SqlSession对象中,第二次查询直接获取即可。
但是如果我们在两次查询操作的中间加上
sqlSession.clearCache()(强制清空一级缓存),这时我们就会发现他会进行两次数据库的连接操作。
二级缓存
二级缓存是 SqlSessionFactory 级别的,根据 mapper 的 namespace 划分区域的,相同 namespace 的 mapper 查询的数据缓存在同一个区域,如果使用 mapper 代理方法每个 mapper 的 namespace 都不同,此时可以理解为二级缓存区域是根据 mapper 划分。 每次查询会先从缓存区域查找,如果找不到则从数据库查询,并将查询到数据写入缓存。Mybatis 内部存储缓存使用一个 HashMap,key 为hashCode+sqlId+Sql 语句。value 为从查询出来映射生成的 java 对象。sqlSession 执行 insert、update、delete 等操作 commit 提交后会清空缓存区域,防止脏读。
二级缓存配置操作
第一步.启用二级缓存
在我们前面创建的mybatis.xml文件中加入
<!--启用二级缓存-->
<setting name="cacheEnabled" value="true"/>
cacheEnabled 设置为 true 时启用二级缓存,设置为 false 时禁用二级缓存。
第二步.对象序列化
在我们创建时实体类对象实现序列化接口java.io.Serialzable
public class Student implements Serializable {
}
第三步.配置映射文件
在我们定义的StudentMapper.xml映射文件中添加<cache />
<!--设置二级缓存配置的
size="20" 缓存对象数量
flushInterval=""设置二级缓存的有效时间
-->
<cache size="20" flushInterval="3000"></cache>
二级缓存工作模式
二级缓存演示代码
package com.ffyc.mybatis.test;
import com.ffyc.mybatis.dao.StudentDao;
import com.ffyc.mybatis.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
public class Test7 {
public static void main(String[] args) {
/*
mybatis 框架也是提供了缓存功能
一级缓存:是SqlSession级别的,在同一个Sqlsession中相同的两次查询,只查询一次数据库
将第一次查询的数据存储在SqlSession对象中,第二次查询直接获取即可
一级缓存失效
1.执行增删改操作后,当前的一级缓存会清空
2.sqlSession.clearCache();强制清空一级缓存
3.sqlSession.close(); 关闭连接对象,清空一级缓存
二级缓存:
二次缓存是sqlSessionFactory级别(sqlSessionFactory对象只有一个,创建后就不关闭了,多个Sqlsession共享一个sqlSessionFactory)
使用是需要配置的
1.启用二级缓存
<setting name="cacheEnabled" value="true"/>
2.对象序列化
将所有的 POJO 类实现序列化接口 Java.io. Serializable
3.配置映射文件
在 Mapper 映射文件中添加<cache />,表示此mapper 开启二级缓存
*/
/*
SqlSession对象是与数据库交互的,每次与数据库连接都需要创建一个新的连接对象
用完关闭即可
*/
SqlSession sqlSession = MybatisUtil.getSqlSession();
//获取接口的代理对象,由代理对象调用接口中对应方法所匹配的sql
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
studentDao.findStudents1(2);
sqlSession.commit();
sqlSession.close();
SqlSession sqlSession1 = MybatisUtil.getSqlSession();
//获取接口的代理对象,由代理对象调用接口中对应方法所匹配的sql
StudentDao studentDao1 = sqlSession1.getMapper(StudentDao.class);
studentDao1.findStudents1(2);
sqlSession1.commit();
sqlSession1.close();
}
}
因为二级缓存是SqlSessionFactory 级别的,SqlSessionFactory对象只有一个,这里我们创建两个sqlsession对象,用来进行同样的查询操作,会发现在结果中1只进行了一次数据库的连接操作。