mybatis
2021-04-21 14:31:31 0 举报
AI智能生成
mybatis总结
作者其他创作
大纲/内容
三层架构
持久层(DAL)
和数据库进行交互
业务层(BLL)
处理业务需求
表现层(UI)
页面展示数据,jsp,html等
ORM
对象-关系数据库映射 Object-Relation Mapping
ORM是通过使用描述对象和数据库之间映射的元数据,将java程序中的对象自动持久化到关系数据库中
ORM是通过使用描述对象和数据库之间映射的元数据,将java程序中的对象自动持久化到关系数据库中
MVC
Model(模型)
一般指业务模型,代码中指JavaBean部分,数据模型 entity 业务模型 service
View (视图)
一般指用户看到的界面
,代码中指jsp,html,servlet等
,代码中指jsp,html,servlet等
Controller(控制器)
处理用户的请求和响应给用户的逻辑业务需求,对应代码中的servlet部分
JDBC步骤
1,使用jdbc编程需要连接数据库,注册驱动和数据库信息
2,操作Connection,打开Statement对象
3,通过Statement对象执行SQL,返回结果到ResultSet对象
4,使用ResultSet读取数据,然后通过代码转化为具体的POJO对象
5,关闭数据库相关的资源
1,使用jdbc编程需要连接数据库,注册驱动和数据库信息
2,操作Connection,打开Statement对象
3,通过Statement对象执行SQL,返回结果到ResultSet对象
4,使用ResultSet读取数据,然后通过代码转化为具体的POJO对象
5,关闭数据库相关的资源
jdbc技术列举
原生JDBC
Spring的JdbcTemplate(只属于工具)
Apache的DBUtils(只属于工具)
JDBC的缺点和Mybatis的优点
JDBC缺点
(1)需要频繁的创建数据库连接
(2)涉及到的增删改查等功能需要在各个java文件中编写大量代码
(3)对于底层事务、数据类型转换等都需要手动处理,又是各种代码
(2)涉及到的增删改查等功能需要在各个java文件中编写大量代码
(3)对于底层事务、数据类型转换等都需要手动处理,又是各种代码
mybatis优点
(1)封装了jdbc对数据库的各种操作,减少代码
(2)增加了连接池、一、二级缓存
(3)可以自动生成sql语句
(2)增加了连接池、一、二级缓存
(3)可以自动生成sql语句
什么是mybatis
MyBatis是一款优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。
mybatis和hibernate比较
1. Hibernate是全自动的,MyBatis是半自动的 Hibernate实现了部分自动生成SQL
2. MyBatis真正实现了java代码和sql的分离
3. SQL优化上 MyBatis强于Hibernate
4. MyBatis优化维护方便 SQL全存在于XML中 不需要修改源代码
5. 开发效率上 Hibernate略强于mybatiss
6. 从性能上说 因为Mybatis全都是自己手写的SQL,因此性能相对较高反之。Hibernate更加提倡使用HQL,HQL往往会查询更多的字段,从而性能反而较低
2. MyBatis真正实现了java代码和sql的分离
3. SQL优化上 MyBatis强于Hibernate
4. MyBatis优化维护方便 SQL全存在于XML中 不需要修改源代码
5. 开发效率上 Hibernate略强于mybatiss
6. 从性能上说 因为Mybatis全都是自己手写的SQL,因此性能相对较高反之。Hibernate更加提倡使用HQL,HQL往往会查询更多的字段,从而性能反而较低
环境搭建(非注解)
第一步:创建maven工程并导入坐标
<?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.wuyang</groupId>
<artifactId>ssm_mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!--mysql数据库依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<!--日志依赖-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
</project>
<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.wuyang</groupId>
<artifactId>ssm_mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!--mysql数据库依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<!--日志依赖-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
</project>
第二步:创建实体类和dao的接口
实体类
public class User implements Serializable {
private Integer id;
private String username;
private String address;
private String sex;
private Date birthday;
get set
tostring
实现Serializable 接口是为了确保类的唯一性,会自动分配一个类的id,确保序列化的执行
private Integer id;
private String username;
private String address;
private String sex;
private Date birthday;
get set
tostring
实现Serializable 接口是为了确保类的唯一性,会自动分配一个类的id,确保序列化的执行
接口
/**
* 用户持久层接口
*/
public interface UserDao {
/**
* 查询所有
* @return
*/
List<User> findAll();
}
* 用户持久层接口
*/
public interface UserDao {
/**
* 查询所有
* @return
*/
List<User> findAll();
}
第三步:创建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">
<!--mybatis主配置文件-->
<configuration>
<!--mybatis全局设置-->
<settings>
<!--控制日志输出到控制台-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境-->
<environment id="mysql">
<!--配置事务-->
<transactionManager type="JDBC"/>
<!--配置数据源(连接池)-->
<dataSource type="POOLED">
<!--配置数据库的4个基本信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="147"/>
</dataSource>
</environment>
</environments>
<!--配置映射文件-->
<mappers>
<mapper resource="com/wuyang/dao/UserDao.xml"/>
</mappers>
</configuration>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--mybatis主配置文件-->
<configuration>
<!--mybatis全局设置-->
<settings>
<!--控制日志输出到控制台-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境-->
<environment id="mysql">
<!--配置事务-->
<transactionManager type="JDBC"/>
<!--配置数据源(连接池)-->
<dataSource type="POOLED">
<!--配置数据库的4个基本信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="147"/>
</dataSource>
</environment>
</environments>
<!--配置映射文件-->
<mappers>
<mapper resource="com/wuyang/dao/UserDao.xml"/>
</mappers>
</configuration>
第四步:创建映射配置文件
<?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.wuyang.dao.UserDao">
<!--配置查询所有,id对应UserDao接口中方法findAll()-->
<select id="findAll" resultType="com.wuyang.entity.User">
select * from user;
</select>
</mapper>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wuyang.dao.UserDao">
<!--配置查询所有,id对应UserDao接口中方法findAll()-->
<select id="findAll" resultType="com.wuyang.entity.User">
select * from user;
</select>
</mapper>
第五步,创建测试类
初始化
@Before//用于测试方法执行之前执行
public void init() throws Exception {
//读取配置文件
in = Resources.getResourceAsStream("sqlMapConfig.xml");
//创建SqlSessionFactory工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//使用工厂生产SqlSession对象,true是自动提交事务
sqlSession = factory.openSession(true);
//使用SqlSession创建Dao接口的代理对象
userDao = sqlSession.getMapper(UserDao.class);
}
public void init() throws Exception {
//读取配置文件
in = Resources.getResourceAsStream("sqlMapConfig.xml");
//创建SqlSessionFactory工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//使用工厂生产SqlSession对象,true是自动提交事务
sqlSession = factory.openSession(true);
//使用SqlSession创建Dao接口的代理对象
userDao = sqlSession.getMapper(UserDao.class);
}
垃圾回收(销毁)
@After//用于测试方法执行之后执行
public void destroy() throws Exception {
//sqlSession.commit();
//手动设置自动提交,每次运行时
sqlSession.close();
in.close();
}
public void destroy() throws Exception {
//sqlSession.commit();
//手动设置自动提交,每次运行时
sqlSession.close();
in.close();
}
注意映射文件UserDao.xml要放在resources下,不然就要配置指定资源插件
mbatis多表查询(非注解)
方法一:创建新的实体类AccountUser extends Account,映射配置文件使用resultType="accountuser",不推荐,不常用,非常麻烦的又创建了一个实体类AccountUser
public class AccountUser extends Account{
private String username;
private String address;
private String username;
private String address;
<select id="findAllAccount" resultType="accountuser">
select a.*,u.username,u.address from account a,user u where u.id = a.uid;
</select>
select a.*,u.username,u.address from account a,user u where u.id = a.uid;
</select>
方法二:使用resultMap+collection标签(一对多时使用)
<resultMap id="userMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<collection property="roles" ofType="role">
<id property="roleId" column="rid"></id>
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
</collection>
</resultMap>
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<collection property="roles" ofType="role">
<id property="roleId" column="rid"></id>
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
</collection>
</resultMap>
方法三:使用resultMap+association标签(一对一&多对一使用)
<resultMap id="accountUserMap" type="account">
<!--为了避免两表联查时id重复,给子表id取别名为aid-->
<id property="id" column="aid"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<association property="user" column="uid" javaType="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
</association>
</resultMap>
<!--为了避免两表联查时id重复,给子表id取别名为aid-->
<id property="id" column="aid"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<association property="user" column="uid" javaType="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
</association>
</resultMap>
注解开发
maven配置文件
pom.xml
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
mybatis主配置文件
SqlMapperConfig.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>
<!--引入jdbc外部配置properties文件-->
<properties resource="jdbcConfig.properties"/>
<!--mybatis全局设置-->
<settings>
<!--控制日志输出到控制台-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--不写也行,高版本mybatis默认开启,但没使用,使用需注解@CacheNamespace(blocking = true)-->
<setting name="cacheEnabled" value="true"/>
</settings>
<!--分别配置别名,不分大小写-->
<typeAliases>
<package name="com.tdcq.bean"/>
</typeAliases>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"/>
<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>
<package name="com.tdcq.dao"/>
</mappers>
</configuration>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--引入jdbc外部配置properties文件-->
<properties resource="jdbcConfig.properties"/>
<!--mybatis全局设置-->
<settings>
<!--控制日志输出到控制台-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--不写也行,高版本mybatis默认开启,但没使用,使用需注解@CacheNamespace(blocking = true)-->
<setting name="cacheEnabled" value="true"/>
</settings>
<!--分别配置别名,不分大小写-->
<typeAliases>
<package name="com.tdcq.bean"/>
</typeAliases>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"/>
<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>
<package name="com.tdcq.dao"/>
</mappers>
</configuration>
jdbc属性配置文件
jdbcConfig.properties
driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/ssm
username = root
password = 147
url = jdbc:mysql://localhost:3306/ssm
username = root
password = 147
javaBean
User.java
public class User implements Serializable {
private Integer id;
private String username;
private String address;
private String sex;
private Date birthday;
接口
UserDao.java
public interface UserDao {
/**
* 查询所有用户
*
* @return
*/
@Select("select * from user")
List<User> findAll();
/**
* 查询所有用户
*
* @return
*/
@Select("select * from user")
List<User> findAll();
测试类
UserTest.java
public class MybatisAnnotationTest {
private InputStream inputStream;
private SqlSessionFactory sqlSessionFactory;
private SqlSession sqlSession;
private UserDao userDao;
@Before//初始化
public void init() throws Exception {
//1.获取字节输入流
inputStream = Resources.getResourceAsStream("SqlMapperConfig.xml");
//2.根据字节输入流构建SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//3.根据SqlSessionFactory生产一个SqlSession
sqlSession = sqlSessionFactory.openSession();
//4.使用SqlSession获取Dao对象
userDao = sqlSession.getMapper(UserDao.class);
}
@After//释放资源
public void destroy() throws Exception {
sqlSession.commit();
sqlSession.close();
inputStream.close();
}
/**
* 查询所有
*/
@Test
public void testfindAll() {
userDao.findAll();
}
private InputStream inputStream;
private SqlSessionFactory sqlSessionFactory;
private SqlSession sqlSession;
private UserDao userDao;
@Before//初始化
public void init() throws Exception {
//1.获取字节输入流
inputStream = Resources.getResourceAsStream("SqlMapperConfig.xml");
//2.根据字节输入流构建SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//3.根据SqlSessionFactory生产一个SqlSession
sqlSession = sqlSessionFactory.openSession();
//4.使用SqlSession获取Dao对象
userDao = sqlSession.getMapper(UserDao.class);
}
@After//释放资源
public void destroy() throws Exception {
sqlSession.commit();
sqlSession.close();
inputStream.close();
}
/**
* 查询所有
*/
@Test
public void testfindAll() {
userDao.findAll();
}
一对一&多对一(使用注解)
实体类
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
//多对一(mybatis中称为一对一)映射
//一个账户只能属于一个用户
private User user;
private Integer id;
private Integer uid;
private Double money;
//多对一(mybatis中称为一对一)映射
//一个账户只能属于一个用户
private User user;
接口
/**
* 查询所有账户,并且获取每个账户所属的用户信息
* 一对一&多对一
* @return
*/
@Select("select * from account")
//如果只有当前接口使用就不必起id = "accountUserMap"
@Results(id = "accountUserMap", value = {
//id=true表示主键
//property对应实体类属性名,column对应数据库列名
@Result(id = true, column = "id", property = "id"),
@Result(column = "uid", property = "uid"),
@Result(column = "money", property = "money"),
//把当前account表的uid作为下一个表的参数
@Result(column = "uid", property = "user",
//一对一(多对一)采用one = @One
//fetchType = FetchType.EAGER 加载类型为立即加载,
//一共有两种加载类型LAZY(懒加载,缓加载,也叫延迟加载),EAGER(立即加载),DEFAULT(不写默认立即加载);
one = @One(select = "com.tdcq.dao.UserDao.findById", fetchType = FetchType.EAGER))
})
List<Account> findAll();
* 查询所有账户,并且获取每个账户所属的用户信息
* 一对一&多对一
* @return
*/
@Select("select * from account")
//如果只有当前接口使用就不必起id = "accountUserMap"
@Results(id = "accountUserMap", value = {
//id=true表示主键
//property对应实体类属性名,column对应数据库列名
@Result(id = true, column = "id", property = "id"),
@Result(column = "uid", property = "uid"),
@Result(column = "money", property = "money"),
//把当前account表的uid作为下一个表的参数
@Result(column = "uid", property = "user",
//一对一(多对一)采用one = @One
//fetchType = FetchType.EAGER 加载类型为立即加载,
//一共有两种加载类型LAZY(懒加载,缓加载,也叫延迟加载),EAGER(立即加载),DEFAULT(不写默认立即加载);
one = @One(select = "com.tdcq.dao.UserDao.findById", fetchType = FetchType.EAGER))
})
List<Account> findAll();
测试
初始化略
/**
* 查询所有账户,并且获取每个账户所属的用户信息
* 一对一(多对一)立即加载
*/
@Test
public void testfindAll() {
List<Account> accounts = accountDao.findAll();
for (Account account: accounts){
System.out.println(account);
System.out.println(account.getUser());
}
}
* 查询所有账户,并且获取每个账户所属的用户信息
* 一对一(多对一)立即加载
*/
@Test
public void testfindAll() {
List<Account> accounts = accountDao.findAll();
for (Account account: accounts){
System.out.println(account);
System.out.println(account.getUser());
}
}
一对多(使用注解)
实体类
public class User implements Serializable {
private Integer id;
private String username;
private String address;
private String sex;
private Date birthday;
//一对多关系映射,一个用户对应多个账号
private List<Account> accounts;
private Integer id;
private String username;
private String address;
private String sex;
private Date birthday;
//一对多关系映射,一个用户对应多个账号
private List<Account> accounts;
接口
/**
* 查询所有用户,并且获取所有用户的所有账号
* 一对多
*
* @return
*/
@Select("select * from user")
//只有当前接口使用的可以不定义id="userAccountMap"
@Results(value = {
@Result(id = true, column = "id", property = "id"),
@Result(column = "username", property = "username"),
@Result(column = "address", property = "address"),
@Result(column = "sex", property = "sex"),
@Result(column = "birthday", property = "birthday"),
//把当前user表中的id作为下一个sql语句的参数
@Result(column = "id", property = "accounts",
//一对多使用懒加载(延迟加载,缓加载)
many = @Many(select = "com.tdcq.dao.AccountDao.findAccountByUid", fetchType = FetchType.LAZY)
)
})
List<User> findAll2();
* 查询所有用户,并且获取所有用户的所有账号
* 一对多
*
* @return
*/
@Select("select * from user")
//只有当前接口使用的可以不定义id="userAccountMap"
@Results(value = {
@Result(id = true, column = "id", property = "id"),
@Result(column = "username", property = "username"),
@Result(column = "address", property = "address"),
@Result(column = "sex", property = "sex"),
@Result(column = "birthday", property = "birthday"),
//把当前user表中的id作为下一个sql语句的参数
@Result(column = "id", property = "accounts",
//一对多使用懒加载(延迟加载,缓加载)
many = @Many(select = "com.tdcq.dao.AccountDao.findAccountByUid", fetchType = FetchType.LAZY)
)
})
List<User> findAll2();
测试
/**
* 查询所有用户,并且获取所有用户的所有账号
* 一对多,延迟加载
*/
@Test
public void testFindAll2(){
List<User> users = userDao.findAll2();
for (User user:users){
System.out.println("------------------------------------------------------------");
System.out.println(user);
System.out.println(user.getAccounts());
}
}
* 查询所有用户,并且获取所有用户的所有账号
* 一对多,延迟加载
*/
@Test
public void testFindAll2(){
List<User> users = userDao.findAll2();
for (User user:users){
System.out.println("------------------------------------------------------------");
System.out.println(user);
System.out.println(user.getAccounts());
}
}
二级缓存
主配置文件SqlMapperConfig.xml
<settings>
<!--不写也行,高版本mybatis默认开启,但没使用,使用需注解@CacheNamespace(blocking = true)-->
<setting name="cacheEnabled" value="true"/>
</settings>
<!--不写也行,高版本mybatis默认开启,但没使用,使用需注解@CacheNamespace(blocking = true)-->
<setting name="cacheEnabled" value="true"/>
</settings>
接口
@CacheNamespace(blocking = true)
public interface UserDao {
public interface UserDao {
测试
@Test
public void testFindOne2() {
SqlSession session = factory.openSession();
UserDao userDao = session.getMapper(UserDao.class);
User user = userDao.findById(47);
System.out.println(user);
session.close();//释放一级缓存
SqlSession session1 = factory.openSession();//再次打开session
UserDao userDao1 = session1.getMapper(UserDao.class);
User user1 = userDao1.findById(47);
System.out.println(user1);
System.out.println(user==user1);
session1.close();
}
public void testFindOne2() {
SqlSession session = factory.openSession();
UserDao userDao = session.getMapper(UserDao.class);
User user = userDao.findById(47);
System.out.println(user);
session.close();//释放一级缓存
SqlSession session1 = factory.openSession();//再次打开session
UserDao userDao1 = session1.getMapper(UserDao.class);
User user1 = userDao1.findById(47);
System.out.println(user1);
System.out.println(user==user1);
session1.close();
}
一级缓存的生命周期
1.MyBatis在开启一个数据库会话时,会 创建一个新的SqlSession对象,SqlSession对象中会有一个新的Executor对象,Executor对象中持有一个新的PerpetualCache对象;当会话结束时,SqlSession对象及其内部的Executor对象还有PerpetualCache对象也一并释放掉。
2.如果SqlSession调用了close()方法,会释放掉一级缓存PerpetualCache对象,一级缓存将不可用;
3. 如果SqlSession调用了clearCache(),会清空PerpetualCache对象中的数据,但是该对象仍可使用;
4.SqlSession中执行了任何一个update操作(update()、delete()、insert()) ,都会清空PerpetualCache对象的数据,但是该对象可以继续使用;
一级缓存和二级缓存的区别
1.一级缓存使用SqlSession存储,二级缓存使用SqlSessionFactory存储
2.一级缓存存储的是对象,二级缓存存储的是数据
0 条评论
下一页