Mybatis联合查询

案例

一个博客系统中,用户可以任意发表博文(Post),用户还可以对博文进行评论(Comment)。于是在这个系统中,存在以下的关系:

174535_QpRn_254689.png

在数据库中,Author,Post和Comment存在于不同的表中。但Comment会使用外键关联Post,而Post又会外键关联Author。

create table author (
  id int primary key,
  name varchar(20)
);

create table post (
  id int primary key,
  authorId int,
  title varchar(100),
  created timestamp,
  content text,
  foreign key (authorId) REFERENCES author(id)
);

create table comment (
  id int primary key,
  postId int,
  content text,
  created timestamp,
  foreign key (postId) REFERENCES post(id)
);

在java类中,Author, Post和Comment分别对应的java类型为:

public class Post {
  private int id;
  private Author author;
  private String title;
  private String content;
  private Timestamp created;
  private List<Comment> comments;
  // getters and setters
}

public class Author {
  private int id;
  private String name;
  // getters and setters
}

public class Comment {
  private int id;
  private int postId;
  private String content;
  private Timestamp created;
  // getters and setters
}

下面使用Mybatis的联合查询,创建一个Post实例,其中comments会自动填充到Post的comments表中。

联合查询

首先给出mybatis的配置:

<?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>
    <typeAliases>
        <typeAlias type="com.test.Post" alias="Post" />
        <typeAlias type="com.test.Author" alias="Author" />
        <typeAlias type="com.test.Comment" alias="Comment" />
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="jdbc" />
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/joey" />
                <property name="username" value="mysql" />
                <property name="password" value="mysql" />
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/test/my/BlogMapper.xml" />
    </mappers>
</configuration>

以及SessionManager工厂类:

public class SessionManager {
	private static SqlSessionFactory sessionFactory;
	
	public static synchronized SqlSessionFactory getSessionFactory() {
		if (sessionFactory != null) return sessionFactory;
		
		String resource = "com/lux/stat/dest/mybatis-conf.xml";
		try {
			sessionFactory = new SqlSessionFactoryBuilder().build(Resources
					.getResourceAsReader(resource));
		} catch (IOException e) {
			e.printStackTrace();
		}
		return sessionFactory;
	}
}

还有BlogMapper接口:

public interface BlogMapper {
    public Post getPostById(int id);
    public List<Post> getPosts();
}

最后是测试用main函数:

public class Test {
    public static void main(String[] args) {
        // initData();
        SqlSession session = SessionManager.getSessionFactory().openSession();
        BlogMapper mapper = session.getMapper(BlogMapper.class);
        Post post = mapper.getPostById(1);
		
        System.out.println(post.getAuthor().getName());
        System.out.println(post.getComments().size());
        System.out.println(post.getComments().get(0).getContent());
        
        List<Post> posts = mapper.getPosts();
        post=posts.get(0);
        System.out.println(post.getAuthor().getName());
        System.out.println(post.getComments().size());
        System.out.println(post.getComments().get(0).getContent());
        session.close();
    }
}

Mybatis联合查询提供了两种方式

方式一,嵌套查询

BlogMapper.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.test.my.BlogMapper">
  <resultMap id="postResult" type="Post">
    <association property="author" column="authorId" javaType="Author" select="getAuthorById"/>
    <collection property="comments" javaType="ArrayList" column="id" ofType="Comment" select="getCommentsById"/>
  </resultMap>
  
  <select id="getPostById" resultMap="postResult">
     select id, authorId, title, content, created from post where id=#{param1}
  </select>
  <select id="getPosts" resultMap="postResult">
     select id, authorId, title, content, created from post
  </select>
  <select id="getAuthorById" resultType="Author">
    select id,  name from author where id=#{param1}
  </select>
  <select id="getCommentsById" resultType="Comment">
    select id,  content, created, postId from comment where postId=#{param1}
  </select>
</mapper>

此类方式的缺点是效率低。组合最后的实例,必须要执行多条语句。像本例的getPosts()方法,如果posts数目为n,那么执行sql的条数应该为1+n+n。

方式二,JOIN语句

BlogMapper.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.test.my.BlogMapper">
  <resultMap id="postResult" type="Post">
    <id property="id" column="id" />
    <result property="title" column="title" />
    <result property="content" column="content" />
    <result property="created" column="created" />
    <association property="author" javaType="Author">
      <id property="id" column="authorId" />
      <result property="name" column="name" />
    </association>
    <collection property="comments" javaType="ArrayList" ofType="Comment">
      <id property="id" column="commentId" />
      <result property="content" column="comment" />
      <result property="created" column="commentCreated" />
    </collection>
  </resultMap>
  
  <select id="getPosts" resultMap="postResult">
     select A.id, A.title, A.content, A.created, 
            B.id as authorId, B.name, 
            C.id as commentId, C.content as comment, C.created as commentCreated
     from post A 
     join author B on A.authorid=B.id
     join comment C on A.id = C.postId
  </select>
  <select id="getPostById" resultMap="postResult">
     select A.id, A.title, A.content, A.created, 
            B.id as authorId, B.name, 
            C.id as commentId, C.content as comment, C.created as commentCreated
     from post A 
     join author B on A.authorid=B.id
     join comment C on A.id = C.postId
     where A.id=#{param1}
  </select>
</mapper>

使用此种方法,可以一条join语句便组装好post实例。

转载于:https://my.oschina.net/xpbug/blog/324710

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值