Data Access 之 MyBatis(三) - SQL Mapping XML(Part C)(下)

简介: Data Access 之 MyBatis(三) - SQL Mapping XML(Part C)

新建SQL映射文件lock.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.citi.dao.LockDao">
    <select id="getLockById" resultMap="mylock">
        SELECT l.id,l.lockName,k.id kid, k.keyname,k.lockid
            FROM t_lock l
            LEFT JOIN t_key k ON l.id = k.lockid
            WHERE l.id=#{id}
    </select>
    <resultMap id="mylock" type="com.citi.entity.Lock">
        <id property="id" column="id"></id>
        <result property="lockName" column="lockName"></result>
        <collection property="keyList" ofType="com.citi.entity.Key">
            <!--column是起的别名,如果没起别名,就和数据库列字段一致-->
            <id property="id" column="kid"></id>
            <result property="keyName" column="keyName"></result>
        </collection>
    </resultMap>
</mapper>
复制代码
  • collection:复杂类型的集合
  • ofType:指定集合里面元素的类型

将lock.xml注册到MyBatis全局配置文件中

<mappers>
    <mapper resource="mappers/employee.xml"/>
    <mapper resource="mappers/cat.xml"/>
    <mapper resource="mappers/key.xml"/>
    <mapper resource="mappers/lock.xml"/>
</mappers>
复制代码

新建测试类

public class LockDaoTest {
    SqlSessionFactory sqlSessionFactory = null;
    SqlSession openSession = null;
    @Before
    public void setUp() throws Exception {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        openSession = sqlSessionFactory.openSession();
    }
    @Test
    public void getLockById() {
        LockDao lockDao = openSession.getMapper(LockDao.class);
        Lock lock = lockDao.getLockById(3);
        System.out.println(lock);
        List<Key> keyList = lock.getKeyList();
        for (Key key : keyList) {
            System.out.println("Key:" + key);
        }
    }
}
复制代码

执行测试

dd0ed556ef5f416381463267e89b4bc7_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

联合查询较为繁琐,使用分步查询也可以完成;先查出Key,在根据Key的信息到t_lock表中查出锁的信息

分步查询 Key -> Lock

在KeyDao和LockDao中分别增加一个查询方法

Lock getLockByIdSimplely(Integer id);
复制代码
Key getKeyByIdSimplely(Integer id);
复制代码

在lock.xml映射文件中增加SQL语句

<select id="getLockByIdSimplely" resultType="com.citi.entity.Cat">
    select * from t_lock where id = #{id}
</select>
复制代码

在key.xml中完成分步查询

<select id="getKeyByIdSimplely" resultMap="mykeysimplely">
    select * from t_key where id = #{id}
</select>
<resultMap id="mykeysimplely" type="com.citi.entity.Key">
    <id property="id" column="id"></id>
    <result property="keyName" column="keyname"></result>
    <association property="lock"
                 select="com.citi.dao.LockDao.getLockByIdSimplely"
                 column="lockid">
    </association>
</resultMap>
复制代码
  • property:指定封装哪个属性
  • select:指定一个查询SQL的唯一标识,MyBatis自动调用指定的SQL将查询的结果结果封装到指定的属性
  • colume:指定将哪一列数据传递过去

在KeyDaoTest中增加getKeyByIdSimplely方法的测试代码

@Test
public void getKeyByIdSimplely() {
    KeyDao keyDao = openSession.getMapper(KeyDao.class);
    Key key = keyDao.getKeyByIdSimplely(1);
    System.out.println(key);
}
复制代码

执行测试

004e6b40be7947d0877df4e5b96c232b_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

根据控制台打印的信息可以看出分步查询其实就是分别执行了两条SQL,先获取Key,在获取Lock;每次查询Key都要数据库执行两条SQL严重影响性能,而且并不是每次查询Key的时候也需要锁的信息,因此对查询锁信息可以使用按需加载,需要的时候再执行查锁。

在MyBatis全局配置文件中配置开启延迟加载和属性按需加载

<settings>
    <setting name="lazyLoadingEnabled" value="true"/>
    <setting name="aggressiveLazyLoading" value="true"/>
</settings>
复制代码

将打印key的代码注释(不注释会调用Key的toString方法导致懒加载失效),再次执行测试

858334fe062b411b8bbec9efcd0babcb_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

控制台只会打印出一条SQL语句,也就是后台只执行了一条SQL语句

修改测试代码,获取Lock

@Test
public void getKeyByIdSimplely() {
    KeyDao keyDao = openSession.getMapper(KeyDao.class);
    Key key = keyDao.getKeyByIdSimplely(1);
    // System.out.println(key);
    String lockName = key.getLock().getLockName();
    System.out.println(lockName);
}
复制代码

再次测试

5421111bf6dc4b2892f25dc06e4ff13c_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

