iBatis 之 启用延迟加载示例

从概念上讲,延迟加载是一种延迟对象创建直到需要时的策略。它也称为设计模式。当我们谈论从数据库中获取信息时的延迟加载时,延迟加载本质上是指将某些选择/子选择查询的执行延迟到要求其相关数据的时间。

在本教程中,我将展示一个使用iBatis开发应用程序时延迟加载的示例。本教程分为以下几节。

1)创建一个Maven项目
2)更新运行时依赖项
3)在启用延迟加载的情况下配置sql-map和config文件
4)编写域类
5)测试应用程序

1)创建一个Maven项目

运行以下命令以创建一个简单的Java项目,该项目受eclipse插件支持。

mvn archetype:generate -DgroupId=com.how2codex.ibatis.demo -DartifactId=ibatisHelloWorld
-DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

2)更新运行时依赖项

这将在pom.xml文件中完成。您可以下载所需的jar文件,并将其放在lib文件夹中。

pom.xml

<dependencies>
    <!-- iBatis support -->
    <dependency>
        <groupId>org.apache.ibatis</groupId>
        <artifactId>ibatis-sqlmap</artifactId>
        <version>2.3.4.726</version>
    </dependency>
    <!-- Database connectivity support -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.9</version>
    </dependency>
    <!-- Proxy support (Mandatory) -->
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2.2</version>
    </dependency>
    <!-- Internal dependency (Required) -->
    <dependency>
        <groupId>asm</groupId>
        <artifactId>asm-util</artifactId>
        <version>3.3.1</version>
    </dependency>
    <!-- Internal dependency (Required) -->
    <dependency>
        <groupId>opensymphony</groupId>
        <artifactId>oscache</artifactId>
        <version>2.4</version>
        <scope>compile</scope>
        <!-- This excludes the transitive dependency on JMS -->
        <exclusions>
                <exclusion>
                        <groupId>javax.jms</groupId>
                        <artifactId>jms</artifactId>
                </exclusion>
        </exclusions>
    </dependency>

3)编写域类

在域类UserTEO.java和DepartmentTEO.java下面。UserTEO具有DepartmentTEO的参考,我们的目标是延迟加载。

UserTEO.java

package com.how2codex.ibatis.demo.dto;
import java.io.Serializable;
public class UserTEO implements Serializable
{
    private static final long serialVersionUID = 1L;
    
    private Integer id;
    private String name;
    private String email;
    private String password;
    private int status;
    private DepartmentTEO department;
    
    //Getters and Setters
}

部门TEO.java

package com.how2codex.ibatis.demo.dto;
import java.io.Serializable;
public class DepartmentTEO implements Serializable
{
    private static final long serialVersionUID = 1L;
    
    private int id;
    private String name;
    
    //Getters and Setters
}

4)在启用延迟加载的情况下配置sql-map和config文件

要在您的应用程序中配置iBatis,您将需要配置sql-map-config.xml文件以及sql-map文件。

以下是为本教程编写的两个此类文件。

sql-maps-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig
        PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
<sqlMapConfig>
    
    <!--  Lazy loading is globally enabled here -->
    <settings useStatementNamespaces="true" cacheModelsEnabled="false" lazyLoadingEnabled="true"/>
    
    <transactionManager type="JDBC">
        <dataSource type="SIMPLE">
          <property name="JDBC.Driver" value="com.mysql.jdbc.Driver"/>
          <property name="JDBC.ConnectionURL"  value="jdbc:mysql://localhost:3306/demoDB"/>
          <property name="JDBC.Username" value="root"/>
          <property name="JDBC.Password" value="lg225295"/>
        </dataSource>
      </transactionManager>
    
    <sqlMap resource="user.xml"/>
</sqlMapConfig>

