赞
踩
目的:提高查询效率,降低数据库查询压力,提升系统整体性能。
一级缓存:默认开启,Session级别,同一个会话内生效。
命中缓存的情况:statementid、SQL语句、结果集的范围、传递的参数相同。
同一个查询之前执行DML操作,清空缓存,session.clearCache()也会清空缓存。
二级缓存:需要配置,SQLSessionFactory级别,不同会话之间可以共享。
使用步骤:1、全局配置mybatis_config.xml文件中
<settting name="cacheEnabled" value="true" />
2、mapper.xml配置要使用二级缓存的查询
<cache />
3、使用查询返回的对象的类必须实现序列化接口。
MemCached、OSCache、EHCache。
<association>标签是处理单一的关联对象(处理单一属性的关联关系)。
property :指定关联对象的属性
javaType :关联对象的类型(可以省略)
select :执行一个新的查询
column:在新的查询中用哪个列的值作为查询条件
2.1 RolesMapper.java
提供一个根据用户主键userid去查询用户角色的方法,如下:
- public interface RolesMapper {
- /**
- * 根据用户id查询此用户对应的角色信息
- * @param id
- * @return
- */
- Roles findRolesByUserId(int id);
- }
2.2 RolesMapper.xml配置
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE mapper
- PUBLIC "-//mybatis.org//DTDMapper3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- <mapper namespace="com.dyh.dao.RolesMapper">
- <!--<resultMap id="rolesMap" type="com.dyh.pojo.Roles">
- <id property="roleid" column="roleid" />
- <result property="roleName" column="rolename" />
- </resultMap>-->
- <!--<select id="findRolesByUserId" resultMap="rolesMap" parameterType="int">-->
- <select id="findRolesByUserId" resultType="roles" parameterType="int">
- select roleid,rolename from roles where user_id=#{userid}
- </select>
- </mapper>
2.3 JUnit单元测试RolesMapperTest
- package com.dyh.test;
-
- import com.dyh.dao.RolesMapper;
- import com.dyh.pojo.Roles;
- import com.dyh.util.MybatisUtil;
- import org.apache.ibatis.session.SqlSession;
- import org.junit.After;
- import org.junit.Before;
- import org.junit.Test;
-
- import static org.junit.Assert.*;
-
- public class RolesMapperTest {
- SqlSession session;
- RolesMapper mapper;
-
- @Before
- public void setUp() throws Exception {
- session = MybatisUtil.getConnection();
- mapper = session.getMapper(RolesMapper.class);
- }
-
- @Test
- public void testFindRolesByUserId(){
- Roles roles = mapper.findRolesByUserId(1);
- System.out.println(roles);
- }
-
- @After
- public void tearDown() throws Exception {
- MybatisUtil.closeConnection();
- }
- }
2.4 UserMapper.java
增加如下方法:
- public interface UsersMapper {
- List<Users> queryUsersAndRoles();
- // 增加如下方法
- List<Users> queryUsersAndRolesBySelect();
- }
2.5 UserMapper.xml
增加如下内容:
- <resultMap id="usersAndRolesMap2" type="users">
- <id property="userid" column="userid" />
- <result property="username" column="username" />
- <result property="usersex" column="usersex" />
- <!-- 配置一对一的关联关系 -->
- <!-- column="userid" 是users表中的主键,使用这个值取查询roles表 -->
- <association property="roles" javaType="roles"
- select="com.dyh.dao.RolesMapper.findRolesByUserId" column="userid">
- <id property="roleid" column="roleid" />
- <result property="roleName" column="rolename" />
- </association>
- </resultMap>
-
- <sql id="deptColumns">
- deptno,dname,loc as city
- </sql>
-
- <select id="queryUsersAndRolesBySelect" resultMap="usersAndRolesMap2">
- SELECT u.userid,u.username,u.usersex
- FROM users u
- </select>
2.6 JUnit单元测试UsersMapperTest.java
- @Test
- public void testQueryUsersAndRoles2(){
- List<Users> list = mapper.queryUsersAndRolesBySelect();
- list.forEach(System.out::println);
- }
2.7 延迟加载与立即加载
在association一对一关联标签和collection一对多关联标签中有个属性fetchType="lazy",属性值有lazy懒加载(延迟加载)、eager立即加载。如果不配置fetchType属性值,fetchType默认值是eager立即加载。
2.7.1 懒加载(延迟加载)lazy
测试类UsersMapperTest.java中修改代码如下:注意,不能直接打印users对象,因为其toString方法中获取了roles的属性值。
- @Test
- public void testQueryUsersAndRoles2(){
- List<Users> list = mapper.queryUsersAndRolesBySelect();
- //list.forEach(System.out::println);
- for (Users users:list) {
- System.out.println(users.getUsername());
- // 懒加载没有获取角色信息的时候,不会去查询角色表
- //System.out.println(users.getRoles());
- }
- }
UserMapper.xml配置修改如下:
应用场景:完成用户与订单查询。 要求一个用户可以对应多个订单。
<collection>标签是处理所关联对象是多个的(处理关联属性是集合时的关联关系)。
property :指定关联对象的属性
javaType :关联对象的类型(可省略。默认List 类型,如果集合是 Set 类型时需要配置并给定 Set 的全名 )
ofType:指定集合里存放的对象类型
select :执行一个新的查询
column:在新的查询中用哪个列的值作为查询条件
- -- users表使用上次课建立好的表和数据
- CREATE TABLE `orders`(
- `orderid` INT(11) NOT NULL AUTO_INCREMENT,
- `orderprice` DOUBLE DEFAULT NULL,
- `user_id` INT(11) DEFAULT NULL,
- PRIMARY KEY(`orderid`),
- KEY `orders_fk`(`user_id`),
- CONSTRAINT `orders_fk` FOREIGN KEY(`user_id`) REFERENCES `users`(`userid`) ) ENGINE=INNODB DEFAULT CHARSET=utf8;
-
- INSERT INTO orders VALUES(DEFAULT, 80, 1),
- (DEFAULT, 90, 1),
- (DEFAULT, 100, 1),
- (DEFAULT, 92, 2),
- (DEFAULT, 102, 2);
- SELECT * FROM orders;
-
- -- 一对多查询,查询用户及其对应的订单信息
- SELECT u.userid,u.username,u.usersex,
- o.orderid,o.orderprice
- FROM users u,orders o
- WHERE u.userid=o.user_id
- public class Orders {
- private Integer orderid;
- private Double orderprice;
- // get、set、toString、constructor方法自行补充
- }
一对多,说明一个users对象可以有多个订单,所以要在Users类中添加如下属性:
- private List<Orders> ordersList;
-
- public List<Orders> getOrdersList() {
- return ordersList;
- }
-
- public void setOrdersList(List<Orders> ordersList) {
- this.ordersList = ordersList;
- }
-
- @Override
- public String toString() {
- return "Users{" +
- "userid=" + userid +
- ", username='" + username + '\'' +
- ", usersex='" + usersex + '\'' +
- ", roles=" + roles +
- ",orderList=" + ordersList +
- '}';
- }
- /**
- * 查询用户和其所下的订单
- * @return
- */
- List<Users> queryUsersAndOrders();
- <resultMap id="usersAndOrdersMap" type="com.dyh.pojo.Users">
- <id property="userid" column="userid" />
- <result property="username" column="username" />
- <result property="usersex" column="usersex" />
- <!-- 配置一对多的关联关系 -->
- <collection property="ordersList" ofType="com.dyh.pojo.Orders" >
- <id property="orderid" column="orderid" />
- <result property="orderprice" column="orderprice" />
- </collection>
- </resultMap>
- <sql id="deptColumns">
- deptno,dname,loc as city
- </sql>
-
- <select id="queryUsersAndOrders" resultMap="usersAndOrdersMap">
- SELECT u.userid,u.username,u.usersex,
- o.orderid,o.orderprice
- FROM users u,orders o
- WHERE u.userid=o.user_id
- </select>
增加如下方法:
- @Test
- public void testQueryUsersAndOrders(){
- List<Users> list = mapper.queryUsersAndOrders();
- list.forEach(System.out::println);
- }
中增加如下方法:
- /**
- * 查询用户和其所下的订单
- * @return
- */
- List<Users> queryUsersAndOrders2();
中增加如下代码:
- <resultMap id="usersAndOrdersMap2" type="com.dyh.pojo.Users">
- <id property="userid" column="userid" />
- <result property="username" column="username" />
- <result property="usersex" column="usersex" />
- <!-- 配置一对多的关联关系 -->
- <collection property="ordersList" ofType="com.dyh.pojo.Orders"
- select="com.dyh.dao.OrdersMapper.findOrderListByUsersId" column="userid">
- <id property="orderid" column="orderid" />
- <result property="orderprice" column="orderprice" />
- </collection>
- </resultMap>
- <sql id="deptColumns">
- deptno,dname,loc as city
- </sql>
-
- <select id="queryUsersAndOrders2" resultMap="usersAndOrdersMap2">
- SELECT u.userid,u.username,u.usersex
- FROM users u
- </select>
需要增加com.dyh.OrdersMapper.findOrderListByUsersId的接口及实现。
- public interface OrdersMapper {
- /**
- * 根据用户id去查询用户的所有订单
- * @param userid 用户id
- * @return 订单集合
- */
- List<Orders> findOrderListByUsersId(int userid);
- }
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE mapper
- PUBLIC "-//mybatis.org//DTDMapper3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- <mapper namespace="com.dyh.dao.OrdersMapper">
- <select id="findOrderListByUsersId"
- resultType="com.dyh.pojo.Orders" parameterType="int">
- select orderid,orderprice from orders where user_id=#{userid}
- </select>
- </mapper>
增加如下代码:
- @Test
- public void testQueryUsersAndOrders2(){
- List<Users> list = mapper.queryUsersAndOrders2();
- list.forEach(System.out::println);
- }
测试结果
一对一的实现方式二:<association select="" />
延迟加载与立即加载:<association fetchType="lazy|eager" />
一对多关联查询:<collection ofType="集合中的对象类型" />
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。