MyBatis表關聯 一對多 多對一 多對多
在上一篇文章中,我們已經搭建了eclipse,mybatis,mysql 的開發環境,並且實現了 mybatis 的簡單的增刪改查功能。參考文章
有了上一篇文章的基礎,可以處理一些簡單的應用,但在實際專案中,經常是關聯表的查詢。比如:最常見到的多對一,一對多等。
1. Mybatis表關聯一對多
在Java實體物件對中,一對多可以根據List和Set來實現,兩者在mybitis中都是通過collection標籤來配合來加以實現。這篇介紹的是多表中的多對一表關聯查詢。
應用場景:首先根據文章 ID 讀取一篇文章資訊,然後再讀取這篇文章的評論。
1.1 準備表和資料
CREATE TABLE `article` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL DEFAULT '',
`content` text,
`created` datetime NOT NULL DEFAULT '2018-09-10 00:00:00',
PRIMARY KEY (`id`)
);
INSERT INTO `article` VALUES ('1', 'MyBatis詳解', 'MyBatis詳解。。。', '2018-09-10 20:11:23');
CREATE TABLE `comment` (
`cid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`aid` int(10) unsigned NOT NULL,
`commentcontent` varchar(254) NOT NULL DEFAULT '',
`postedby` varchar(20) NOT NULL DEFAULT '',
`created` datetime NOT NULL DEFAULT '2018-09-10 00:00:00',
PRIMARY KEY (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
INSERT INTO `comment` VALUES ('1', '1', 'MyBatis詳解這篇文章寫的真好', 'Angelia的頭號粉絲', '2018-09-10 21:40:17');
INSERT INTO `comment` VALUES ('2', '1', 'MyBatis詳解這篇文章寫的簡直是太好了', 'Angelia的二號粉絲', '2018-09-10 21:40:17');
INSERT INTO `comment` VALUES ('3', '1', 'MyBatis詳解這篇文章寫的不能再好了', 'Angelia的三號粉絲', '2018-09-10 21:40:17');
1.2 建立表對應的 JavaBean 物件
public class Article {
private int id;
private String title;
private String content;
private List<Comment> comments;
// getters and setters
}
public class Comment {
private int id;
private String commentcontent;
private String postedBy;
private Article article;
// getters and setters
}
1.3 介面IArticle和對映檔案Article.xml
public interface IArticle {
public Article getArticle(int id);
}
<mapper namespace="com.angelia.mybatis.dao.IArticle">
<resultMap id="articleMap" type="Article" >
<id column="id" property="id" />
<!-- <result property="id" column="id" /> -->
<result property="title" column="title" />
<result property="content" column="content" />
</resultMap>
<!-- Article級聯評論查詢 方法配置 (一篇文章對多個評論) -->
<resultMap id="articleCommentMap" type="Article" extends="articleMap">
<collection property="comments" ofType="com.angelia.mybatis.model.Comment" column="aid">
<id property="id" column="cid" javaType="int" jdbcType="INTEGER" />
<result property="commentcontent" column="commentcontent" javaType="string" jdbcType="VARCHAR" />
<result property="postedBy" column="postedBy" javaType="string" jdbcType="VARCHAR" />
</collection>
</resultMap>
<select id="getArticle" resultMap="articleCommentMap" parameterType="int">
SELECT a.*, c.*
FROM article a, comment c
WHERE a.id = c.aid AND id = #{aid}
</select>
</mapper>
1.4 測試類
@Test
public void test() {
Article article = articleMapper.getArticle(1);
System.out.println("Article: " + article);
List<Comment> comments = article.getComments();
for(Comment comment : comments) {
System.out.println("Comment Content:" + comment.getCommentcontent());
System.out.println("Content Posted By:" + comment.getPostedBy());
}
}
2. Mybatis表關聯多對一
在上章的一對多中,我們已經學習如何在 Mybatis 中關聯多表,但在實際專案中也是經常使用多對一的情況,在這一節中我們來學習如何處理多對一。多表對映的多對一關係要用到 mybitis 的 association 來加以實現。
應用場景:首先根據帖子 ID 讀取一個帖子資訊,然後再讀取這個帖子所屬的使用者資訊。
2.1 建立介面IComment和對映檔案Comment.xml
public interface IComment {
public Comment getComment(int cid);
}
<mapper namespace="com.angelia.mybatis.dao.IComment">
<resultMap id="commentMap" type="Comment">
<id property="id" column="cid" />
<result property="commentcontent" column="commentcontent" />
<result property="postedBy" column="postedBy" />
</resultMap>
<resultMap id="commentArticleMap" type="Comment" extends="commentMap">
<association property="article" javaType="Article">
<id property="id" column="aid" />
<result property="title" column="title" />
<result property="content" column="content" />
</association>
</resultMap>
<!-- <resultMap id="commentArticleMap" type="Comment" >
<result property="id" column="cid" />
<result property="commentcontent" column="commentcontent" />
<result property="postedBy" column="postedBy" />
<association property="article" javaType="Article">
<id property="id" column="aid" />
<result property="title" column="title" />
<result property="content" column="content" />
</association>
</resultMap> -->
<select id="getComment" resultMap="commentArticleMap" parameterType="int">
SELECT a.*, c.*
FROM article a, comment c
WHERE a.id = c.aid AND c.cid = #{cid}
</select>
</mapper>
2.2 測試程式碼
@Test
public void test() {
Comment comment = commentMapper.getComment(1);
System.out.println("Comment Content:" + comment.getCommentcontent());
System.out.println("Content Posted By:" + comment.getPostedBy());
System.out.println("Article : " + comment.getArticle());
}
3. Mybatis 多對多
Mybatis3.0新增了association和collection標籤專門用於對多個相關實體類資料進行級聯查詢,但仍不支援多個相關實體類資料的級聯儲存和級聯刪除操作。因此在進行實體類多對多對映表設計時,需要專門建立一個關聯物件類對相關實體類的關聯關係進行描述。下文將以“Author”和“Paper”兩個實體類之間的多對多關聯對映為例進行CRUD操作。
應用場景:假設專案中存在作者和論文,從一個作者讀取出它所關聯的論文,從一篇論文也知道這篇論文的所有作者資訊。
3.1 準備表結構和資料
CREATE TABLE `author` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`author_name` varchar(64) NOT NULL DEFAULT '',
`mobile` varchar(16) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of author
-- ----------------------------
INSERT INTO `author` VALUES ('1', 'Angelia', '13888888888');
INSERT INTO `author` VALUES ('2', 'Snowdrop', '13666666666');
CREATE TABLE `paper` (
`paper_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`paper_title` varchar(100) NOT NULL DEFAULT '',
`paper_content` text,
PRIMARY KEY (`paper_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of paper
-- ----------------------------
INSERT INTO `paper` VALUES ('1', 'MyBatis詳解 表關聯多對一', '多對一具體詳解');
INSERT INTO `paper` VALUES ('2', 'MyBatis詳解 表關聯一對多', '一對多具體詳解');
INSERT INTO `paper` VALUES ('3', 'MyBatis詳解 表關聯多對多', '多對多具體詳解');
CREATE TABLE `author_paper` (
`author_id` int(10) unsigned NOT NULL DEFAULT '0',
`paper_id` int(10) unsigned NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user_group
-- ----------------------------
INSERT INTO `author_paper` VALUES ('1', '1');
INSERT INTO `author_paper` VALUES ('2', '1');
INSERT INTO `author_paper` VALUES ('1', '2');
INSERT INTO `author_paper` VALUES ('2', '3');
3.2 建立表對應的JavaBean 物件
public class Author {
private int id;
private String authorName;
private String mobile;
private List<Paper> papers;
// getters and setters
}
public class Paper {
private int paperId;
private String title;
private String content;
private List<Author> authors;
// getters and setters
}
public class AuthorPaper {
private int authorId;
private int paperId;
// getters and setters
}
3.3 建立介面和對映檔案Author.xml,Paper.xml和AuthorPaper.xml
public interface IAuthor {
public Author getAuthor(int authorId);
public void insertAuthor(Author author);
}
public interface IPaper {
public Paper getPaper(int paperId);
public void insertPaper(Paper paper);
}
public interface IAuthorPaper {
public List<Author> getAuthorsByPaperId(int paperId);
public List<Paper> getPapersByAuthorId(int id);
public void insertAuthorPaper(AuthorPaper authorPaper);
}
<mapper namespace="com.angelia.mybatis.dao.IAuthor">
<parameterMap type="Author" id="parameterAuthorMap">
<parameter property="id"/>
<parameter property="authorName"/>
<parameter property="mobile"/>
</parameterMap>
<insert id="insertAuthor" parameterMap="parameterAuthorMap">
INSERT INTO author(author_name, mobile) VALUES(#{authorName}, #{mobile});
</insert>
<resultMap id="resultAuthorMap" type="Author" >
<result property="id" column="id"/>
<result property="authorName" column="author_name"/>
<result property="mobile" column="mobile"/>
<collection property="papers" column="id" select="com.angelia.mybatis.dao.IAuthorPaper.getPapersByAuthorId"/>
</resultMap>
<select id="getAuthor" resultMap="resultAuthorMap" parameterType="int">
SELECT * FROM author WHERE id = #{id}
</select>
</mapper>
<mapper namespace="com.angelia.mybatis.dao.IPaper">
<parameterMap id="parameterPaperMap" type="Paper">
<parameter property="paperId" />
<parameter property="title" />
<parameter property="content" />
</parameterMap>
<insert id="insertPaper" parameterMap="parameterPaperMap">
INSERT INTO `paper`(paper_title, paper_content) VALUES(#{title}, #{content});
</insert>
<resultMap id="resultPaperMap" type="Paper">
<id property="paperId" column="paper_id" />
<result property="title" column="paper_title" />
<result property="content" column="paper_content" />
<collection property="authors" column="paper_id" select="com.angelia.mybatis.dao.IAuthorPaper.getAuthorsByPaperId" />
</resultMap>
<select id="getPaper" resultMap="resultPaperMap" parameterType="int">
SELECT * FROM `paper` WHERE paper_id = #{paperId}
</select>
</mapper>
<mapper namespace="com.angelia.mybatis.dao.IAuthorPaper">
<parameterMap type="AuthorPaper" id="parameterAuthorPaperMap">
<parameter property="authorId"/>
<parameter property="paperId"/>
</parameterMap>
<insert id="insertAuthorPaper" parameterMap="parameterAuthorPaperMap">
INSERT INTO author_paper(author_id, paper_id) VALUES(#{authorId}, #{paperId})
</insert>
<!-- 根據一篇論文的ID,檢視這篇論文的的所有作者 -->
<resultMap id="resultAuthorMap2" type="Author" >
<result property="id" column="id"/>
<result property="authorName" column="author_name"/>
<result property="mobile" column="mobile"/>
</resultMap>
<select id="getAuthorsByPaperId" resultMap="resultAuthorMap2" parameterType="int">
SELECT a.*, ap.paper_id
FROM author a, author_paper ap
WHERE a.id=ap.author_id AND ap.paper_id = #{paperId}
</select>
<!-- 根據一個作者ID,檢視這個作者所有論文-->
<resultMap id="resultPaperMap2" type="Paper" >
<result property="paperId" column="paper_id"/>
<result property="title" column="paper_title"/>
<result property="content" column="paper_content"/>
</resultMap>
<select id="getPapersByAuthorId" resultMap="resultPaperMap2" parameterType="int">
SELECT p.*, ap.author_id
FROM paper p, author_paper ap
WHERE p.paper_id = ap.paper_id AND ap.author_id = #{id}
</select>
</mapper>
3.4 建立測試類
public class AuthorPaperTest {
private SqlSession session;
private IAuthorPaper authorPaperMapper;
private IAuthor authorMapper;
private IPaper paperMapper;
@Before
public void before() {
session = MyBatisUtil.getSessionFactory().openSession();
// 獲取Mapper
authorPaperMapper = session.getMapper(IAuthorPaper.class);
authorMapper = session.getMapper(IAuthor.class);
paperMapper = session.getMapper(IPaper.class);
}
@After
public void after() {
session.close();
}
@Test
public void test() {
//getAuthorsByPaperId(1);
//getPapersByAuthorId(1);
//getAuthorAndPapers(2);
getAuthorAndPapers(2);
/*Author author = new Author();
author.setAuthorName("優雅的作家Angelia");
author.setMobile("13666666666");
saveAuthor(author);
Paper paper = new Paper();
paper.setTitle("MyBatis從入門到精通");
paper.setContent("MyBatis從入門到精通...");
savePaper(paper);*/
/*AuthorPaper ap = new AuthorPaper();
ap.setAuthorId(4);
ap.setPaperId(4);
saveAuthorPaper(ap);*/
}
public void getAuthorsByPaperId(int paperId) {
List<Author> authors = authorPaperMapper.getAuthorsByPaperId(paperId);
for (Author author : authors) {
System.out.println(author);
}
}
public void getPapersByAuthorId(int id) {
List<Paper> papers = authorPaperMapper.getPapersByAuthorId(id);
for (Paper paper : papers) {
System.out.println(paper);
}
}
public void getPaperAndAuthors(int paperId) {
Paper paper = paperMapper.getPaper(paperId);
System.out.println(paper);
List<Author> authors = paper.getAuthors();
for (Author author : authors) {
System.out.println(author);
}
}
public void getAuthorAndPapers(int authorId) {
Author author = authorMapper.getAuthor(authorId);
System.out.println(author);
List<Paper> papers = author.getPapers();
for (Paper paper : papers) {
System.out.println(paper);
}
}
public void saveAuthorPaper(AuthorPaper authorPaper) {
authorPaperMapper.insertAuthorPaper(authorPaper);
session.commit();
}
public void saveAuthor(Author author) {
authorMapper.insertAuthor(author);
session.commit();
}
public void savePaper(Paper paper) {
paperMapper.insertPaper(paper);
session.commit();
}
}
相關文章
- JPA(3) 表關聯關係(多對一、一對多、多對多、一對一)
- Mybatis【一對多、多對一、多對多】知識要點MyBatis
- spring data jpa關聯查詢(一對一、一對多、多對多)Spring
- mybatis一對多&&多對一處理MyBatis
- MyBatis07-(多對一、一對多)MyBatis
- Mybatis一對多、多對一處理MyBatis
- mybatis的一對多,多對一,以及多對對的配置和使用MyBatis
- Mybatis09_一對一、一對多、多對多、延遲載入MyBatis
- gorm 關係一對一,一對多,多對多查詢GoORM
- Spring Data JPA 之 一對一,一對多,多對多 關係對映Spring
- 模型關聯一對多模型
- JPA中對映關係詳細說明(一對多,多對一,一對一、多對多)、@JoinColumn、mappedBy說明APP
- Laravel多對多模型關聯Laravel模型
- MyBatis加強(1)~myBatis物件關係對映(多對一關係、一對多關係)、延遲/懶載入MyBatis物件
- laravel 多對多關聯刪除中間表Laravel
- Spring Boot 入門系列(二十八) JPA 的實體對映關係,一對一,一對多,多對多關係對映!Spring Boot
- MyBatis 使用resultMap 以及 一對一和一對多MyBatis
- #MyBatis多表查詢 #多對一、一對多的兩種實現方式 @FDDLCMyBatis
- Laravel 多對多關聯模型 CURD 詳解Laravel模型
- spring data jpa 多對一聯表查詢Spring
- Rails 一對多AI
- MyBatis初級實戰之六:一對多關聯查詢MyBatis
- JavaEE MyBatis關聯對映之多對多(教材學習筆記)JavaMyBatis筆記
- Spring Boot整合Mybatis完成級聯一對多CRUD操作Spring BootMyBatis
- 多對一處理 和一對多處理的處理
- 多對多關聯 attach() 相同的資料包錯
- hibernate一對多、多對多的實體設計和配置檔案配置
- springDataJpa聯表查詢之多對多Spring
- 在 CSDN 上面看到的一篇關於 Laravel 關聯表模型和多對多關係的文章Laravel模型
- 為什麼反向關聯 一對一和一對多都是同一個方法
- spring-data-jpa一對多、多對多雙向關聯,查詢操作的時候進入死迴圈問題Spring
- DcatAdmin 多對多關聯是,multipleSelect 報錯 Array to string conversion
- jpa一對多查詢
- 6.Hibernate多對多關係建立
- Mybatis plus 一對多關聯查詢分頁不準確的問題MyBatis
- [增刪改查] 最規範的 JPA 一對多/多對一 CRUD 示例
- 多對多關聯的時候,怎麼返回中間表的資料集合
- hibernate中多對多關係的維護