覆盖全局的延迟加载配置,在association标签中增加fetchType="eager",注释掉获取锁的代码,再次执行测试

e51efa0850b04f429c4d25f033c26129_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

分步查询 Lock -> Key

分别在LockDao、KeyDao中新增方法

Lock getLockByIdStep(Integer id);
复制代码
List<Key> getKeysByLockId(Integer id);
复制代码

在key.xml中新增查询key的SQL语句

<select id="getKeysByLockId" resultType="com.citi.entity.Key">
    select * from t_key where lockid = #{id}
</select>
复制代码

在lock.xml中新增getLockByIdStep方法的映射

<select id="getLockByIdStep" resultMap="mylockstep">
    select * from t_lock where id = #{id}
</select>
<resultMap id="mylockstep" type="com.citi.entity.Lock">
    <id property="id" column="id"></id>
    <result property="lockName" column="lockName"></result>
    <collection property="keyList"
                select="com.citi.dao.KeyDao.getKeysByLockId"
                column="id">
    </collection>
</resultMap>
复制代码

增加测试方法

@Test
public void getLockByIdStep() {
    LockDao lockDao = openSession.getMapper(LockDao.class);
    Lock lock = lockDao.getLockByIdStep(3);
    System.out.println(lock);
    List<Key> keyList = lock.getKeyList();
    for (Key key : keyList) {
        System.out.println("Key:" + key);
    }
}
复制代码

执行测试

903990ba71ea4da4a7a7b4906df8f706_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

reslutMap标签中的 column属性是用来传递select属性指定的查询方法的参数,如果该查询方法有多个参数则可以使用{key1=value1,key2=value2}的方式来传递数据。

实际应用中更推荐使用连接查询的方式而非分步查询,相比较会减少对数据库的压力


相关文章
|
druid Java 数据库连接
SpringBoot原理分析 | Spring Data整合:JDBC、Druid、Mybatis
SpringBoot原理分析 | Spring Data整合:JDBC、Druid、Mybatis
287 0
|
SQL
启动mysq异常The server quit without updating PID file [FAILED]sql/data/***.pi根本解决方案
启动mysq异常The server quit without updating PID file [FAILED]sql/data/***.pi根本解决方案
305 0
|
9月前
|
SQL Oracle 数据库
使用访问指导(SQL Access Advisor)优化数据库业务负载
本文介绍了Oracle的SQL访问指导(SQL Access Advisor)的应用场景及其使用方法。访问指导通过分析给定的工作负载,提供索引、物化视图和分区等方面的优化建议,帮助DBA提升数据库性能。具体步骤包括创建访问指导任务、创建工作负载、连接工作负载至访问指导、设置任务参数、运行访问指导、查看和应用优化建议。访问指导不仅针对单条SQL语句,还能综合考虑多条SQL语句的优化效果,为DBA提供全面的决策支持。
228 11
|
SQL Java 关系型数据库
spring data elasticsearch 打印sql(DSL)语句
spring data elasticsearch 打印sql(DSL)语句
781 0
|
11月前
|
SQL 存储 机器学习/深度学习
将 AWS Data Lake 和 S3 与 SQL Server 结合使用
将 AWS Data Lake 和 S3 与 SQL Server 结合使用
164 0
|
XML Java 关系型数据库
IDEA 报错: java.sql.SQLException: Access denied for user ‘root ‘@‘localhost‘ (using password: YES)
IDEA 报错: java.sql.SQLException: Access denied for user ‘root ‘@‘localhost‘ (using password: YES)
1980 0
|
SQL 存储 数据可视化
access sql 数据库,Access SQL
access sql 数据库,Access SQL
解决java.sql.SQLException: Access denied for user ‘Lenovo‘@‘localhost‘ (using password: YES)问题~
解决java.sql.SQLException: Access denied for user ‘Lenovo‘@‘localhost‘ (using password: YES)问题~
313 0
|
4月前
|
Android开发 开发者
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
本文详细介绍了如何通过自定义 `attrs.xml` 文件实现 Android 自定义 View 的属性配置。以一个包含 TextView 和 ImageView 的 DemoView 为例,讲解了如何使用自定义属性动态改变文字内容和控制图片显示隐藏。同时,通过设置布尔值和点击事件,实现了图片状态的切换功能。代码中展示了如何在构造函数中解析自定义属性,并通过方法 `setSetting0n` 和 `setbackeguang` 实现功能逻辑的优化与封装。此示例帮助开发者更好地理解自定义 View 的开发流程与 attrs.xml 的实际应用。
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
|
11月前
|
XML 前端开发 Java
讲解SSM的xml文件
本文详细介绍了SSM框架中的xml配置文件,包括springMVC.xml和applicationContext.xml,涉及组件扫描、数据源配置、事务管理、MyBatis集成以及Spring MVC的视图解析器配置。
222 1