文章目录
一、延迟加载介绍
在操作数据库时,尽量查询单表,因为查询单表的效率最高。但很多时候难免要进行多表查询,这时使用延迟加载,就可以提高关联查询的效率
。并且延迟加载只能使用resultMap。
二、测试延迟加载
- 下面setting标签中的配置是设置懒加载的两行代码,使用时将其放在全局配置文件中。另外,在dao配置文件中的sql语句也进行了拆分。
- 这里有一个小技巧:如果要在一个xml文件中引用另外一个xml文件中的sql语句,就需要使用另一个xml文件的命名空间.id号。
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
1.创建两张数据库表
创建user表和orders表进行测试,手动添加记录如下:
User表
CREATE TABLE `user` (
`id` INT(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`username` VARCHAR(50) NULL DEFAULT NULL COMMENT '姓名',
`sex` VARCHAR(1) NULL DEFAULT NULL COMMENT '性别',
`address` VARCHAR(200) NULL DEFAULT NULL COMMENT '住址',
`birthday` DATE NULL DEFAULT NULL COMMENT '生日',
PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1
;
orders订单表
CREATE TABLE `orders` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`creattime` DATETIME NULL DEFAULT NULL,
`number` VARCHAR(50) NULL DEFAULT NULL,
`user_id` INT(10) NULL DEFAULT NULL,
`count` INT(10) NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `FK_user_id` (`user_id`),
CONSTRAINT `FK_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=4
;
2.两张表的pojo以及扩展pojo
(1)Orders的pojo
package com.gql.pojo;
import java.io.Serializable;
import java.util.Date;
/**
* 类说明:
* Orders_JavaBean
* @guoqianliang1998.
*/
public class Orders implements Serializable{
private static final long serialVersionUID = 1L;
private int id;
private Date creattime;
private String number;
private int user_id;
private int count;
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Date getCreattime() {
return creattime;
}
public void setCreattime(Date creattime) {
this.creattime = creattime;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public int getUser_id() {
return user_id;
}
public void setUser_id(int user_id) {
this.user_id = user_id;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
(2)User的pojo
package com.gql.pojo;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 类说明:
* User_JavaBean
* @guoqianliang1998.
*/
public class User implements Serializable{
private static final long serialVersionUID = 1L;
private int id;
private String username;
private String sex;
private String address;
private Date birthday;
//用户关联多个订单对象
private List<Orders> orderList;
public List<Orders> getOrderList() {
return orderList;
}
public void setOrderList(List<Orders> orderList) {
this.orderList = orderList;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
(3)扩展类的pojo
package com.gql.pojo.custom;
import com.gql.pojo.Orders;
/**
* 类说明:
* Orders_pojo扩展类
* @guoqianliang1998.
*/
public class OrdersCustom extends Orders {
private String username;
private String sex;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
3.dao接口
package com.gql.mapper.custom;
import java.util.List;
import com.gql.pojo.custom.OrdersCustom;
/**
* 类说明:
* dao层接口
* @guoqianliang1998.
*/
public interface OrdersMapperCustom {
List<OrdersCustom> getOrdersLazyLoading();
}
4.dao配置文件
<?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.gql.mapper.custom.OrdersMapperCustom">
<select id="getOrders" resultType="com.gql.pojo.custom.OrdersCustom">
SELECT
o.id,
o.creattime,
o.number,
o.user_id,
o.count,
u.username,
u.sex
FROM orders o, USER u
WHERE u.id=o.user_id;
</select>
<select id="getOrdersLazyLoading" resultMap="getOrdersLazyLoadingMap">
SELECT
o.id,
o.creattime,
o.number,
o.user_id,
o.count
FROM orders o;
</select>
<resultMap type="com.gql.pojo.custom.OrdersCustom" id="getOrdersLazyLoadingMap">
<id column="id" property="id"/>
<result column="creattime" property="creattime"/>
<result column="number" property="number"/>
<result column="user_id" property="user_id"/>
<result column="count" property="count"/>
<association property="user" column="user_id" select="getOrdersLazySelect"></association>
</resultMap>
<select id="getOrdersLazySelect" parameterType="int" resultType="com.gql.pojo.User">
select * from user where id=#{id}
</select>
</mapper>
5.全局mybatis-config.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>
<properties resource="db.properties"></properties>
<!-- 设置懒加载 -->
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<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>
</environment>
</environments>
<mappers>
<!-- 使用接口的全限定名,接口名必须和sql配置文件同名且同级目录 -->
<package name="com.gql.mapper"/>
</mappers>
</configuration>
6.测试延迟加载
package com.gql.mapper.custom;
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.junit.Before;
import org.junit.Test;
import com.gql.pojo.custom.OrdersCustom;
/**
* 类说明:
* 使用扩展pojo测试dao层
* @guoqianliang1998.
*/
public class OrdersMapperCustomTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void init() throws IOException{
String resource = "mybatis-config.xml";
InputStream in = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
}
@Test
public void testgetOrdersLazyLoading(){
SqlSession session = sqlSessionFactory.openSession();
OrdersMapperCustom mapper = session.getMapper(OrdersMapperCustom.class);
List<OrdersCustom> list = mapper.getOrdersLazyLoading();
System.out.println(list.get(0).getUser().getUsername());
}
}
在debug模式下运行测试代码,可以看到当还没有访问扩展类对象OrdersCustom中的User对象的username属性时,此时只执行了一条sql语句。
当按下F6下一步,此时运行了打印语句,第二条sql语句才执行。
延迟加载测试成功。