文章目录
一、Jdbc回顾
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//通过驱动管理类获取数据库链接
connection = DriverManager
.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8","ro
ot", "root");
//定义 sql 语句 ?表示占位符
String sql = "select * from user where username = ?";
//获取预处理 statement
preparedStatement = connection.prepareStatement(sql);
//设置参数,第一个参数为 sql 语句中参数的序号(从 1 开始),第二个参数为设置的参数值
preparedStatement.setString(1, "王五");
//向数据库发出 sql 执行查询,查询出结果集
resultSet = preparedStatement.executeQuery();
//遍历查询结果集
while(resultSet.next()){
System.out.println(resultSet.getString("id")+"
"+resultSet.getString("username"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//释放资源
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(preparedStatement!=null){
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
二、myBatis基本使用
1、xml使用
(一). 导入坐标
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>xx.xx.xx</version>
</dependency>
(二). 编写实体类
public class User{
private int id;
private String username;
private String password;
}
(三). 编写持久层接口
public interface UserDao {
//TODO
}
//或
public interface UserMapper {
//TODO
}
(四). 编写持久层接口的映射文件 UserDao.xml(UserMapper.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="">
</mapper>
注意:
1.配置文件和Dao接口的包结构相同
也就是说:若UserDao所在的包为cn.edu.szu.Test.Dao,
那么,在resource下也需要一个UserDao.xml文件所在的包为cn.edu.szu.Test.Dao。
2.配置文件mapper标签的namespace属性值必须是Dao接口的全限定类名。
3.配置文件操作配置的id属性值必须是Dao接口的方法名。
(五). 编写SqlMapConfig.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>
<!-- 配置 mybatis 的环境 -->
<environments default="mysql">
<!-- 配置 mysql 的环境 -->
<environment id="mysql">
<!-- 配置事务的类型 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置连接数据库的信息:用的是数据源(连接池) -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/testDB"/>
<property name="username" value="root"/>
<property name="password" value="1234"/>
</dataSource>
</environment>
</environments>
<!-- 告知 mybatis 映射配置的位置 -->
<mappers>
<mapper resource="cn/edu/szu/Test/Dao/UserDao.xml"/>
</mappers>
</configuration>
(六). 测试类
public class MybatisTest {
public static void main(String[] args)throws Exception {
//1.读取配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建 SqlSessionFactory 的构建者对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.使用构建者创建工厂对象 SqlSessionFactory
SqlSessionFactory factory = builder.build(in);
//4.使用 SqlSessionFactory 生产 SqlSession 对象
SqlSession session = factory.openSession();
//5.使用 SqlSession 创建 dao 接口的代理对象
IUserDao userDao = session.getMapper(IUserDao.class);
//6.使用代理对象执行查询所有方法
List<User> users = userDao.findAll();
for(User user : users) {
System.out.println(user);
}
//7.释放资源
session.close();
in.close();
}
}
2、注解使用
(一).在xml的基础下,移除XXXMapper.xml文件,改为在XXXDao上使用@select…等注解。
(二). 在SqlMapConfig.xml文件当中将mappers标签里mapper的配置改为Dao接口的全限定类名。
三、myBatis深入学习
1、基于代理 Dao 实现 CRUD 操作
1、持久层接口和持久层接口的映射配置必须在相同的包下
2、持久层映射配置中 mapper 标签的 namespace 属性取值必须是持久层接口的全限定类名
3、SQL 语句的配置标签,,,的 id 属性必须和持久层接口的方法名相同。
标签当中的一些属性及占位符:
resultType 属性:用于指定结果集的类型。
parameterType属性:用于指定传入参数的类型。
sql 语句中使用#{}字符:它代表占位符,相当于原来 jdbc 部分所学的?,都是用于执行语句时替换实际的数据。
具体的数据是由#{}里面的内容决定的。
基 本 类 型 和 String 我 们 可 以 直 接 写 类 型 名 称 , 也 可 以 使 用 包 名 . 类 名 的 方 式 , 例 如 :
java.lang.String。
实体类类型,目前我们只能使用全限定类名。
究其原因,是 mybaits 在加载时已经把常用的数据类型注册了别名,从而我们在使用时可以不写包名,
而我们的是实体类并没有注册别名,所以必须写全限定类名。
findById
<select id="findById" resultType="cn.edu.szu.Test.POLO.User" parameterType="int">
select * from user where id = #{id}
</select>
注意:
#{}中内容的写法(#{id}):
由于数据类型是基本类型,所以此处可以随意写。
save
<insert id="saveUser" parameterType="cn.edu.szu.Test.POLO.User">
insert into user(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address})
</insert>
注意:
#{}中内容的写法:
由于我们保存方法的参数是 一个 User 对象,此处要写 User 对象中的属性名称。
它用的是 ognl 表达式。
ognl 表达式:
它是 apache 提供的一种表达式语言,全称是:
Object Graphic Navigation Language 对象图导航语言
它是按照一定的语法格式来获取数据的。
语法格式就是使用 #{对象.对象}的方式:
#{user.username}它会先去找 user 对象,然后在 user 对象中找到 username 属性,并调用
getUsername()方法把值取出来。但是我们在 parameterType 属性上指定了实体类名称,所以可以省略 user.
而直接写 username。
update
<update id="updateUser" parameterType="cn.edu.szu.Test.POLO.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},
address=#{address} where id=#{id}
</update>
delete
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id = #{id}
</delete>
模糊匹配
第一种方式:
<select id="findByName" resultType="cn.edu.szu.Test.POLO.User" parameterType="String">
select * from user where username like #{username}
</select>
传参的时候使用"%参数值%"
第二种方式:
使用${}:
<select id="findByName" parameterType="string" resultType="cn.edu.szu.Test.POJO.User">
select * from user where username like '%${value}%'
</select>
#{}与${}的区别
#{}表示一个占位符号:
通过#{}可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型转换,#{}可以有效防止 sql 注入。 #{}可以接收简单类型值或 pojo 属性值。 如果 parameterType 传输单个简单类
型值,#{}括号中可以是 value 或其它名称。
$ {}表示拼接 sql 串:
通过$ {}可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换, $ {}可以接收简
单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,${}括号中只能是 value。
新增用户 id 的返回值
新增用户后,同时还要返回当前新增用户的 id 值,因为 id 是由数据库的自动增长来实现的,所以就相
当于我们要在新增后将自动增长 auto_increment 的值返回。
<insert id="saveUser" parameterType="USER">
<!-- 配置保存时获取插入的 id -->
<selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
2、Mybatis 的输出结果封装
正常情况下,我们要求POJO的属性值与数据库字段名相同,结果集封装的时候,Mybatis会自动按照属性值利用反射机制进行封装,而当POJO属性值与数据库字段值不同的时候,有些字段就无法进行封装,而解决这个问题,有两种解决思路。
1.修改SQL语句
<select id="findAll" resultType="cn.edu.szu.Test.POJO.User">
select id as userId,username as userName,birthday as userBirthday,
sex as userSex,address as userAddress from user
</select>
在sql语句上,使用 “as” 为数据库字段取别名,取得别名就是POJO对象的属性值名,可以实现数据的封装。
由于这种方式是在数据库层面解决问题,因此这种方式效率是最高的。
2.使用resultMap 结果类型
定义resultMap :
<resultMap type="cn.edu.szu.Test.POJO.User" id="userMap">
<id column="id" property="userId"/>
<result column="username" property="userName"/>
<result column="sex" property="userSex"/>
<result column="address" property="userAddress"/>
<result column="birthday" property="userBirthday"/>
</resultMap>
其中:
type 属性:指定实体类的全限定类名
id 属性:给定一个唯一标识,是给查询 select 标签引用用的。
id 标签:用于指定主键字段
result 标签:用于指定非主键字段
column 属性:用于指定数据库列名
property 属性:用于指定实体类属性名称
映射配置
<select id="findAll" resultMap="userMap">
select * from user
</select>
3、SqlMapConfig.xml配置文件
SqlMapConfig.xml 中配置的内容和顺序
-properties(属性)
–property
-settings(全局配置参数)
–setting
-typeAliases(类型别名)
–typeAliase
–package
-typeHandlers(类型处理器)
-objectFactory(对象工厂)
-plugins(插件)
-environments(环境集合属性对象)
–environment(环境子属性对象)
—transactionManager(事务管理)
—dataSource(数据源)
-mappers(映射器)
–mapper
–package
typeAliases
<typeAliases>
<!-- 单个别名定义 -->
<typeAlias alias="user" type="cn.edu.szu.Test.POJO.User"/>
<!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) -->
<package name="cn.edu.szu.Test.POJO"/>
<package name="其它包"/>
</typeAliases>
mappers
1.使用相对于类路径的资源
<mapper resource="cn/edu/szu/UserMapper.xml"/>
2.使用 mapper 接口类路径
<mapper class="cn.edu.szu.UserMapper"/>
注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中。
3.注册指定包下的所有 mapper 接口
<package name="cn.edu.szu.Mapper"/>
注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中。
4、Mybatis 连接池与事务
连接池
Mybatis 将它自己的数据源分为三类:
UNPOOLED 不使用连接池的数据源
POOLED 使用连接池的数据源
JNDI 使用 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>
MyBatis 在初始化时,根据< dataSource>的 type 属性来创建相应类型的的数据源 DataSource,即:
type=”POOLED”:MyBatis 会创建 PooledDataSource 实例
注意:
使用“POOLED”时,myBatis会准备两个池,一个是空闲池,一个是活动池,当获取连接的时候,首先去空闲池找,如果空闲池没有连接了,就查看活动池,如果活动池拥有的连接小于最大连接,则在活动池创建一个新的连接返回,如果活动池连接数已满,则找到活动池年龄最大,也就是最早进入的连接处理后返回。
type=”UNPOOLED” : MyBatis 会创建 UnpooledDataSource 实例
type=”JNDI”:MyBatis 会从 JNDI 服务上查找 DataSource 实例,然后返回使用。
这个模式采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是不一样。
注意:如果不是web或者maven的war工程,是不能使用的。
我们课程中使用的是tomcat服务器,采用连接池就是jdbc连接池。
Mybatis 中事务提交方式
手动提交:
//TODO
session = factory.openSession();
//TODO
session.commit();
//TODO
自动提交:
session = factory.openSession(true);
JNDI数据源的使用
JNDI:Java Naming and Directory Interface。是SUN公司推出的一套规范,属于JavaEE技术之一。目的是模仿windows系统中的注册表。
1.创建javaEE工程
2.导入相关依赖
3.在META-INF目录中建立一个名为context.xml的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!--
<Resource
name="jdbc/eesy_mybatis" 数据源的名称
type="javax.sql.DataSource" 数据源类型
auth="Container" 数据源提供者
maxActive="20" 最大活动数
maxWait="10000" 最大等待时间
maxIdle="5" 最大空闲数
username="root" 用户名
password="1234" 密码
driverClassName="com.mysql.jdbc.Driver" 驱动类
url="jdbc:mysql://localhost:3306/mybatisLearn" 连接url字符串
/>
-->
<Resource
name="jdbc/eesy_mybatis"
type="javax.sql.DataSource"
auth="Container"
maxActive="20"
maxWait="10000"
maxIdle="5"
username="root"
password="1234"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mybatisLearn"
/>
</Context>
4.修改SqlMapConfig.xml中的配置
<dataSource type="JNDI">
<property name="data_source" value="java:comp/env/jdbc/mybatisLearn"/>
</dataSource>
5、Mybatis 的动态 SQL 语句
动态 SQL 之 < if> 标签
<select id="findByUser" resultType="user" parameterType="user">
select * from user where 1=1
<if test="username!=null and username != '' ">
and username like #{username}
</if>
<if test="address != null">
and address like #{address}
</if>
</select>
注意:< if>标签的 test 属性中写的是对象的属性名,如果是包装类的对象要使用 OGNL 表达式的写法。
另外要注意 where 1=1 的作用!
动态 SQL 之< where>标签
与前面的写法区别就是1=1
<select id="findByUser" resultType="user" parameterType="user">
select * from user
<where>
<if test="username!=null and username != '' ">
and username like #{username}
</if>
<if test="address != null">
and address like #{address}
</if>
</where>
</select>
动态标签之< foreach>标签
<!-- 查询所有用户在 id 的集合之中 -->
<select id="findInIds" resultType="user" parameterType="queryvo">
<!-- select * from user where id in (1,2,3,4,5); -->
<include refid="defaultSql"></include>
<where>
<if test="ids != null and ids.size() > 0">
<foreach collection="ids" open="id in ( " close=")" item="uid"
separator=",">
#{uid}
</foreach>
</if>
</where>
</select>
SQL 语句:
select 字段 from user where id in (?)
< foreach>标签用于遍历集合,它的属性:
collection:代表要遍历的集合元素,注意编写时不要写#{}
open:代表语句的开始部分
close:代表结束部分
item:代表遍历集合的每个元素,生成的变量名
sperator:代表分隔符
抽取SQL 片段
<!-- 抽取重复的语句代码片段 -->
<sql id="defaultSql">
select * from user
</sql>
<select id="findAll" resultType="user">
<include refid="defaultSql"></include>
</select>
6、Mybatis 多表查询
association标签使用
需求:
从数据库当中查询出Account信息并且查询出User的信息封装到user字段当中。
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
private User user;
}
<!-- 建立对应关系 -->
<resultMap type="account" id="accountMap">
<id column="aid" property="id"/>
<result column="uid" property="uid"/>
<result column="money" property="money"/>
<!-- 它是用于指定从表方的引用实体属性的 -->
<association property="user" javaType="user">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="birthday" property="birthday"/>
<result column="address" property="address"/>
</association>
</resultMap>
<select id="findAll" resultMap="accountMap">
select u.*,a.id as aid,a.uid,a.money from account a,user u where a.uid =u.id;
</select>
collection标签的使用
需求:
查询所有用户信息及用户关联的账户信息。
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
private List<Account> accounts;
}
<resultMap type="user" id="userMap">
<id column="id" property="id"></id>
<result column="username" property="username"/>
<result column="address" property="address"/>
<result column="sex" property="sex"/>
<result column="birthday" property="birthday"/>
<!-- collection 是用于建立一对多中集合属性的对应关系
ofType 用于指定集合元素的数据类型
-->
<collection property="accounts" ofType="account">
<id column="aid" property="id"/>
<result column="uid" property="uid"/>
<result column="money" property="money"/>
</collection>
</resultMap>
<!-- 配置查询所有操作 -->
<select id="findAll" resultMap="userMap">
select u.*,a.id as aid ,a.uid,a.money from user u left outer join account
a on u.id =a.uid
</select>
7、Mybatis 延迟加载策略
主要的原理就是,在用到相关属性的时候才会到那个配置文件当中寻找执行sql语句并将结果封装返回。
首先,在SqlMapperConfig.xml文件当中开启延迟加载的全局开关。
<!-- 开启延迟加载的支持 -->
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
实体类
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
private User user;
}
一对一延迟
< association>中的select属性。
<mapper namespace="cn.edu.szu.Test.UserMapper">
<!-- 建立对应关系 -->
<resultMap type="account" id="accountMap">
<id column="aid" property="id"/>
<result column="uid" property="uid"/>
<result column="money" property="money"/>
<!-- 它是用于指定从表方的引用实体属性的 -->
<association property="user" javaType="user"
select="cn.edu.szu.Test.UserMapper.findById"
column="uid">
</association>
</resultMap>
<select id="findAll" resultMap="accountMap">
select * from account
</select>
</mapper>
延迟加载的效果:
只有访问Account当中的user成员变量的时候,才会执行根据id查找user的sql语句并且将结果封装至user当中,只是访问Account对象的话只会执行select * from account
一对多延迟
与一对一类似,使用< collection>当中加select属性,用法同上。
7、Mybatis 缓存
一级缓存:
它指的是Mybatis中SqlSession对象的缓存。
当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供一块区域中。
该区域的结构是一个Map。当我们再次查询同样的数据,mybatis会先去sqlsession中
查询是否有,有的话直接拿出来用。
当SqlSession对象消失时,mybatis的一级缓存也就消失了。
二级缓存:
它指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。
二级缓存的使用步骤:
第一步:让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
<settings>
<!-- 开启二级缓存的支持 -->
<setting name="cacheEnabled" value="true"/>
</settings>
因为 cacheEnabled 的取值默认就为 true,所以这一步可以省略不配置。为 true 代表开启二级缓存;为false 代表不开启二级缓存。
第二步:让当前的映射文件支持二级缓存(在UserMapper.xml中配置)
在UserMapper.xml文件当中添加< cache/>
第三步:让当前的操作支持二级缓存(在select标签中配置)
<!-- 根据 id 查询 -->
<select id="findById" resultType="user" parameterType="int" useCache="true">
select * from user where id = #{uid}
</select>
将 UserDao.xml 映射文件中的标签中设置 useCache=”true”代表当前这个 statement 要使用二级缓存,如果不使用二级缓存可以设置为 false。
注意:针对每次查询都需要最新的数据 sql,要设置成 useCache=false,禁用二级缓存。
(三)、MyBatis注解开发
注解开发只是通过配置注解代替了XXXMapper.xml文件,而SqlMapperConfig.xml文件还是需要的
1、常用注解:
@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@ResultMap:实现引用@Results 定义的封装
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
@SelectProvider: 实现动态 SQL 映射
@CacheNamespace:实现注解二级缓存的使用
2、CRUD
@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Select("select * from user")
List<User> findAll();
@Select("select * from user where id = #{uid} ")
@ResultMap("userMap")
User findById(Integer userId);
@Insert("insert into
user(username,sex,birthday,address)values(#{username},#{sex},#{birthday},#{address}
)")
@SelectKey(keyColumn="id",keyProperty="id",resultType=Integer.class,before =
false, statement = { "select last_insert_id()" })
int saveUser(User user);
@Update("update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id
=#{id} ")
int updateUser(User user);
@Delete("delete from user where id = #{uid} ")
int deleteUser(Integer userId);
}
3、@Results和@Result
@Results源码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Results {
String id() default "";
Result[] value() default {};
}
在一个方法上定义的@Results,其他的方法可以使用@ResultMap(value={"…"})的方式使用,不必重复定义。
@Result源码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Result {
//该属性对应列是否为主键
boolean id() default false;
//对应数据库的列名
String column() default "";
//对应实体类的属性名
String property() default "";
//实体类型类型
Class<?> javaType() default void.class;
JdbcType jdbcType() default JdbcType.UNDEFINED;
Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;
//一对一查询
One one() default @One;
//一对多查询
Many many() default @Many;
}
使用:
public interface AccountMapper {
/**
* 查询所有账户,采用延迟加载的方式查询账户的所属用户
*
* @return
*/
@Select("select * from account")
@Results(id = "accountMap",
value = {
@Result(id = true, column = "id", property = "id"),
@Result(column = "uid", property = "uid"),
@Result(column = "money", property = "money"),
)
})
List<Account> findAll();
}
一对一查询(@One的使用):
@One源码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface One {
//指定能执行功能的方法的全限定方法名
String select() default "";
/*
public enum FetchType {
LAZY,//延迟加载
EAGER,//立即加载
DEFAULT;//两个选一个
private FetchType() {
}
}
*/
FetchType fetchType() default FetchType.DEFAULT;
}
需求:查询所有的账户,并且查询出该用户的信息。
@Select("select * from account")
@Results(id="accountMap",
value= {
@Result(id=true,column="id",property="id"),
@Result(column="uid",property="uid"),
@Result(column="money",property="money"),
@Result(column="uid",
property="user",
one=@One(select="cn.edu.szu.Test.AccountMapper.findById",
fetchType=FetchType.LAZY)
)
})
List<Account> findAll();
一对多(@Many的使用):
需求:查询该用户的信息,并查询该用户所拥有的所有账户。
@Select("select * from user")
@Results(id="userMap",
value= {
@Result(id=true,column="id",property="userId"),
@Result(column="username",property="userName"),
@Result(column="sex",property="userSex"),
@Result(column="address",property="userAddress"),
@Result(column="birthday",property="userBirthday"),
@Result(column="id",property="accounts",
many=@Many(
select="cn.edu.szu.Test.AccountMapper.findById",
fetchType=FetchType.LAZY
)
)
})
List<User> findAll();
4、mybatis 基于注解的二级缓存
1.在SqlMapperCpnfig.xml开启二级缓存的支持:
<settings>
<!-- 开启二级缓存的支持 -->
<setting name="cacheEnabled" value="true"/>
</settings>
2.在持久层接口中使用注解配置二级缓存
@CacheNamespace(blocking=true)//mybatis 基于注解方式实现配置二级缓存
public interface UserMapper{}