Mybaits学习

Mybatis介绍

mybatis是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句身,而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。 mybatis通过xml或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。 采用ORM思想解决了实体和数据库映射的问题,对jdbc进行了封装,屏蔽了jdbc api底层访问细节,使我们不用与jdbc api打交道,就可以完成对数据库的持久化操作。
它是一个半自动化框架。

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","root", "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(); 
		 	        }
	 	    } 
 	     } 
      } 
 	        //上边使用jdbc的原始方法(未经封装)实现了查询数据库表记录的操作。

jdbc存在问题:
1、数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
2、Sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
3、使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
4、对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。

两者比较:
1.数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。 解决: 在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。
2.Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。 解决: 将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
3.向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数对应。 解决: Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。
4.对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。 解决: Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。

搭建Mybatis开发环境

配置文件模式

  • 1.创建maven工程,并在pom.xml中导入Mybatis和其他相关包的依赖(mysql ,junit等)
<dependencies> 
	<dependency>
		 <groupId>org.mybatis</groupId> 
		 <artifactId>mybatis</artifactId> 
		 <version>3.4.5</version> 
	 </dependency>
    <dependency>
	     <groupId>junit</groupId> 
	     <artifactId>junit</artifactId> 
	     <version>4.10</version>
	      <scope>test</scope> 
      </dependency>
       <dependency> 
	       <groupId>mysql</groupId> 
	       <artifactId>mysql-connector-java</artifactId> 
	       <version>5.1.6</version> 
	       <scope>runtime</scope>
        </dependency> 
       <dependency> 
	       <groupId>log4j</groupId> 
	       <artifactId>log4j</artifactId>
	        <version>1.2.12</version> 
        </dependency> 
</dependencies>

2.编写相关实体类(对应着数据库)User,和持久层接口 IUserDao(mybatis不用写实现哦,将这个部分放在了注解或者配置文件中了)。
3.编写持久层接口的映射文件IUserDao.xml。
要求:
创建位置:
必须和持久层接口在相同的包中。
名称:
必须以持久层接口名称命名文件名,扩展名是.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="com.itheima.dao.IUserDao">
	  <!-- 配置查询所有操作 -->
	   <select id="findAll" resultType="com.itheima.domain.User"> select * from user </select>
	</mapper>

4.编写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/ee50"/> 
	  	 	    <property name="username" value="root"/> 
	  	 	    <property name="password" value="1234"/>
  	 	     </dataSource>
  	 	 </environment>
 	</environments> 
 	<!-- 告知mybatis映射配置的位置 每个.xml映射都要写!!!!!! --> 
 	<mappers> 
 		<mapper resource="com/itheima/dao/IUserDao.xml"/> 
 	</mappers> 
 </configuration>

-properties(属性)
–property -settings(全局配置参数)
–setting -typeAliases(类型别名)
–typeAliase
–package
-typeHandlers(类型处理器)
-objectFactory(对象工厂)
-plugins(插件)
-environments(环境集合属性对象)
–environment(环境子属性对象)
—transactionManager(事务管理)
—dataSource(数据源)
-mappers(映射器)
–mapper
–package

解耦改进:

<?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>
    <!-- 配置properties classpath下定义properties文件
jdbc.driver=com.mysql.jdbc.Driver 
jdbc.url=jdbc:mysql://localhost:3306/eesy 
jdbc.username=root 
jdbc.password=1234
-->
    <properties resource="jdbcConfig.properties"></properties>

    <!--使用typeAliases配置别名,它只能配置domain中类的别名 这样com.itheima.domain包下就不用写全限定类名了,默认为类本身名字 首字母大写或小写都可以 -->
    <typeAliases>
        <package name="com.itheima.domain"></package>
    </typeAliases>

    <!--配置环境-->
    <environments default="mysql">
        <!-- 配置mysql的环境-->
        <environment id="mysql">
            <!-- 配置事务 -->
            <transactionManager type="JDBC"></transactionManager>

            <!--配置连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"></property>
                <property name="url" value="${jdbc.url}"></property>
                <property name="username" value="${jdbc.username}"></property>
                <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>
    </environments>
    <!-- 配置映射文件的位置
    注册指定包下的所有mapper接口 如:<package name="cn.itcast.mybatis.mapper"/> 注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。 -->
    <mappers>
        <package name="com.itheima.dao"></package>
    </mappers>
</configuration>

5.使用:
//如果是增删改的话 还要提交事务 , 查询就不用

//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.使用代理对象执行查询所有方法 (或者定义通过增删改查方法,在sqlsession对象中提供selectList方法)
   List<User> users = userDao.findAll(); for(User user : users) { System.out.println(user); } 	
   //7.释放资源					  
    session.close(); 
    in.close();

注解模式

将以上做三点修改
1.把编写持久层接口的映射文件IUserDao.xml 删除。
2.在持久层接口的方法上方加入注解 @Select(“select * from user”) 代替xml文件作用
3.在SqlMapConfig.xml中把

<mapper resource="com/itheima/dao/IUserDao.xml"/>

改为

<mapper class="com.itheima.dao.IUserDao"/>

