概述
Mybatis是基于java的持久层框架,采用ORM思想(对象关系映射)去解决实体和数据的映射关系。内部封装了jdbc功能省略了jdbc一些接口的操作,只需要操作配置文件
注意:实体类中的属性和数据库中的需要保持一致
#利用框架开发三种方式:
1、xml文件配置(映射)
2、注解
3、注解结合xml
注意:如果sql语句复杂用xml配置映射
maven的安装与配置
压缩包解压到D盘的根目录下
1、配置MAVEN_HOME路径
2、配置path路径
3、查看安装结果,成功则显示版本号和上一步配置的路径
cmd命令行输入mvn -v
4、搭载本地仓库
找到maven下的conf文件夹中的settings.xml
国外网站的jar包下载很慢,需要使用阿里云的镜像
需要在 mirrors 标签中添加以下代码
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
找到settings标签中添加这段代码
注意:在D:/下新建repository文件夹
在idea中配置路径
开始干活!
创建web项目骨架maven工程:
pom.xml文件添加依赖
测试代码
把工程部署到Tomcat服务器上
这样便可在tomcat服务器上运行成功
创建工程
打印输入是否成功
小功能:右键点击Generate可自动生成set/get方法
基于MyBatis搭载框架工程
首先展示xml配置实现
是通过配置文件 pom.xml(依赖坐标),核心配置文件xml,映射文件xml。
实际开发中要求:mybatis下一般不写dao层接口的实现类
实现查询
(一)MyBatis搭建工程(利用xml文件方式)
1、新建maven项目
本次演示不创建骨架
在百度搜索MyBatis官方文档找到搭建所需要的依赖
2、pom.xml文件导入依赖
<!--依赖的坐标-->
<dependencies>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency>
<!--日志文件(必加的)-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--测试 (必加的)-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
3、创建实体类
需要继承于序列化接口 封装私有属性 get/set方法等
4、用户持久层接口
在源码目录下(java)创建接口,路径包名com.neuedu.dao.UserDao
public interface UserDao {
/查询所有用户信息/
List findAll();
}
5、填写配置文件SqlMappingConfig.xml
resources配置目录下创建文件:SqlMappingConfig.xml
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">
<configuration>
<environments default="mysql">
<!--配置mysql的环境 default和id内容需一致-->
<environment id="mysql">
<!--配置的事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)-->
<dataSource type="POOLED">
<!--详细数据的基本信息(所连接数据库的信息) 4个-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/student"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--找这个里面的配置文件,与该类形成映射关系 从而联系整个mybatis工程-->
<mapper resource="com/neuedu/dao/UserDao.xml"/>
</mappers>
</configuration>
6、设置Mapper代理方式的配置文件(xml)
resources路径下,写一个UserDao.xml的映射配置文件
要求要与对应Mapper的dao层接口包路径一致,只不过在resources下
添加协议和mapper映射
<?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.neuedu.dao.UserDao">
<!--配置sql语句 查询所有用户信息-->
<select id="findAll" resultType="com.neuedu.domain.User">
select * from users
</select>
</mapper>
7、编写测试类具体实现过程
package com.neuedu.test;
import com.neuedu.dao.UserDao;
import com.neuedu.domain.User;
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.InputStream;
import java.util.List;
public class MyBatisTest {
public static void main(String[] ages) throws IOException {
//1、读取配置文件
InputStream in = Resources.getResourceAsStream("SqlMappingConfig.xml");
//2、创建SqlSessionFactory工厂(工厂模式)*/
//创建工厂的过程 mybatis使用构建者模式(将对象细节隐藏,使用时直接调用方法就可以拿到对象)
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3、使用工厂生产SqlSession对象
SqlSession session = factory.openSession();
//4、利用该对象SqlSession 可以创建Dao接口的代理对象(代理模式,不需要new对象)
UserDao userDao = session.getMapper(UserDao.class);
//5、使用代理对象调用执行方法
List<User> users = userDao.findAll();
for (User user : users){
System.out.println(user);
}
//6、释放资源
session.close();
in.close();
}
}
(二)MyBatis搭建工程(利用注解方式)
注解的特点:
annotation 注解(原理就是通过class类实现的),不需要配置xml文件了。
注解的实现使代码又一次减少了 不需要创建和配置映射文件的xml(userdao. xml文件)如图所示
使用@select注解通过class直接指向接口并调用其中方法
以上利用配置xml方式和注解两种方式演示了查询
以下演示方式为配置xml文件,实际开发中我们主要利用xml配置。
实现插入
1、parameterType属性:代表了接口传参(对象)的类型
2、sql语句中使用#{}字符格式:它代表占位符,相当于jdbc中的?
在实体类中取出来的属性。
3、#{user.username}是ognl表达式,apache提供的一种表达式语言。
注意:数据库中插入是DML语句,属于事务。在关闭资源之前需要手动提交 session.commit()
<!--新增用户操作-->
<insert id="insertUser" parameterType="com.neuedu.domain.User">
insert into users(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{Address})
</insert>
测试方法
整合测试代码:
测试方法不使用main方法,以后使用测试方法 @Test
@Test 代表测试方法,一个类中可以有多个
@Before 在测试方法运行之前先执行这个方法
@After 在测试之后执行
如:
package com.neuedu.test;
import com.neuedu.dao.UserDao;
import com.neuedu.domain.User;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
public class MyBatisTest {
private InputStream in;
private SqlSession session;
private UserDao userDao;
@Before//在测试方法之前执行
public void init() throws IOException {
//1、读取配置文件
in = Resources.getResourceAsStream("SqlMappingConfig.xml");
//2、创建SqlSessionFactory工厂(工厂模式)*/
//创建工厂的过程 mybatis使用构建者模式(将对象细节隐藏,使用时直接调用方法就可以拿到对象)
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3、使用工厂生产SqlSession对象
session = factory.openSession();
//4、利用该对象SqlSession 可以创建Dao接口的代理对象(代理模式,不需要new对象)
userDao = session.getMapper(UserDao.class);
}
@After//在测试方法指向后执行
public void destory() throws IOException {
//提交事务
session.commit();
//6、释放资源
session.close();
in.close();
}
@Test
public void testSelectAll(){
List<User> users = userDao.findAll();
for (User user : users){
System.out.println(user);
}
}
@Test
public void testInsert(){
//模拟的用户数据
User user = new User();
user.setUsername("haha");
user.setSex("男");
user.setBrithday(new Date());
user.setAddress("沈阳浑南区");
//执行插入用户的方法
userDao.insertUser(user);
}
}
实现更新(Update)
修改方法
<!--更新用户信息-->
<update id="updateUser" parameterType="com.neuedu.domain.User">
update users set username=#{username}, birthday=#{birthday},
sex=#{sex},address=#{Address} where id=#{id}
</update>
实现删除(delete)
模糊查询(like)
方式一:(提倡)
在这里插入图片描述
方式二
方式1:
因为配置文件中没有%,所以要求我们在传入参数时,需要给模糊查询%的标识
配置文件中#{username} 也只是一个占位符,在sql语句中显示?
<!--模糊查询-->
<select id="findByName" resultType="com.neuedu.domain.User">
select * from users where username like #{username}
</select>
方式2:
<!--模糊查询-->
<select id="findByName" parameterType="java.lang.String" resultType="com.neuedu.domain.User">
select * from users where username like '%${value}%'
</select>
注意:原有的#{}占位符,改成了value {value}写法是固定的,不能写成其他的名字
分组查询
扩展:新增用户时id的返回
keyColumn 对应表中的列
keyProperty 对应实体类中属性
resultType 结果集的类型
order 插入前/后获取结果集 后的话属性值就填AFTER(after)
问题:#{}
与${}
区别?
1、#{}表示的是一个占位符号
通过#{}可以实现preparedStatement中的占位符的值的设置
#{}可以有效的防治注入漏洞
2、${}表示拼接sql语句
${}无法防止注入漏洞
参数核心配置文件及其映射文件参数
指这两个文件:
1、SqlMappingConfig.xml配置
2、mapper映射文件(userDao.xml)
parameter属性
用作指明dao层接口参数的数据类型,指向实体类。
接口的参数的形式:
1、传入基本数据类型,会自动转换包装类可不用全限定类型(类名+包名)
2、传入字符串类型,指明全限定类名
3、传入pojo(简单的java实体类)对象,指明全限定类名
例子:
根据用户名查询用户信息,一个类中存的另一个类的对象作为属性,再当作查询条件使用。
public class QueryVo{ //pojo类
private User user;
private A a;
private int age;
setXX
getXX
}
userDao.xml文件中
resultMap 结果类型(含有映射关系的)
作用:将表中的列和实体类中属性建立映射关系
如这种情况:命名不一致时,表中username----实体类中userName。
修改原有的配置文件
建立User实体类与数据库表的映射关系
UserDao.xml
改造前
利用resultMap后
<!--建立User实体类与数据库表的映射关系
id:给一个唯一的标识,给查询select标签引用的
type:指定实体类的全限定类名
-->
<resultMap id="userMap" type="com.neuedu.domain.User">
<!--id 用于主键字段 需要单独描述出来
column:表中的列
property:实体类中的属性
-->
<id column="id" property="id"></id>
<result column="username" property="userName"></result>
<result column="birthday" property="birthday"></result>
<result column="sex" property="sex"></result>
<result column="address" property="address"></result>
</resultMap>
<select id="findAll" resultMap="userMap">
select * from users
</select>
总结:resultMap实际应用就是为了解决表的列名和实体类中属性名不一致的问题。后续多表查询的时候也会应用。
核心配置文件内标签简介(SqlMappingConfig.xml)
configuration标签中的内容和书写顺序:
properties 属性
propety
settings 设置全局配置参数
setting
typeAliases 类型别名
typeAlias
...
environments 环境变量
environment
transactionManager 事务管理
dataSource 数据库源
mappers 映射器:起到的作用就是将核心配置文件和映射文件进行有效的关联
properties 属性,主要针对数据库的配置
两种方式可以配置
方式1:
<properties>
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mydata"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</properties>
方式2:(常用)
建立一个db.propertis文件放在resources下,就识别为配置文件。
文件中配置数据库jdbc的连接信息
<!--配置数据源(连接池)-->
<dataSource type="POOLED">
<!--配置详细的数据的基本信息 4个基本信息-->
<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>
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydata
jdbc.username=root
jdbc.password=123456
typeAliases 类型的别名
MyBatis默认支持别名,实际开发中我们会采用自定义别名的方式来开发
但是注意:如果名字弄乱了,一堆错误。
<typeAliases>
<!--单个别名定义-->
<typeAlias alias="user" type="com.neuedu.domain.User"></typeAlias>
<!--当有多个实体类需要别名的时候
指定了该实体类的包路径后,该包下面所有的实体类都会有自己的注册别名
别名就是我们的类名
-->
<package name="com.neuedu.domain"/>
</typeAliases>
核心配置文件中的<mappers>
mapper下
resource属性,相当于resource路径下的文件:识别xml这样的资源文件
“com/neuedu/dao/UserDao.xml”
class属性:类路径 按照包的形式写
com.neuedu.dao.UserDao
接口不一定只有一个接口,同样映射文件也不一定只有一个映射文件
当有多个的时候,我们使用package标签(重要)
<package name=""/>
注册指定包下的所有mapper接口(就是指定包下的映射xml文件都放在这里比如userDao.xml)
注意:要求mapper接口名和mapper映射文件名字要相同,且放在同一个目录中
<?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">
<!--mybatis核心配置-->
<configuration>
<!--指定用于properties配制文件的位置,要求配置文件必须在类的路径下-->
<properties resource="db.propertis">
</properties>
<!--别名设置 所用的别名就是我们真实的类名-->
<typeAliases>
<package name="com.neuedu.domain"/>
</typeAliases>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql的环境 default和id内容一致的-->
<environment id="mysql">
<!--配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)-->
<dataSource type="POOLED">
<!--配置详细的数据的基本信息 4个基本信息-->
<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>
<package name="com.neuedu.dao"/>
</mappers>
</configuration>
动态sql——实际应用就是在条件查询上
动态sql语句实际应用:就是为了解决复杂的sql语句的业务逻辑,场景是在应用于业务逻辑比较复杂的时候。
例如:查询用户信息,如果名字不为空则按照具体的名字查询;如果性别不为空还可以根据性别查询;如果名字和性别都不为空,按照名字和性别查询。
1、if标签
<resultMap id="userMap" type="User">
<!--id 用于主键字段
column:表中的列
property:实体类中的属性
-->
<id column="id" property="id"></id>
<result column="username" property="userName"></result>
<result column="birthday" property="birthday"></result>
<result column="sex" property="sex"></result>
<result column="address" property="address"></result>
</resultMap>
<!--根据条件查询-->
<select id="findUserByCondition" resultMap="userMap" parameterType="User">
select * from users where 1=1
<if test="userName != null">
and username = #{userName}
</if>
<if test="sex != null">
and sex = #{sex}
</if>
</select>
2、where标签
where标签可以简化if标签的操作
<select id="findUserByCondition" resultMap="userMap" parameterType="User">
select * from users
<where>
<if test="userName != null">
and username = #{userName}
</if>
<if test="sex != null">
and sex = #{sex}
</if>
</where>
</select>
3、foreach标签
API:
foreach 用于遍历集合
collection 代表了要遍历的集合元素
open 代表了语句的开始部分
close 代表语句结束部分
注意:开始指的是遍历集合数据
item 代表了遍历集合中的每个元素,生成的变量名
separator 分隔符
注意:
1、封装pojo类 封装了用户对象和存储id的集合对象
2、foreach标签的sql的拼接形式
例如
有一个需求:
传入多个id查询用户信息,将id存放的信息当做一个集合,传入集合对集合中的数据遍历使用就可以了。
<!--根据QueryVo 中提供的id集合,查询用户信息-->
<select id="findUserByInIds" resultMap="userMap" parameterType="QueryVo">
select * from users
<where>
<if test="ids != null and ids.size() > 0">
<foreach collection="ids" open="and id in(" close=")" item="uid" separator=",">
#{uid}
</foreach>
</if>
</where>
</select>
多表查询 (重点)
概述:
mybatis下 实体关系
1)一对一关系 两张表他们之间没有中间表的
2)一对多关系 可能有中间表也可能没有
3)多对多的关系 双向的一对多关系 有中间表
表结构 需要合理建立对应的表并设置外键联系
主要操作还是框架中的配置 xml 标签
(一)多对多关系(双向一对多):
两个实体类,其中一个含有另一个对象的集合。
注意: 是以一对多形式为例,进行实现双向一对多,本质就是多对多关系。
第一张表跟中间表连,第一次连接后的结果再跟另一张表第二次连接,
两个实体类,其中一个含有另一个对象的集合。
模拟一个场景:用户和角色的关系模型
需求:查询角色的时候把角色所对应的所有用户信息查出来
because:
(一个用户可以有多个角色)
(一个角色可以赋予多个用户)
so:
当查询用户时,可以同时得到用户所包含的角色信息
当查询角色时,可以同时得到角色所赋予的用户信息
xml文件中的标签说明:
<collection property="users" ofType="user">
collection标签:就是实现一对多的映射关系
property属性:指向实体类中一个对象集合(用户类的对象)作为的属性
ofType属性:集合中储存元素的类型,另一张表在数据库中的映射关系
操作步骤:
1、建立两张表
用户表(id 用户名 性别 出生日期 地址)
角色表(id 角色名称 角色描述)
额外增加一张表:中间表(作用就是为了实现两张表的的多对多对应关系)
中间表:包含两张表的主键,在中间表是外键
用户编号 角色编号
2、根据表结构建立两个实体类
用户类
角色类
3、建立两个映射的配置文件
用户的映射文件
角色的映射文件
4、实现配置查询
当查询用户时,可以同时得到用户所包含的角色信息
当查询角色时,可以同时得到角色所赋予的用户信息
首先从实体类中下手
需要在Role实体类中实现一个角色对应多个用户
//一个角色对应多个用户
private List<User> users;
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
查询所有角色,同时获取角色对应的用户。并书写role表中的resultMap
<resultMap id="roleMap" type="Role">
<id property="roleId" column="ID"></id>
<result property="roleName" column="ROLE_NAME"></result>
<result property="roleDesc" column="ROLE_DESC"></result>
<collection property="users" ofType="user">
<id column="id" property="id"></id>
<result column="username" property="userName"></result>
<result column="birthday" property="birthday"></result>
<result column="sex" property="sex"></result>
<result column="address" property="address"></result>
</collection>
</resultMap>
<select id="findAll" resultMap="roleMap">
select u.*,r.id as rid,r.role_name,r.role_desc from role r
left join user_role ur on r.id = ur.rid
left join user u on u.id = ur.uid
</select>
注意:如果sql语句中给表中某一列改列名时,resultMap中的映射关系也要对应
另张表的信息也要查出来所以另张表的xml文件也要配置
(二)一对一关系
两个实体类,其中一个含有另一个对象。
指的是一个账户只有一个用户的信息。
场景:银行系统中的账户和用户
需求:查询银行账户的时候把它唯一对应的用户信息查出来。
比如银行系统中一个账号对应一个用户(使用者),(一多一)
但是一个用户可以有多个银行账号,(一对多)
如下两个表中有对应的关系,这时多表查询时,不需要中间表。
标签说明:
<association property="user" column="UID" javaType="User">
association标签:说明一个银行账号跟一个用户的一对一的映射关系。
property属性:另一张表中的一个对象(一条数据)。
column:和另张表的连接条件(表结构中的列)。
javaType:实体类中属性(就是连接的另张表)的数据类型,property属性对应对象的数据类型。
数据库中表的关系
账户表
用户信息表
<!--查询所有的信息-->
<select id="findAll" resultMap="accountUserMap">
select u.*, a.id as aid, a.uid, a.money
from account a, user u
where u.id = a.uid
</select>
<!--定义account和resultMap的形式-->
<resultMap id="accountUserMap" type="Account">
<id property="id" column="ID"></id>
<result property="uid" column="UID"></result>
<result property="money" column="MONEY"></result>
<!--一对一关系的映射-->
<association property="user" column="UID" javaType="User">
<id column="id" property="userId"></id>
<result column="username" property="userName"></result>
<result column="birthday" property="userBirthday"></result>
<result column="sex" property="userSex"></result>
<result column="address" property="userAddress"></result>
</association>
</resultMap>
resultMap和resultType的区别?
自己总结是当数据库中的列和实体类中的属性有对应时使用resultMap
MyBatis的每一个查询映射的返回类型都是ResultMap,只是当我们提供的返回类型属性是resultType的时候,MyBatis对自动的给我们把对应的值赋给resultType所指定对象的属性,而当我们提供的返回类型是resultMap的时候,将数据库中列数据复制到对象的相应属性上,可以用于复制查询,两者不能同时用
延迟加载
概述:
先查询一张表,如果查出来的信息不够使用通过映射文件设置select属性连接其他的方法。
针对关联查询
实际开发中,我们并不需要总是加载用户信息
加载分类:
1)延迟加载(懒加载):在真正使用数据时才发起查询,不用的时候不查询
2)立即加载:不管用不用,都需要调用方法发起查询
延迟加载 好处:
弊端是多表查询,所有信息都查询出来。
先查询单表,如果单表满足不了需求,再去做多表查询
在加载情况下表的实体关系:
一对一 一对多 多对一 多对多
1)一对多 多对多 采用延迟加载
2)多对一 一对一 采用立即加载
mybatis默认的是立即加载
需求:
1)查询账户信息和用户信息(这个需求需要多表)
如果先查账户信息可以满足要求,那么就查询单表,如果满足不了要求,那就关联用户信息表查询——延迟加载
通过association 、collection实现延迟加载书写
通过association实现延迟加载:
<!--一对一关系的映射:配置封装User内容
select:查询用户的唯一标识
column:用户根据id查询时,所需要的参数
-->
<association property="user" column="UID" javaType="User" select="com.neuedu.dao.UserDao.findById">
</association>
开启延迟加载 核心配置文件中设置
<!--配置参数-->
<settings>
<!--开启MyBatis的延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
通过collection实现延迟加载
需求:
1)查询用户信息和它所对应的账户信息
<!-- 配置user对象中accounts集合的映射 -->
<collection property="accounts" ofType="account" select="com.neuedu.dao.AccountDao.findByUid" column="id">
</collection>
延时加载使用场景:
延迟加载是一种MyBatis的机制,这种机制就为了合理的使用资源,能单表查的不要多表查,如果单表查不到,关联到多表查询
做关联查询时
1、确定需求需要多表那就做多表连接
2、不确定是否多表连接,可以有时候需要单表,有时候需要多表 就做延迟加载
缓存
概述:
针对于查询,存在于内存中的临时数据,第一次查询缓存到内存中,下一次相同的操作直接使用内存中的缓存,减少了对数据库的操作次数
作用:为了减少查询数据库的次数,从而提高性能
MyBatis缓存分为一级缓存和二级缓存
一级缓存:SqlSession对象的缓存(了解。在二级缓存的结构基础之上)
二级缓存:SqlSessionFactory对象的缓存,由同一个SqlSessionFactory对象创建的SqlSession共享其缓存
一级缓存使用步骤(了解)
一级缓存 SqlSession 不需要手动开启,只要针对该对象没有close或者flush 缓存就存在,
关闭一级缓存
clearCache() 清除缓存
close flush
二级缓存使用步骤
1、框架支持二级缓存 核心配置文件中设置
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
2、让当前的映射文件支持二级缓存
<!--开启二级缓存的支持 针对mapper文件-->
<cache></cache>或<cache/>都可以
3、让当前操作支持二级缓存 select
<!-- 根据id查询所有 -->
<select id="findById" resultType="User" parameterType="Integer" useCache="true">
select * from user where id = #{uid}
</select>
useCache="true" 开启映射文件的二级缓存
注意:如果不使用二级缓存,那么针对每次查询都需要从数据获取的最新数据(useCache=“false”)
问题:二级缓存对象不一致?
解决:存在二级缓存时,所缓存的类要求一定要实现Serializable接口 网络通讯序列化方式保存对象。