文章目录
MyBatis
轻量级的持久层的开源框架,对JDBC进行了完美的封装,是一个不完全的ORM映射框架
1. 基本内容
-
MyBatis 简介
-
轻量级:不依赖于应用服务器(Tomcat),可以单独运行或执行的框架
-
持久层(数据访问层):实现对数据的操作,类似于Dao层
-
ORM:对象关系映射(O:对象; R:关系数据库中的表; M:映射<一一对应的关系>)
-
不完全的映射:只能实现输入参数和输出结果的映射,不能实现sql的自动映射
-
-
MyBatis 作用
MyBatis 就是对数据库中的数据进行操作的一个框架,充当了项目中的数据访问层的角色
-
MyBatis的执行流程
2. MyBatis 用法
-
基本步骤
-
创建一个java项目,导入mybatis的相关jar包,数据库驱动包
-
创建一个和src同目录的资源文件夹(config)
在config文件夹下创建一个全局配置文件 SqlMapConfig.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> <!-- 临时采用jdbc提供的数据源连接池--> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理--> <transactionManager type="JDBC" /> <!-- 数据库连接池--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/girls?characterEncoding=utf-8" /> <property name="username" value="root" /> <property name="password" value="uesrroot" /> </dataSource> </environment> </environments> <!-- 加载mapper映射文件到全局配置文件 mappers:可以加载多个mapper文件 mapper:具体哪一个mapper文件 resource:指定mapper文件的针对全局文件的相对路径 --> <mappers> <mapper resource="AdminMapper.xml"/> </mappers> </configuration>
-
在config下创建一个mybatis配置文件
实现对sql语句的管理以及sql语句中查询语句和查询结果的映射关系配置
标签总结:
- mapper标签:是映射文件的根标签,一个映射文件只能有一个mapper标签,有开始标签和结束标签
- namesapace:命名空间,主要是对sql语句进行隔离,方便管理。但是如果使用mapper动态代理开发,namespace就有特殊的含义了,是xml的全路径名
- select:用于查询的标签
- id:当前sql语句的唯一标识,相当于给sql语句起名字
- resultType:sql语句查询出单条结果要映射的对象类型,类型必须是全路径名,包名+类名;在xml文件中设置别名之后,可以用首字母小写的别名
- " #{} ”:相当于jdbc中的?,{}中传递的参数就是sql条件对应的参数名
- " ${} ”:进行值的拼接,如果传递的值是基本值类型,那么{}中必须是value,相当于把条件直接拼接到sql语句中,容易引起sql注入的问题
- keyProperty:查询到的自增主键映射到输入参数对象的哪个属性上
- order:执行新增语句之后,再去执行当前查询自增主键的函数
- resultType:当前查询自增id返回的类型
<?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"> <!-- mybatis配置文件,实现对sql语句的管理以及sql语句中查询语句和查询结果的映射关系配置 mapper标签:是映射文件的根标签,一个映射文件只能有一个mapper标签,有开始标签和结束标签 namesapace:命名空间,主要是对sql语句进行隔离,方便管理,但是如果使用mapper动态代理开发, namespace就有特殊的含义了,是xml的全路径名 --> <mapper namespace="test"> ... </mapper>
-
查询所有的用户信息
<!-- 查询所有用户信息 --> <!-- 配置 查询所有用户信息的 配置文件 select:用于查询的标签 id:当前sql语句的唯一标识,相当于给sql语句起名字 resultType:sql语句查询出单条结果要映射的对象类型,类型必须是全路径名,包名+类名 --> <select id="findadminlist" resultType="com.pojo.Admin"> select * from admin </select>
-
根据id 查询
<!-- 根据id查询 parameterType:sql传递的条件的值映射的数据类型,输入映射的类型 resultType:sql语句查询出单条结果要映射的对象类型,类型必须是全路径名,包名+类名,输出结果映射的类型 #{}:相当于jdbc中的?,{}中传递的参数就是sql条件对应的参数名 --> <select id="findadminbyid" parameterType="int" resultType="com.pojo.Admin"> select * from admin where id = #{id} </select>
-
根据名字模糊查询
<!-- 根据名字模糊查询 ${}:进行值的拼接,如果传递的值是基本值类型,那么{}中必须是value sql条件基本类型参数传递#{}和${} #{}:相当于?,大括号中参数任意 ${}:相当于把条件直接拼接到sql语句中,容易引起sql注入的问题,{}中参数必须是value --> <select id="findadminbyname" parameterType="String" resultType="com.pojo.Admin"> select * from where username like #{name} select * from where username like '%${value}%' </select>
-
根据id删除
<!-- 根据id删除 增删改不需要指定结果类型映射(resultType) --> <delete id="deleteadminbyid" parameterType="java.lang.Integer"> delete from admin where id = #{id} </delete>
-
新增
<!-- 新增 --> <insert id="inseradmin" parameterType="com.pojo.Admin"> <!-- 通过mysql的一个函数,得到自增主键的值 keyProperty:查询到的自增主键映射到输入参数对象的哪个属性上 order:执行新增语句之后,再去执行当前查询自增主键的函数 resultType:当前查询自增id返回的类型 --> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> select LAST_INSERT_ID() </selectKey> <!-- 通过mysql的UUID函数,自行维护主键 使用UUID维护主键注意事项: 1.主键在数据库中的类型是varchar类型,并且长度大于32 2.通过selectKey标签指定,获取UUID的函数 --> <!-- <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String"> select UUID() </selectKey> --> <!-- 获取oracle序列,实现主键的获取 <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.Integer"> select 序列名.nexval() </selectKey> --> insert into admin values(#{id},#{username},#{password}) </insert>
通过mysql的UUID函数,自行维护主键
使用UUID维护主键注意事项:
- 主键在数据库中的类型是varchar类型,并且长度大于32
- 通过selectKey标签指定,获取UUID的函数
-
根据id修改
<!-- 根据id修改 --> <update id="updateadmin" parameterType="com.pojo.Admin"> update admin set username=#{username},password=#{password} where id=#{id} </update>
-
总结
1.<select id="" parameterType="" resultType=""> select * from where username like #{name} select * from where username like '%${value}%' </select> select:用于查询的标签 id:当前sql语句的唯一标识,相当于给sql语句起名字 parameterType:sql传递的条件的值映射的数据类型,输入映射的类型 resultType:sql语句查询出单条结果要映射的对象类型,类型必须是全路径名,包名+类名,输出结果映 射的类型 #{}:相当于jdbc中的?,{}中传递的参数就是sql条件对应的参数名,大括号中参数任意 ${}:相当于把条件直接拼接到sql语句中,容易引起sql注入的问题,{}中参数必须是value 2.增删改不需要指定结果类型映射(resultType) 3.新增 - 通过mysql的一个函数,得到自增主键的值 keyProperty:查询到的自增主键映射到输入参数对象的哪个属性上 order:执行新增语句之后,再去执行当前查询自增主键的函数 resultType:当前查询自增id返回的类型 <insert id="inseradmin" parameterType="com.pojo.Admin"> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> select LAST_INSERT_ID() </selectKey> insert into admin values(#{id},#{username},#{password}) </insert> - 通过mysql的UUID函数,自行维护主键 使用UUID维护主键注意事项: 1.主键在数据库中的类型是varchar类型,并且长度大于32 2.通过selectKey标签指定,获取UUID的函数 <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String"> select UUID() </selectKey> ... - 获取oracle序列,实现主键的获取 <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.Integer"> select 序列名.nexval() </selectKey> ...
-
创建一个测试类
package com.test; import java.io.IOException; import java.io.InputStream; import java.util.List; 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.apache.log4j.lf5.util.Resource; import org.junit.Test; import com.pojo.Admin; public class AdminTest { // 查询所有用户的信息 // 通过添加单元测试注解的方法来进行单元测试 @Test public void findadminbyid() throws IOException { // 1.通过mubatisResources对象的getResourceAsStream("全局配置文件")方法来加载mybatis全局配置文件,创建一个流对象 InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); // 2.创建一个SqlSessionFactory对象,需要传递一个加载了全局配置文件的流对象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 3.通过SqlSessionFactory工厂对象,创建SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); // 4.通过sqlSession对象,实现增删改查的操作 List<Admin> admininfo = sqlSession.selectList("findadminbyid"); // 5.打印结果 System.out.println(admininfo); // 6.关闭资源 sqlSession.close(); } @Test public void findadminbyid() throws IOException { InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); Admin admin = sqlSession.selectOne("test.findadminbyid", 6); System.out.println(admin); sqlSession.close(); } @Test public void findadminbyname() throws IOException { InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); List<Admin> admins = sqlSession.selectList("test.findadminbyname"); System.out.println(admins); sqlSession.close(); } @Test public void deleteadminbyid() throws IOException { InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); int row = sqlSession.delete("test.deleteadminbyid"); System.out.println(row); //调用jdbc提供的事务,实现提交操作,使程序中的数据和数据库中的数据保持一致性 sqlSession.commit(); sqlSession.close(); } @Test public void inseradmin() throws IOException { InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); Admin admin = new Admin(); admin.setPassword("9372"); admin.setUsername("小李子"); int row = sqlSession.insert("test.inseradmin", admin); System.out.println(row); //调用jdbc提供的事务,实现提交操作,使程序中的数据和数据库中的数据保持一致性 sqlSession.commit(); //查看自增主键的值,意义在于涉及到级联新增(新增部门级联新增一个部门的员工)时, //System.out.println(admin.getId()); 直接通过查看对象的id值,是获取不到自增主键的 sqlSession.close(); } @Test public void updateadmin() throws IOException { InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); Admin admin = new Admin(); admin.setId(12); admin.setPassword("9372"); admin.setUsername("小李子"); int row = sqlSession.update("test.updateadmin", admin); System.out.println(row); //调用jdbc提供的事务,实现提交操作,使程序中的数据和数据库中的数据保持一致性 sqlSession.commit(); sqlSession.close(); } }
-
3. 改进
Dao
层DaoImpl
实现类
4. 代理开发
1)Mapper代理的开发模式
-
mapper代理开发 程序员只需要关注接口开发 不需要对实现类进行关注 由mybaits为我们完成具体的数据实现
-
mapper代理开发需要遵循的开发规范
- mapper.java接口文件和mapper.xml映射文件同名且在同一包下(UserMapper.java和UserMapper.xml)
- 映射文件中的namespace命名空间的值必须是接口文件的全路径名
- 接口文件中的方法名必须和映射文件中管理的sql的ID名一致
- 接口文件中方法的输入参数的类型必须和映射文件中parameterType指定的类型一致
- 接口文件中方法的返回值类型参考映射文件中resultType指定的类型
-
UserMapper.java
package com.mapper; import java.util.List; import com.pojo.User; public interface UserMapper { //根据id查询 public User finduserbyid (int id); //根据姓名模糊查询 public List<User> finduserbyname (String username); //新增 public boolean insertuser (User user); }
-
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="com.mapper.UserMapper"> <!-- 根据id查询 --> <select id="finduserbyid" parameterType="int" resultType="user"> select * from user where id = #{id} </select> <!-- 根据名字查询 --> <select id="finduserbyname" parameterType="String" resultType="user"> select * from user where username like '%${value}%' </select> <!-- 新增 --> <insert id="insertuser" parameterType="user"> insert into user (username,password) values (#{username},#{password}) </insert> <!-- 修改 --> <update id="updateuser" parameterType="user"> update user </update> </mapper>
-
再建一个test类
package com.test; import java.io.IOException; import java.util.List; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import com.mapper.UserMapper; import com.pojo.User; import com.until.SqlSessionFactorySingleton; public class UserMapperTest { //根据id查询 @Test public void usermappertest() throws IOException{ //1.得到sqlsession对象 SqlSession sqlsession = SqlSessionFactorySingleton.getinstance().openSession(); //2.通过sqlsession对象获取mapper接口 UserMapper usermapper = sqlsession.getMapper(UserMapper.class); //3.调用接口中对数据库进行操作的方法 User user = usermapper.finduserbyid(2); System.out.println(user); } //姓名模糊查询 @Test public void usermappertest2() throws IOException{ //1.得到sqlsession对象 SqlSession sqlsession = SqlSessionFactorySingleton.getinstance().openSession(); //2.通过sqlsession对象获取mapper接口 UserMapper usermapper = sqlsession.getMapper(UserMapper.class); //3.调用接口中对数据库进行操作的方法 List<User> list = usermapper.finduserbyname("N"); System.out.println(list); } //新增 @Test public void usermappertest3() throws IOException{ //1.得到sqlsession对象 SqlSession sqlsession = SqlSessionFactorySingleton.getinstance().openSession(); //2.通过sqlsession对象获取mapper接口 UserMapper usermapper = sqlsession.getMapper(UserMapper.class); //3.调用接口中对数据库进行操作的方法 User user = new User(); user.setUsername("Pass"); user.setPassword("1234"); boolean flag = usermapper.insertuser(user); sqlsession.commit(); if(flag) { System.out.println("新增成功"); }else { System.out.println("失败"); } } }
2)ResultType 和 ResultMap
-
ResultType
作为输出结果映射类型
sql查询的字段名必须和映射对象的属性名完全一致,这样才能够实现数据的绑定
一般在单表查询时使用
-
ResultMap
(高级映射)针对别名映射
多表连接查询时,指定映射类型
可以手动绑定查询的字段和映射的结果
-
查询的字段手动绑定到映射结果对象类型的步骤:
-
首先定义一个
<ResultMap>
标签,指定映射结果的对象类型 -
把查询的字段手动绑定到映射结果对象类型的属性上
-
<resultMap type="" id=""> <id colum="数据库中查出的字段名" property="映射对象的属性名"/> -- 实现主键的映射 <result colum="" property=""/> -- 实现其他普通字段的映射 </resultMap> type:当前映射的结果对象类型,你查出的结果要映射到哪个对象类型上 id:当前resultMap的唯一标识
-
3)动态sql
为了完成对sql语句的一个灵活组装和拼接,实现sql语句根据不同条件查询不同结果的操作。(想查什么就查什么)
主要实现sql条件的一个动态拼接和封装
-
where
标签:包含多个条件,会自动去除第一个条件的and -
mapper.xml
<!-- 动态sql实现sql条件的一个动态拼接, 提供where动态标签,可以自动包含多个条件,where标签会自动删除第一个条件的and,所以最好加上and --> <select id="querybydynamic" parameterType="user" resultType="user"> select * from user <where> <if test="username != null and username != ''"> and username like '%${username}%' </if> <if test="password != null and password != ''"> and password = #{password} </if> </where> </select>
-
sql片段
重复的动态条件代码抽离出来,形成一个动态的sql片段
<select id="" parameterType="" resultType=""> select count(*) from user <where> <include refid="dynamicquery"></include> </where> </select>
5. 多表级联查询
1)分析表结构
2)多表查询建立扩展类,包含所有查询的属性
-
建立一个拓展类,包含两个实体类的所有属性
-
查询语句尽量不写
select * from …
,写具体的查询的字段名:select orders.id,user_id,number,createtime,note,name,phone,address from orders,user_order where orders.user_id = user_order.id
<select id="findorderanduser" resultType=" ">
select orders.id,user_id,number,createtime,note,name,phone,address
from orders,user_order
where orders.user_id = user_order.id
</select>
3)多表级联查询,包装类
-
一对一
- column:数据库查出的字段名
- property:实体类里的对象的属性名,映射到对象的属性名
- association:把连接查询的用户信息映射到单个用户对象上,一一映射
- javaType:映射到对象的类型
- Mapper.xml
<!-- 查询订单级联查询用户的resultMap 一对一 --> <resultMap type="com.pojo.Orders" id="orderanduserresultmap"> <!-- column:数据库查出的字段名,property:实体类里的对象的属性名 --> <id column="id" property="orders_id"/> <result column="user_id" property="user_id"/> <result column="number" property="number"/> <result column="createtime" property="createtime"/> <result column="note" property="note"/> <!-- 把连接查询的用户信息映射到单个的用户对象上,一一映射 --> <association property="user" javaType="com.pojo.User"> <result column="phone" property="phone"/> <result column="address" property="address"/> <result column="name" property="name"/> </association> </resultMap> <!-- 查询订单,关联查询订单所属的信息 --> <select id="findorderanduser" resultMap="orderanduserresultmap"> select orders.id,user_id,number,createtime,note,name,phone,address from orders,user_order where orders.user_id = user_order.id </select>
-
包装类
public class Orders { private int orders_id; private int user_id; private String number; private Date createtime; private String note; //包装类 private User user;
-
测试类
//多表查询,查询订单以及所属的信息
@Test
public void orderstest1() throws IOException{
//1.得到sqlsession对象
SqlSession sqlsession = SqlSessionFactorySingleton.getinstance().openSession();
//2.通过sqlsession对象获取mapper接口
OrdersMapper ordermapper = sqlsession.getMapper(OrdersMapper.class);
//3.调用接口中对数据库进行操作的方法
List list = ordermapper.findorderanduser();
System.out.println(list);
sqlsession.close();
} -
一对多
-
需求:查询用户级联查询用户订单信息
-
collection:把查询的订单信息,映射到包装类中的集合属性上
-
ofType:指定集合属性的映射类型
-
Mapper.xml
<!-- 查询用户级联查询用户的订单信息 一对多 --> <resultMap type="com.pojo.User" id="userandorderresultmap"> <id column="id" property="user_id"/> <result column="phone" property="phone"/> <result column="address" property="address"/> <result column="name" property="name"/> <collection property="orders" ofType="com.pojo.Orders"> <id column="orders.id" property="orders_id"/> <result column="user_id" property="user_id"/> <result column="number" property="number"/> <result column="createtime" property="createtime"/> <result column="note" property="note"/> </collection> </resultMap>
-
测试类
//查询用户级联查询用户的订单信息 @Test public void orderstest2() throws IOException{ //1.得到sqlsession对象 SqlSession sqlsession = SqlSessionFactorySingleton.getinstance().openSession(); //2.通过sqlsession对象获取mapper接口 OrdersMapper ordermapper = sqlsession.getMapper(OrdersMapper.class); //3.调用接口中对数据库进行操作的方法 List<User> list = ordermapper.finduserandorders(); System.out.println(list); sqlsession.close(); }
-
-
多对多
-
需求:查询用户,关联查询用户所下的订单,以及订单明细,和商品信息
-
注意事项:
-
没有关系的两张表不能使用包装类
-
用户表 — 订单表,一对多
订单表 — 订单明细表,一对多
订单明细 — 商品,一对一
-
用户表里可以建立订单类,一对多,list
订单表里建立订单明细,一对多,list
订单明细表里建立商品明细,一对一,items
-
resultMap
注意约束文件中规定的 association,collection的顺序<mapper namespace="com.mapper.UserMapper"> <!--四表联查--> <resultMap id="userandordersandorderdetailanditemsresultMap" type="com.pojo.User"> <id column="user_id" property="user_id"></id> <result column="user_name" property="name"></result> <result column="phone" property="phone"></result> <result column="address" property="address"></result> <!-- 用户表里的订单,一对多,collection --> <collection property="orders" ofType="com.pojo.Orders"> <id column="orders_id" property="orders_id"></id> <result column="number" property="number"></result> <result column="orders_createtime" property="createtime"></result> <result column="note" property="note"></result> <!-- 订单表里的订单明细,一对多,collection --> <collection property="orderdetails" ofType="com.pojo.orderdetail"> <id column="items_id" property="items_id"></id> <result column="items_num" property="items_num"></result> <!-- 订单明细里的商品,一对一,association --> <association property="items" javaType="com.pojo.items"> <result column="items_name" property="name"></result> <result column="price" property="price"></result> <result column="detail" property="detail"></result> <result column="items_createtime" property="createtime"></result> </association> </collection> </collection> <!--查询用户,级联查询用户的订单,订单明细,商品信息,四表联查,多对多--> <select id="finduserbymany" resultMap="userandordersandorderdetailanditemsresultMap"> SELECT user_order.id user_id, user_order.`name` user_name, phone, address, orders.id orders_id, orders.number, orders.createtime orders_createtime, orders.note, orderdetail.items_id, orderdetail.items_num, items.`name` items_name, items.price, items.detail, items.createtime items_createtime FROM user_order, orders, orderdetail, items WHERE user_order.id = orders.user_id AND orders.id = orderdetail.orders_id AND orderdetail.items_id = items.id </select> </mapper>
-
-
4)关联查询mybatis思路
6. 懒加载
在多表连接查询时先查询一张表的信息,如果用到了关联表的信息时,这个时候再去查询关联表
当前这样的实现方式可以提高查询效率
-
需求:查询订单关联查询用户信息实现延迟加载
实现步骤:
-
先创建查询订单的sql语句(查订单单表)
<!-- 懒加载 --> <select id="findorderbylazy" resultMap="findorderbylazy"> select * from orders </select>
-
再创建根据订单表中的用户id查询订单关联的用户信息的sql
<select id="finduserbylazy" resultType="com.pojo.User" parameterType="int"> select user_order.id user_id, user_order.`name`, phone, address from user_order where id = #{id} </select>
-
给查询订单的sql标签中创建resultmap结果映射通过association或者collection标签设置延迟加载
<resultMap type="orders" id="findorderbylazy"> <id column="id" property="orders_id"/> <result column="user_id" property="user_id"/> <result column="number" property="number"/> <result column="createtime" property="createtime"/> <result column="note" property="note"/> <!-- select:指定延迟加载需要加载的sql语句 column:根据外键进行两表关联查询 --> <association property="user" javaType="com.pojo.User" select="finduserbylazy" column="user_id"></association> </resultMap>
-
在mybatis全局配置文件中通过setting标签设置开启延迟加载的命令
<!-- 懒加载 --> <settings> < !-- 开启延迟加载的配置 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 设置加载方式为懒加载 --> <setting name="aggressiveLazyLoading" value="false"/> </settings>
-
7. 缓存
1)一级缓存
-
where 数据库中的字段名 = #{实体类中的属性名} ,必须对应起来
-
查询的数据库的结果的字段名必须和实体类中的属性名相对应
-
UserMapper.xml
<!-- 缓存测试 --> <!-- where 数据库中的字段名 = #{实体类中的属性名} ,必须对应起来 查询的数据库的结果的字段名必须和实体类中的属性名相对应 --> <select id="finduserbyid" parameterType="int" resultType="user"> select user_order.id user_id,user_order.name,user_order.phone,user_order.address from user_order where id = #{user_id} </select> <!-- 缓存测试,更改 --> <update id="updateuser" parameterType="user"> update user_order set name=#{name},phone=#{phone},address=#{address} where id=#{user_id} </update>
-
UserMapperTest.java
//一级缓存测试 @Test public void usertest3() throws IOException { SqlSession sqlSession = SqlSessionFactorySingleton.getinstance().openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //第一次查询 User user = userMapper.finduserbyid(2); System.out.println(user); //第一次查询之后更改 user.setName("Pack"); userMapper.updateuser(user); sqlSession.commit();; //第二次查询 User user2 = userMapper.finduserbyid(2); System.out.println(user2); sqlSession.close(); }
2)二级缓存
-
mapper的缓存
-
SqlMapConfig.xml
<!-- 懒加载 --> <settings> <!-- 开启延迟加载的配置 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 设置加载方式为懒加载 --> <setting name="aggressiveLazyLoading" value="false"/> <!-- 二级缓存开启 --> <setting name="cacheEnabled" value="true"/> </settings>
-
UserMapper.xml
<!-- 二级缓存的开启 --> <cache></cache>
-
pojo实现序列化接口
public class User implements Serializable{ private int user_id; private String name; private String phone; private String address;
-
UserMapperTest.java
//二级缓存的测试 //(mapper缓存) @Test public void usertest4() throws IOException { SqlSession sqlSession1 = SqlSessionFactorySingleton.getinstance().openSession(); SqlSession sqlSession2 = SqlSessionFactorySingleton.getinstance().openSession(); SqlSession sqlSession3 = SqlSessionFactorySingleton.getinstance().openSession(); SqlSession sqlSession4 = SqlSessionFactorySingleton.getinstance().openSession(); UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class); UserMapper userMapper2 = sqlSession1.getMapper(UserMapper.class); UserMapper userMapper3 = sqlSession1.getMapper(UserMapper.class); UserMapper userMapper4 = sqlSession1.getMapper(UserMapper.class); //第一次查询 User user = userMapper1.finduserbyid(2); System.out.println(user); sqlSession1.close(); //第一次查询之后更改 user.setName("Pack"); userMapper2.updateuser(user); sqlSession3.commit();; //第二次查询 User user2 = userMapper2.finduserbyid(2); System.out.println(user2); //sqlSession2.close(); }