配置文件模式与注解使用详解

例1:

<select id="findById" resultType="com.itheima.domain.User" parameterType="int"> select * from user where id = #{uid} </select>

select :查询语句
id :对应持久层接口方法名
resultType :对应持久层接口方法返回类型(在没经过SqlMapConfig配置时,用全限定类名)
parameterType:对应持久层接口方法参数类型(基本类型和String可直接写)(如果是类名也得:在没经过SqlMapConfig配置时,用全限定类名)
sql语句中使用#{}字符: 它代表占位符,相当于原来jdbc部分所学的?,都是用于执行语句时替换实际的数据。 具体的数据是由#{}里面的内容决定的。 #{}中内容的写法: 由于数据类型是基本类型,所以此处可以随意写。

例2:

<insert id="saveUser" parameterType="com.itheima.domain.User"> insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) </insert>

insert:插入语句
parameterType:参数为类,由于我们保存方法的参数是 一个User对象,此处#{}要写User对象中的属性名称。 原则上应该是#{User.username} 但上面指定了实体类名称所以只要属性名就行。

这个是增删改操作 别忘了提交事务。

例3:

<insert id="saveUser" parameterType="USER">
 <!-- 配置保存时获取插入的id -->
  <selectKey keyColumn="id" keyProperty="id" resultType="int"> 
  select last_insert_id();
   </selectKey>
    insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
 </insert>

注解

@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);

这个目前没怎么懂,获取插入数据的id值

例4:
模糊查询
法一 :#{username}, “%王%”,加百分号。(一般使用)
法二: ‘%${value}%’ “王”
区别:
#{}表示一个占位符号 通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。 表 示 拼 接 s q l 串 通 过 {}表示拼接sql串 通过 sql{}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, 可 以 接 收 简 单 类 型 值 或 p o j o 属 性 值 , 如 果 p a r a m e t e r T y p e 传 输 单 个 简 单 类 型 值 , {}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值, pojoparameterType{}括号中只能是value。

例5:
输入参数是QueryVo类,选择条件是QueryVo类中的属性User的属性 要写user.username.liqi

<select id="findByVo" resultType="com.itheima.domain.User" parameterType="com.itheima.domain.QueryVo"> select * from user where username like #{user.username}; </select>

例6
输出结果的封装:
如果数据库的字段和类中的属性一样(不区分大小写),就会自动封装。
如果不一样:两种方法

1.使用别名查询  数据库的字段 as 类属性名称
<!-- 配置查询所有操作 -->
 <select id="findAll" resultType="com.itheima.domain.User"> 
 select id as userId,username as userName,birthday as userBirthday, sex as userSex,address as userAddress from user
  </select>
2.resultMap
<resultMap type="com.itheima.domain.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>

id标签:用于指定主键字段
result标签:用于指定非主键字段
column属性:用于指定数据库列名
property属性:用于指定实体类属性名称
使用时 返回
resultType=“com.itheima.domain.User” 改为 resultMap=“userMap”

<select id="findAll" resultMap="userMap"> select * from user </select>

注解

@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") 
 }) 	
List<User> findAll();

@Select("select * from user where id = #{uid} ")
 @ResultMap("userMap") 
 User findById(Integer userId);

id 是否是主键字段
column 数据库的列名
property需要装配的属性名
one 需要使用的@One注解(@Result(one=@One)())) 代替association
使用格式: @Result(column=" “,property=”",one=@One(select=""))
many 需要使用的@Many注解(@Result(many=@many)())) 代替collection
使用格式: @Result(property="",column="",many=@Many(select=""))

例7

动态查询

test 和 sql语句#{username} 中的应该是属性名
sql其他的是数据库字段名

<!-- 抽取重复的语句代码片段 --> 
<sql id="defaultSql">
 select * from user
  </sql>

需求:实现 select * from user where username like #{username} and and address like #{address}:
如果存在#{username} 或者 #{address}的话

<select id="findByUser" resultType="user" parameterType="user"> 
<include refid="defaultSql"></include> 
<where> 
	<if test="username!=null and username != '' "> 
		and username like #{username} 
	</if> 
	<if test="address != null"> 
		and address like #{address}
	 </if>
  </where> 
</select>

需求:传入多个id查询用户信息,用下边两个sql实现:
SELECT * FROM USERS WHERE username LIKE ‘%张%’ AND (id =10 OR id =89 OR id=16) SELECT * FROM USERS WHERE username LIKE ‘%张%’ AND id IN (10,89,16)

<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"> 
		    	<!--这个id 应该是字段名 -->
			    <foreach collection="ids" open="id in ( " close=")" item="uid" separator=","> 
			    #{uid}
			     </foreach> 
		    </if> 
	    </where> 
 </select>

例8
association 和 collection

一个account类中 有一个类属性 user 将其封装成 resultMap (account 这边没写全限定类名,在sqlmapconfig 配置过了)

<resultMap type="account" id="accountMap">
	 <id column="aid" property="id"/>
  	<result column="uid" property="uid"/>
    <result column="money" property="money"/>
    <!-- 它是用于指定从表方的引用实体属性的 association 一对一-->
     <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>

