目的:提高查询效率,降低数据库查询压力,提升系统整体性能。
一级缓存:默认开启,Session级别,同一个会话内生效。
命中缓存的情况:statementid、SQL语句、结果集的范围、传递的参数相同。
同一个查询之前执行DML操作,清空缓存,session.clearCache()也会清空缓存。
二级缓存:需要配置,SQLSessionFactory级别,不同会话之间可以共享。
使用步骤:1、全局配置mybatis_config.xml文件中
2、mapper.xml配置要使用二级缓存的查询
3、使用查询返回的对象的类必须实现序列化接口。
MemCached、OSCache、EHCache。
标签是处理单一的关联对象(处理单一属性的关联关系)。 property :指定关联对象的属性
javaType :关联对象的类型(可以省略)
select :执行一个新的查询
column:在新的查询中用哪个列的值作为查询条件
2.1 RolesMapper.java
提供一个根据用户主键userid去查询用户角色的方法,如下:
public interface RolesMapper {
/**
* 根据用户id查询此用户对应的角色信息
* @param id
* @return
*/
Roles findRolesByUserId(int id);
}
2.2 RolesMapper.xml配置
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 queryUsersAndRoles();
// 增加如下方法
List queryUsersAndRolesBySelect();
}
2.5 UserMapper.xml
增加如下内容:
deptno,dname,loc as city
2.6 JUnit单元测试UsersMapperTest.java
@Test
public void testQueryUsersAndRoles2(){
List 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 list = mapper.queryUsersAndRolesBySelect();
//list.forEach(System.out::println);
for (Users users:list) {
System.out.println(users.getUsername());
// 懒加载没有获取角色信息的时候,不会去查询角色表
//System.out.println(users.getRoles());
}
}
UserMapper.xml配置修改如下:
应用场景:完成用户与订单查询。 要求一个用户可以对应多个订单。
标签是处理所关联对象是多个的(处理关联属性是集合时的关联关系)。 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 ordersList;
public List getOrdersList() {
return ordersList;
}
public void setOrdersList(List ordersList) {
this.ordersList = ordersList;
}
@Override
public String toString() {
return "Users{" +
"userid=" + userid +
", username='" + username + '\'' +
", usersex='" + usersex + '\'' +
", roles=" + roles +
",orderList=" + ordersList +
'}';
}
/**
* 查询用户和其所下的订单
* @return
*/
List queryUsersAndOrders();
deptno,dname,loc as city
增加如下方法:
@Test
public void testQueryUsersAndOrders(){
List list = mapper.queryUsersAndOrders();
list.forEach(System.out::println);
}
中增加如下方法:
/**
* 查询用户和其所下的订单
* @return
*/
List queryUsersAndOrders2();
中增加如下代码:
deptno,dname,loc as city
需要增加com.dyh.OrdersMapper.findOrderListByUsersId的接口及实现。
public interface OrdersMapper {
/**
* 根据用户id去查询用户的所有订单
* @param userid 用户id
* @return 订单集合
*/
List findOrderListByUsersId(int userid);
}
增加如下代码:
@Test
public void testQueryUsersAndOrders2(){
List list = mapper.queryUsersAndOrders2();
list.forEach(System.out::println);
}
测试结果
一对一的实现方式二:
延迟加载与立即加载:
一对多关联查询: