MyBatis连接查询
一对一
在类中添加需要关联实体类的一个类属性
public class Blogs implements Serializable {
private Integer id;
private String title;
//private Integer authorId;
private Authors authors;
private Byte featured;
private String style;
xml配置方案:
在需要进行关联查询的mapper中配置association
节点
- property:对应该实体类关联另一个实体类的变量名
- column:对应表的字段名
- javaType:对应关联的实体类
- select:指定子查询(注意要加入名称空间)
<resultMap id="BaseResultMap" type="com.xm.pojo.Blogs">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="title" jdbcType="VARCHAR" property="title" />
<!-- <result column="author_id" jdbcType="INTEGER" property="authorId" />-->
<result column="featured" jdbcType="TINYINT" property="featured" />
<result column="style" jdbcType="VARCHAR" property="style" />
<association property="authors" column="author_id" javaType="Authors" select="com.xm.dao.AuthorsMapper.selectByPrimaryKey"></association>
</resultMap>
@Test
public void test(){
SqlSession session = MyBatisUtil.sqlSession();
BlogsMapper mapper = session.getMapper(BlogsMapper.class);
Blogs blogs = mapper.selectByPrimaryKey(1);
session.commit();
session.close();
System.out.println(blogs);
}
如果是批量查询,关联查询时,如果所查是同一个id,会把所关联直接从一级缓存中获取
一对多
首先在主表中要有一个列表属性用于存放多个数据
public class Posts {
private List<Comments> commentsList;
}
配置文件:
在mapper文件中使用collection
节点
- property:对应表中的commentsList
- column:当前表与外表关联的键(一般是id)
- javaType:对应property的类型
- ofType:对应外表的实体类
<resultMap id="BaseResultMap" type="com.xm.pojo.Posts">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="blog_id" jdbcType="INTEGER" property="blogId" />
<result column="author_id" jdbcType="INTEGER" property="authorId" />
<result column="create_on" jdbcType="TIMESTAMP" property="createOn" />
<result column="section" jdbcType="VARCHAR" property="section" />
<result column="subject" jdbcType="VARCHAR" property="subject" />
<result column="visit" jdbcType="INTEGER" property="visit" />
<collection property="commentsList" column="id" javaType="ArrayList" ofType="Comments"
select="com.xm.dao.CommentsMapper.selectCommentsByPostId"/>
</resultMap>
@Test
public void testSelectPostByPrimaryKey(){
SqlSession session = MyBatisUtil.sqlSession();
PostsMapper mapper = session.getMapper(PostsMapper.class);
PostsWithBLOBs posts = mapper.selectByPrimaryKey(1);
System.out.println(posts);
session.close();
}
上面的两种查询都是先执行一次单表查询,再利用单表查询的结果继续执行其他单表查询,最后组装结果映射
嵌套结果的查询
先执行关联查询,一次性将所有数据都查询出来,再将所有查询出来的列组织成嵌套的结果对象。效率高,但写起来相对比较繁琐
<resultMap id="blogResultMapNested" type="Blogs">
<id column="blog_id" property="id"></id>
<result column="blog_title" property="title"></result>
<result column="blog_style" property="style"></result>
<result column="blog_featured" property="featured"></result>
<!-- 在association中配置关联的表格 -->
<association column="blog_author_id" property="authors" javaType="Authors">
<id column="author_id" property="id"></id>
<result column="author_username" property="username"></result>
<result column="author_password" property="password"></result>
<result column="author_email" property="email"></result>
<result column="author_bio" property="bio"></result>
<result column="author_nickname" property="nickname"></result>
<result column="author_favorite_section" property="favoriteSection"></result>
<result column="author_realname" property="realname"></result>
</association>
</resultMap>
<!-- 使用如下查询方式 -->
<select id="selectBlogListNested" resultMap="blogResultMapNested">
select
b.id as blog_id,
b.title as blog_title,
b.author_id as blog_author_id,
b.style as blog_style,
b.featured as blog_featured,
a.id as author_id,
a.username as author_username,
a.password as author_password,
a.email as author_email,
a.bio as author_bio,
a.favorite_section as author_favorite_section,
a.nickname as author_nickname,
a.realname as author_realname
from blogs b
left join authors a
on b.author_id = a.id;
</select>
构造方法映射
在查询后会调用构造方法创建对象
public class Blogs implements Serializable {
private Integer id;
private String title;
public Blogs(Integer id, String title) {
this.id = id;
this.title = title;
System.out.println("调用了构造方法");
}
<resultMap id="blogResultMapConstructor" type="Blogs">
<constructor>
<idArg column="id" javaType="int"/>
<arg column="title" javaType="string"/>
</constructor>
</resultMap>
<select id="selectBlogByIdConstructor" parameterType="int" resultMap="blogResultMapConstructor">
select * from blogs where id = #{id}
</select>
延迟加载
如果没有在mybatis配置文件中配置延迟加载,则默认使用积极加载,只要进行查询,都会执行所关联表的查询
启动延迟加载的配置:
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
延迟加载分为积极延迟加载和非积极延迟加载,当开启积极延迟加载后,默认是积极
积极延迟加载:只要获取任意属性内容,无论属性是否是关联表的内容,都会执行关联的表查询
非积极延迟加载:使用非延迟加载,只有当访问关联表数据时,才会执行关联表的查询。
<settings >
<setting name="aggressiveLazyLoading" value="false"/>
</settings>