(一)Mybatis高级映射包括一对一,一对多,多对多
我们设计如下几张表:
oa_forum:论坛主题分类
oa_topic:发帖(包括帖子标题,帖子内容等,其中相关外键:forumId)
oa_reply:帖子回复(包括回复的内容,时间等等,相关外键:topicId)
数据模型分析:
1.分模块对每张表的内容进行熟悉。
2.每张表重要的字段设置 非空字段、外键字
3.数据库级别表与表之间的关系 外键关系
4.表与表之间的业务关系 在分析表与表之间的业务关系时一定要建立 在某个业务意义基础上去分析。
oa_forum====>oa_topic:一对多
oa_topic=====>oa_forum:一对一(一个帖子只能属于一个主题)
oa_topic<=====>oa_reply:多对多
(二)Mybatis高级映射分析开发过程
Mybatis是持久层的应用框架,让程序员把经经历全部放在sql语句上,所以在开发过程中的步骤应该是:
1.写好数据库语句,获得想要的数据(哪几列)
2.写好与sql对应的pojo类(用来与sql语句完成映射关系)
3.写mapper.xml完成映射
4.完成接口mapper.java
pojo类如下
(Forum.java)
package com.mybatis.po;
import java.util.List;
/**
* Created by Administrator on 2018/3/30.
* 论坛主题分类
*/
public class Forum {
private long id;
private String name;
private String description;
private int position;
private int topicCount;
private int articleCount;
private long astTopicId;
private List<Topic> topicList;
public List<Topic> getTopicList() {
return topicList;
}
public void setTopicList(List<Topic> topicList) {
this.topicList = topicList;
}
@Override
public String toString() {
return "Forum{" +
"id=" + id +
", name='" + name + '\'' +
", description='" + description + '\'' +
", position=" + position +
", topicCount=" + topicCount +
", articleCount=" + articleCount +
", astTopicId=" + astTopicId +
'}';
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public int getTopicCount() {
return topicCount;
}
public void setTopicCount(int topicCount) {
this.topicCount = topicCount;
}
public int getArticleCount() {
return articleCount;
}
public void setArticleCount(int articleCount) {
this.articleCount = articleCount;
}
public long getAstTopicId() {
return astTopicId;
}
public void setAstTopicId(long astTopicId) {
this.astTopicId = astTopicId;
}
}
(Topic.java)
package com.mybatis.po;
import com.sun.org.apache.regexp.internal.RE;
import java.util.Date;
import java.util.List;
/**
* Created by Administrator on 2018/3/30.
* 发帖的标题
*/
public class Topic {
private long id;
private String title;
private String content;
private String faceIcon;
private Date postTime;
private String ipAddr;
private long authorId;
private int type;
private int replyCount;
private Date lastUpdateTime;
private long forumId;
private long lastReplyId;
private List<Reply> replyList;
private Forum forum;
@Override
public String toString() {
return "Topic{" +
"id=" + id +
", title='" + title + '\'' +
", content='" + content + '\'' +
", faceIcon='" + faceIcon + '\'' +
", postTime=" + postTime +
", ipAddr='" + ipAddr + '\'' +
", authorId=" + authorId +
", type=" + type +
", replyCount=" + replyCount +
", lastUpdateTime=" + lastUpdateTime +
", forumId=" + forumId +
", lastReplyId=" + lastReplyId +
'}';
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getFaceIcon() {
return faceIcon;
}
public void setFaceIcon(String faceIcon) {
this.faceIcon = faceIcon;
}
public Date getPostTime() {
return postTime;
}
public void setPostTime(Date postTime) {
this.postTime = postTime;
}
public String getIpAddr() {
return ipAddr;
}
public void setIpAddr(String ipAddr) {
this.ipAddr = ipAddr;
}
public long getAuthorId() {
return authorId;
}
public void setAuthorId(long authorId) {
this.authorId = authorId;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getReplyCount() {
return replyCount;
}
public void setReplyCount(int replyCount) {
this.replyCount = replyCount;
}
public Date getLastUpdateTime() {
return lastUpdateTime;
}
public void setLastUpdateTime(Date lastUpdateTime) {
this.lastUpdateTime = lastUpdateTime;
}
public long getForumId() {
return forumId;
}
public void setForumId(long forumId) {
this.forumId = forumId;
}
public long getLastReplyId() {
return lastReplyId;
}
public void setLastReplyId(long lastReplyId) {
this.lastReplyId = lastReplyId;
}
public Forum getForum() {
return forum;
}
public void setForum(Forum forum) {
this.forum = forum;
}
public List<Reply> getReplyList() {
return replyList;
}
public void setReplyList(List<Reply> replyList) {
this.replyList = replyList;
}
}
(Reply.java)
package com.mybatis.po;
import java.util.Date;
/**
* Created by Administrator on 2018/3/30.
* 帖子回复
*/
public class Reply {
private long id;
private String title;
private String content;
private String faceIcon;
private Date postTime;
private String ipAddr;
private long authorId;
private long topicId;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getFaceIcon() {
return faceIcon;
}
public void setFaceIcon(String faceIcon) {
this.faceIcon = faceIcon;
}
public Date getPostTime() {
return postTime;
}
public void setPostTime(Date postTime) {
this.postTime = postTime;
}
public String getIpAddr() {
return ipAddr;
}
public void setIpAddr(String ipAddr) {
this.ipAddr = ipAddr;
}
public long getAuthorId() {
return authorId;
}
public void setAuthorId(long authorId) {
this.authorId = authorId;
}
public long getTopicId() {
return topicId;
}
public void setTopicId(long topicId) {
this.topicId = topicId;
}
@Override
public String toString() {
return "Reply{" +
"id=" + id +
", title='" + title + '\'' +
", content='" + content + '\'' +
", faceIcon='" + faceIcon + '\'' +
", postTime=" + postTime +
", ipAddr='" + ipAddr + '\'' +
", authorId=" + authorId +
", topicId=" + topicId +
'}';
}
}
(三)实现
1.一对一映射
1.1使用resultTpye作为输出映射
!--查询发帖标题关联所属的分类-->
<select id="findTopicToForumById" parameterType="int" resultType="com.mybatis.po.TopicToForum">
SELECT oa_topic.*,oa_forum.name,oa_forum.description FROM oa_topic,oa_forum
WHERE oa_topic.forumId = oa_forum.id AND(oa_topic.id = #{id})
</select>
1.2使用resultMap作为输出映射
<!--查询发帖标题关联所属的分类的resultMap
将整个查询结果映射到com.mybatis.po.Topic中-->
<resultMap type="com.mybatis.po.Topic" id="topicToForumByIdResultMap" >
<!--配置要映射的发帖标题信息-->
<!--id:指定查询列中的唯一的标识,发帖标题信息的唯一标识,如果有多个列组成唯一标识,那么需要配置多个id-->
<!--column:唯一标识的列-->
<!--property:要映射到的com.mybatis.po.Topic中的哪一个属性-->
<id column="id" property="id"/>
<!--需要多少个result映射就写多少个-->
<result column="title" property="title"/>
<result column="content" property="content"/>
<!--配置要映射关联的所属分类的信息-->
<!--association:用于映射关联查询单个对象的查询信息-->
<!--property:要将关联查询的信息关联到com.mybatis.po.Topic的哪个属性-->
<!--javaType: 属性的类型-->
<association property="forum" javaType="com.mybatis.po.Forum" >
<!--id:关联查询到的所属分类的唯一标识-->
<!--column:用于指定标识所属分类的列-->
<!--javaType:映射到forum的哪个属性-->
<id column="forumId" property="id"/>
<result column="name" property="name"/>
<result column="description" property="description"/>
</association>
</resultMap>
<!--查询发帖标题关联所属的分类,使用resultMap-->
<select id="findTopicToForumByIdResultMap" parameterType="int" resultMap="topicToForumByIdResultMap">
SELECT oa_topic.*,oa_forum.name,oa_forum.description FROM oa_topic,oa_forum
WHERE oa_topic.forumId = oa_forum.id AND(oa_topic.id = #{id})
</select>
resultType:使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射。
如果没有查询结果的特殊要求建议使用resultType。
resultMap:需要单独定义resultMap,实现有点麻烦,如果对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo的属性中。
resultMap可以实现延迟加载,resultType无法实现延迟加载。
2.一对多映射
<!--查询查询分类下的发帖的resultMap
将整个查询结果映射到com.mybatis.po.Forum中-->
<resultMap type="com.mybatis.po.Forum" id="findForumToTopicByIdResultMap" >
<!--配置要映射的分类信息-->
<!--id:指定查询列中的唯一的标识,分类的唯一标识,如果有多个列组成唯一标识,那么需要配置多个id-->
<!--column:唯一标识的列-->
<!--property:要映射到的com.mybatis.po.Forum中的哪一个属性-->
<id column="forumId" property="id"/>
<!--需要多少个result映射就写多少个-->
<result column="name" property="name"/>
<!--配置要映射关联的所属发帖的信息-->
<!--collection:一个分类下查询出很多帖子,使用collection-->
<!--property:要将关联查询的信息关联到com.mybatis.po.Forum的哪个属性-->
<!--ofType: 要映射到集合属性中pojo的类型-->
<collection property="topicList" ofType="com.mybatis.po.Topic" >
<!--id:关联查询到的所属分类的唯一标识-->
<!--column:用于指定标识所属分类的列-->
<id column="id" property="id"/>
<result column="content" property="content"/>
</collection>
</resultMap>
<!--查询分类下的发帖-->
<select id="findForumToTopicById" resultMap="findForumToTopicByIdResultMap">
SELECT oa_forum.name,oa_topic.* FROM oa_forum,oa_topic
WHERE oa_forum.id = oa_topic.forumId
</select>
3.多对对映射
<!--查询发帖的回复resultMap
将整个查询结果映射到com.mybatis.po.Topic中-->
<resultMap type="com.mybatis.po.Topic" id="findTopicToReplyByIdResultMap" >
<!--配置要映射的分类信息-->
<!--id:指定查询列中的唯一的标识,分类的唯一标识,如果有多个列组成唯一标识,那么需要配置多个id-->
<!--column:唯一标识的列-->
<!--property:要映射到的com.mybatis.po.Topic中的哪一个属性-->
<id column="id" property="id"/>
<!--需要多少个result映射就写多少个-->
<result column="title" property="title"/>
<!--配置要映射关联的所属发帖的信息-->
<!--collection:发帖下查询出很多回复,使用collection-->
<!--property:要将关联查询的信息关联到com.mybatis.po.Reply的哪个属性-->
<!--ofType: 要映射到集合属性中pojo的类型-->
<collection property="replyList" ofType="com.mybatis.po.Reply" >
<!--id:关联查询到的所属分类的唯一标识-->
<!--column:用于指定标识所属分类的列-->
<id column="reply_id" property="id"/>
<result column="content" property="content"/>
</collection>
</resultMap>
<!--查询发帖的回复-->
<select id="findTopicToReply" parameterType="int" resultMap="findTopicToReplyByIdResultMap">
SELECT oa_topic.*,oa_reply.id reply_id,oa_reply.content FROM oa_topic,oa_reply
WHERE oa_topic.id = oa_reply.topicId
</select>
4.mapper.java(接口)
package com.mybatis.mapper;
import com.mybatis.po.*;
import java.util.List;
/**
* Created by Administrator on 2018/3/29.
* 通过发帖的标题来查找所属的分类
*/
public interface TopicToForumMapper {
// 查询发帖标题关联所属的分类
public TopicToForum findTopicToForumById(int id) throws Exception;
// 查询发帖标题关联所属的分类ResultMap查询
public Topic findTopicToForumByIdResultMap(int id) throws Exception;
// 查询分类下的发帖
public List<Forum> findForumToTopicById(int id) throws Exception;
// 查询发帖的回复
public List<Topic> findTopicToReply() throws Exception;
}
总结:
mybatis实际上完成的是sql代码映射,做什么样的映射取决于我们所获取到的列,对于一对多或是多对多的完成过程中mybatis在形成list的过程中由于我们在<collection><collection/>中配置了主键id,所以会去除重复多余的信息,一个id只生成了一个一条记录:
SELECT oa_forum.name,oa_topic.* FROM oa_forum,oa_topic
WHERE oa_forum.id = oa_topic.forumId AND (oa_forum.id=101)
resultMap总结:
resultType: 作用: 将查询结果按照sql列名pojo属性名一致性映射到pojo中。 场合: 常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list(list中是pojo)即可。
resultMap: 使用association和collection完成一对一和一对多高级映射(对结果有特殊的映射要求)。