注解

@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="com.itheima.dao.IUserDao.findById", fetchType=FetchType.EAGER) ) 
    })

fetchType=FetchType.EAGER 立即查找 把这个该成LAZY就是延迟,一般一对一是立即加载

即user 类中有类列表属性 List

<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>

注解

@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="com.itheima.dao.IAccountDao.findByUid", fetchType=FetchType.LAZY) )
    })

一般多对多是LAZY 延迟加载

Mybatis事务提交方式

手动提交
session.commit();
自动提交
session = factory.openSession(true);

Mybatis 延迟加载策略

延迟加载: 就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载. 好处:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。

坏处: 因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时间,所以可能造成用户等待时间变长,造成用户体验下降

一对多,多对多 延时加载
一对一,多对一 立即加载

1.在SqlMapConfig中配置延迟加载

<settings> 
<setting name="lazyLoadingEnabled" value="true"/> 
<setting name="aggressiveLazyLoading" value="false"/> 
</settings>

需求 :查询账户信息同时查询用户信息。

association(一般立即加载)

<mapper namespace="com.itheima.dao.IAccountDao">
<resultMap type="account" id="accountMap">
 <id column="aid" property="id"/> 
 <result column="uid" property="uid"/> 
 <result column="money" property="money"/>
  <!-- 它是用于指定从表方的引用实体属性的 select 指定内容查询用户的唯一标志 column 用户根据id查询时 所需要的参数的值
 或者 select: 填写我们要调用的 select 映射的 id column : 填写我们要传递给 select 映射的参数 -->
   <association property="user" javaType="user" select="com.itheima.dao.IUserDao.findById" 
   column="uid"> 
   </association>
    </resultMap>
    
<select id="findAll" resultMap="accountMap"> 
	select * from account 
</select>
</mapper>
<mapper namespace="com.itheima.dao.IUserDao">
 <!-- 根据id查询 --> 
 <select id="findById" resultType="user" parameterType="int" > 
 select * from user where id = #{uid} 
 </select> 
 </mapper>
List<Account> accounts = accountDao.findAll(); //只会查询accounts 延迟查询

//加了下面几句才会用到了user 出现user 查询下面的
for(Account account :accounts)
{
	account.getUser();
}

注解 :

@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="com.itheima.dao.IUserDao.findById", fetchType=FetchType.LAZY) ) 
    })

collection (一般延迟)

<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用于指定集合元素的数据类型 select是用于指定查询账户的唯一标识(账户的dao全限定类名加上方法名称) column是用于指定使用哪个字段的值作为条件查询 --> 
  <collection property="accounts" ofType="account" select="com.itheima.dao.IAccountDao.findByUid" column="id"> 
  </collection> 
  </resultMap> 
  <!-- 配置查询所有操作 --> 
  <select id="findAll" resultMap="userMap"> select * from user </select>
<select id="findByUid" resultType="account" parameterType="int"> 
select * from account where uid = #{uid} 
</select>

注解

@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="com.itheima.dao.IAccountDao.findByUid", fetchType=FetchType.LAZY ) )
    })

Mybatis缓存

一级缓存

一级缓存是SqlSession范围的缓存,当调用SqlSession的修改,添加,删除,commit(),close()等。方法时,就会清空一级缓存。

<select id="findById" resultType="UsEr" parameterType="int" useCache="true">

连续两次查询同一个东西 且不调用SqlSession的修改,添加,删除,commit(),close()等,只会提交一句sql语句。第二次直接

在这里插入图片描述

二级缓存

二级缓存是mapper映射级别的缓存,多个SqlSession去操作同一个Mapper映射的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

开启二级缓存(默认开启)
在这里插入图片描述
1.在SqlMapConfig中配置 (默认配置好的)

<settings>
 <!-- 开启二级缓存的支持 --> 
 <setting name="cacheEnabled" value="true"/> 
 </settings>

2.配置Mapper映射

<cache>标签表示当前这个mapper映射将使用二级缓存,区分的标准就看mapper的namespace值。


 <?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.itheima.dao.IUserDao"> <!-- 开启二级缓存的支持 --> 
  <cache></cache> 
  </mapper>
<!-- 根据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,禁用二级缓存。

测试`

SqlSession sqlSession1 = factory.openSession();
 IUserDao dao1 = sqlSession1.getMapper(IUserDao.class);
  User user1 = dao1.findById(41); 
  System.out.println(user1); 
  
  sqlSession1.close();//一级缓存消失 

  SqlSession sqlSession2 = factory.openSession(); 
  IUserDao dao2 = sqlSession2.getMapper(IUserDao.class);
   User user2 = dao2.findById(41); 
   System.out.println(user2); sqlSession2.close(); 
   System.out.println(user1 == user2);

注解
1.配置

<settings>
 <!-- 开启二级缓存的支持 --> 
 <setting name="cacheEnabled" value="true"/> 
 </settings>

2 在持久层接口中使用注解配置二级缓存
@CacheNamespace(blocking=true)//mybatis基于注解方式实现配置二级缓存 public interface IUserDao {}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值