Mybatis提供了关联查询映射的功能。
一、一对一关联
实体类如下:
Users表对应的实体类:
public class User {
private int id;
private String names;
private int age;
private Teacher teacher;
......getXxx和setXxx方法
}
Teacher表对应的实体类:
public class Teacher {
private int id;
private String name;
.....getXxx和setXxx方法
}
Mapper文件中的配置如下:
<mapper namespace="com.tianjunwei.lazy.entity.Users">
<select id="getUser" parameterType="int" resultMap="user">
select * from users,tbl_teacher where users.id=#{id} and users.teacher_id=tbl_teacher.id
</select>
<resultMap type="com.tianjunwei.lazy.entity.User" id="user" >
<id column="id" property="id" javaType="int" jdbcType="INTEGER"></id>
<result column="name" property="names" javaType="string" jdbcType="VARCHAR"/>
<result column="age" property="age" javaType="int" jdbcType="INTEGER"/>
<association property="teacher" javaType="com.tianjunwei.lazy.entity.Teacher"> <!-- fetchType="lazy" -->
<id property="id" column="id"/>
<result property="name" column="name"/>
</association>
</resultMap>
</mapper>
Main函数如下:
public class LazyUser {
public static void main(String [] args){
//mybatis的配置文件
String resource = "learn/mybatis-config.xml";
InputStream is = LazyUser.class.getClassLoader().getResourceAsStream(resource);
//构建sqlSession的工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = sessionFactory.openSession();
String statement = "com.tianjunwei.lazy.entity.Users.getUser";//映射sql的标识字符串
//执行查询返回一个唯一user对象的sql
User user = session.selectOne(statement, 1);
session.commit(true);
System.out.println(user.getNames());
Teacher teacher = user.getTeacher();
System.err.println(teacher.getName());
}
}
这样就可以通过查询获得一对一的User和Teacher的关联数据。
虽然上面的示例帮助我们查询到了User和Teacher的关联数据,但有时候可能我们并不需要关联数据,并且我们是使用一条sql语句通过两个表的联合查询来获得数据的。Mybatis给我们提供了延迟加载的机制,就是当我们不需要Teacher的数据时,并不会给我们查询,当需要Teacher数据时再进行查询,这样有一点不好的地方就是不是一次查询数据,需要多次连接数据库来获取数据。
1、首选需要在Mybatis的配置文件中添加如下配置:
<!-- 打开延迟加载的开关 -->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 将积极加载改为消息加载即按需加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
2、修改Mapping文件中的内容:
其实就是执行两次sql语句分别获取Users和Teacher中的值
<mapper namespace="com.tianjunwei.lazy.entity.User">
<select id="getById" parameterType="int" resultMap="user">
select * from users where users.id=#{id}
</select>
<select id="getTeacher" resultMap="teacher">
select * from tbl_teacher where id=#{id}
</select>
<resultMap type="com.tianjunwei.lazy.entity.Teacher" id="teacher" >
<id column="id" property="id" javaType="int" jdbcType="INTEGER"></id>
<result column="name" property="name" javaType="string" jdbcType="VARCHAR"/>
</resultMap>
<resultMap type="com.tianjunwei.lazy.entity.User" id="user" >
<id column="id" property="id" javaType="int" jdbcType="INTEGER"></id>
<result column="name" property="names" javaType="string" jdbcType="VARCHAR"/>
<result column="age" property="age" javaType="int" jdbcType="INTEGER"/>
<association property="teacher" javaType="com.tianjunwei.lazy.entity.Teacher" select="com.tianjunwei.lazy.entity.User.getTeacher" column="id"> <!-- fetchType="lazy" -->
<id property="id" column="id"/>
<result property="name" column="name"/>
</association>
</resultMap>
</mapper>
Main函数中的方法还是和原来的一样
public class LazyMain {
public static void main(String [] args){
//mybatis的配置文件
String resource = "learn/mybatis-config.xml";
InputStream is = LazyMain.class.getClassLoader().getResourceAsStream(resource);
//构建sqlSession的工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = sessionFactory.openSession();
String statement = "com.tianjunwei.lazy.entity.User.getById";//映射sql的标识字符串
//执行查询返回一个唯一user对象的sql
User user = session.selectOne(statement, 1);
session.commit(true);
System.out.println(user.getNames());
Teacher teacher = user.getTeacher();
System.err.println(teacher.getName());
}
}
执行过程:从下图你可以看到是执行了两次Sql语句。
当把下面代码注释掉之后,就是我们不需要teacher的数据时
//Teacher teacher = user.getTeacher();
//System.err.println(teacher.getName());
执行结果如下图,就不会执行teacher相关的sql语句,这样就实现了延迟加载的功能。
以上介绍的是一对一的情况,Mapping文件中使用的是association标签
二、一对多关联
我们介绍一下一对多情况
Teacher的实体定义如下:
public class Teacher {
private int id;
private String name;
private List<User> users;
.....getXxx和setXxx方法....
}
Mapper文件中的定义如下,一对多使用的标签是collection,这里我们还是使用延迟加载方式,实现原理就是执行两次SQL,按需执行SQL语句。
<mapper namespace="com.tianjunwei.lazy.entity.Teacher">
<select id="getById" parameterType="int" resultMap="user">
select * from users where users.teacher_id=#{id}
</select>
<select id="getTeacher" resultMap="teacher">
select * from tbl_teacher where id=#{id}
</select>
<resultMap type="com.tianjunwei.lazy.entity.Teacher" id="teacher" >
<id column="id" property="id" javaType="int" jdbcType="INTEGER"></id>
<result column="name" property="name" javaType="string" jdbcType="VARCHAR"/>
<collection property="users" column="id" select="com.tianjunwei.lazy.entity.Teacher.getById" javaType="list">//使用collection标签
</collection>
</resultMap>
<resultMap type="com.tianjunwei.lazy.entity.User" id="user" >
<id column="id" property="id" javaType="int" jdbcType="INTEGER"></id>
<result column="name" property="names" javaType="string" jdbcType="VARCHAR"/>
<result column="age" property="age" javaType="int" jdbcType="INTEGER"/>
</resultMap>
</mapper>
Main函数如下:
public class LazyMainTeacher {
public static void main(String [] args){
//mybatis的配置文件
String resource = "learn/mybatis-config.xml";
InputStream is = LazyMainTeacher.class.getClassLoader().getResourceAsStream(resource);
//构建sqlSession的工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = sessionFactory.openSession();
String statement = "com.tianjunwei.lazy.entity.Teacher.getTeacher";//映射sql的标识字符串
//执行查询返回一个唯一user对象的sql
Teacher teacher = (Teacher) session.selectList(statement, 1).get(0);
session.commit(true);
System.out.println(teacher.getName());
List<User> users = teacher.getUsers();
System.err.println(users.get(3).getAge());
}
}
运行结果:可以看到确实是执行两次SQL语句
分享到:
相关推荐
这次我们将深入探讨 MyBatis 如何实现这种高级关联查询,并通过源码分析来理解其工作原理。 “一对多”关联通常指的是一个实体(如用户)可以拥有多个关联实体(如订单)。在 MyBatis 中,我们可以使用 `...
5. **延迟加载(Lazy Loading)**:当需要提高性能时,可以配置 Mybatis 使用延迟加载策略,只在真正需要时才加载关联的对象。 通过对这些源代码的学习,开发者不仅可以提升 Mybatis 的使用技巧,还能深入理解 ORM ...
5. 探索高级特性:如缓存、关联查询、延迟加载等,提升开发效率。 总之,MyBatis3.2.2是一个强大的工具,通过深入研究源码和文档,开发者不仅可以提升自己的技能,还能更好地利用它来提高项目的开发效率和质量。
5. **使用延迟加载(Lazy Loading)**:MyBatis支持延迟加载,即在真正需要子记录时才去数据库查询。但这种方式在大数据量时可能导致不必要的数据库交互,因此需要根据实际需求权衡。 6. **批处理(Batch)**:对于...
Mybatis 是一个流行的 Java 持久层框架,它简化了数据库操作,通过 XML 或注解方式将 SQL 语句与 Java 代码分离。在面试中,了解 Mybatis ...在实际开发中,掌握 Mybatis 的源码分析和优化技巧也是提升项目性能的关键。
8. **延迟加载(Lazy Loading)**: MyBatis支持延迟加载,即在真正需要关联数据时才执行查询。这可以通过在`<collection>`标签中设置`lazyLoad="true"`实现。 9. **示例代码**:在`mybatisDemo001`项目中,可能包含...
4. **关联映射和延迟加载**:MyBatis的关联映射允许开发者在一次查询中获取到多个表的数据,实现对象关系映射。延迟加载则是一种优化策略,只有当真正需要关联数据时才会进行查询。`关联映射、延迟加载(难点).rar`...
1. MyBatis的高级特性:例如延迟加载、动态SQL的更复杂用法、一对一和一对多的关联映射等。 2. MyBatis的Executor执行器:解释不同执行器的差异,如Simple、Reuse和Batch,以及它们在性能上的影响。 3. MyBatis的...
此外,还会涉及缓存机制、延迟加载和关联查询优化等内容。 4. **实战演练**:教程可能包含实际案例,让学习者通过编写和运行代码来加深理解,如创建一个简单的CRUD应用,或者处理复杂的一对多、多对多关系。 通过...
3. **延迟加载(Lazy Loading)**: MyBatis的延迟加载特性可以在需要时才去获取关联数据,而不是一开始就全部加载。但是,如果在循环中访问关联数据,延迟加载反而会导致N+1问题,因此需要谨慎使用。 4. **子查询或...
源码分析可能包括以下几个方面: 1. **框架结构**:了解ORM框架的整体架构,如各个模块的划分和它们之间的关系。 2. **映射机制**:探究对象与数据库表之间的映射是如何实现的,包括字段映射、关系映射等。 3. **...
- **延迟加载**:仅在真正需要时才加载关联对象,提高系统性能; - **分页查询**:实现复杂数据分页功能,避免大数据量带来的性能瓶颈; - **批量操作**:支持批量插入、更新等操作,减少网络通信次数,提升效率。 ...
7. **灵活的映射**:MyBatis支持一对一、一对多、多对一等多种关联关系的映射,以及延迟加载,使得数据对象关系的处理更为便捷。 学习MyBatis时,首先需要了解其基本概念,如SqlSessionFactory、SqlSession、Mapper...
使用分页和延迟加载技术,提升响应速度;通过集群部署和负载均衡提高系统可用性和并发处理能力。 9. **评估与改进**:推荐系统的效果可通过准确率、召回率、F1值等指标进行评估。根据评估结果,可以调整相似度计算...
6. 性能优化:考虑到图片的大小,可能会实现图片的延迟加载、缓存策略,以提高用户体验和服务器性能。 项目的源代码文件"sunualbum-main"很可能包含了所有必要的Java源代码、配置文件、静态资源(如HTML、CSS、...