user.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap  PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="user">
    <typeAlias alias="USER" type="com.how2codex.ibatis.demo.dto.UserTEO" />
    <typeAlias alias="DEPARTMENT" type="com.how2codex.ibatis.demo.dto.DepartmentTEO" />
    
    <resultMap id="userResultMap" class="USER">
        <result property="id" column="ID" />
        <result property="name" column="NAME" />
        <result property="email" column="EMAIL" />
        <result property="password" column="PASSWORD" />
        <result property="status" column="STATUS" />
        <result property="department" column="DEPT_ID" select="user.getDepartmentById" />
    </resultMap>
    
    <resultMap id="departmentResultMap" class="DEPARTMENT">
        <result property="id" column="ID" />
        <result property="name" column="NAME" />
    </resultMap>
    
    <select id="getDepartmentById" parameterClass="java.lang.Integer" resultMap="departmentResultMap">
          SELECT * FROM DEPARTMENT WHERE ID = #value#
    </select>
    
    <select id="getUserById" parameterClass="java.lang.Integer" resultMap="userResultMap">
          SELECT * FROM USERINFO WHERE ID = #value#
    </select>
    
</sqlMap>

5)测试应用程序

我在下面编写了加载iBatis配置,连接数据库和加载用户对象的代码。它首先调用用户详细信息,然后从数据库中加载用户对象。

但是,只有当我尝试从用户对象获取部门数据时,才选择部门数据。这意味着部门数据是延迟加载的。

package com.how2codex.ibatis.demo;
import java.io.Reader;
import com.how2codex.ibatis.demo.dao.UserDao;
import com.how2codex.ibatis.demo.dao.UserDaoIbatis;
import com.how2codex.ibatis.demo.dto.UserTEO;
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
public class TestMain {
    public static void main(String[] args) throws Exception
    {
        UserDao manager = new UserDaoIbatis();
        
        Reader reader = Resources.getResourceAsReader("sql-maps-config.xml");
        SqlMapClient sqlmapClient = SqlMapClientBuilder.buildSqlMapClient (reader);
        
        UserTEO user = manager.getUserById(1, sqlmapClient);
        System.out.println(user.getEmail());
        
        System.out.println("LAZY load the department");
        
        System.out.println(user.getDepartment().getName());
    }
}

下面是程序的输出。

DEBUG [main] - Created connection 27994366.
DEBUG [main] - {conn-100000} Connection
DEBUG [main] - {conn-100000} Preparing Statement:      SELECT * FROM USERINFO WHERE ID = ? 
DEBUG [main] - {pstm-100001} Executing Statement:      SELECT * FROM USERINFO WHERE ID = ? 
DEBUG [main] - {pstm-100001} Parameters: [1]
DEBUG [main] - {pstm-100001} Types: [java.lang.Integer]
DEBUG [main] - {rset-100002} ResultSet
DEBUG [main] - {rset-100002} Header: [ID, NAME, EMAIL, PASSWORD, STATUS, DEPT_ID]
DEBUG [main] - {rset-100002} Result: [1, Demo User, demo-user@howtodoinjava.com, password, 1, 1]
DEBUG [main] - Returned connection 27994366 to pool.
demo-user@howtodoinjava.com
LAZY load the department
DEBUG [main] - Checked out connection 27994366 from pool.
DEBUG [main] - {conn-100003} Connection
DEBUG [main] - {conn-100003} Preparing Statement:      SELECT * FROM DEPARTMENT WHERE ID = ? 
DEBUG [main] - {pstm-100004} Executing Statement:      SELECT * FROM DEPARTMENT WHERE ID = ? 
DEBUG [main] - {pstm-100004} Parameters: [1]
DEBUG [main] - {pstm-100004} Types: [java.lang.Integer]
DEBUG [main] - {rset-100005} ResultSet
DEBUG [main] - {rset-100005} Header: [ID, NAME]
DEBUG [main] - {rset-100005} Result: [1, Finance]
DEBUG [main] - Returned connection 27994366 to pool.
Finance
源码下载

学习愉快!

saigon has written 1440 articles

Leave a Reply