[英]How to configure xml mapper to insert entity with collection property in mybatis
我開始學習myBatis概念,並嘗試在xml中進行簡單(或不那么簡單)的插入配置。 我有一個Java應用程序,可以針對數據庫讀取,插入和更新一些書。 與數據庫連接的xml配置已經完成。
在Java中,我有2個簡單的Pojo:
public class Book {
private Long id;
private String name;
private List<Author> authors;
private String desc;
public Book() {
//Default Constructor
}
//constructors that takes args, setters & getters
}
和
public class Author {
private String authorName;
public Author() {
// Default Constructor
}
public Author(String authorName) {
this.authorName = authorName;
}
public String getAuthorName() {
return authorName;
}
public void setAuthorName(String authorName) {
this.authorName = authorName;
}
}
這是查詢的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.kepler.learning.mybooks.dao.BookDao"> <resultMap id="BookResult" type="Book"> <id property="id" column="id"></id> <result property="name" column="name"></result> <result property="desc" column="desc"></result> <collection property="authors" ofType="Author"> <result property="authorName" column="authorName"></result> </collection> </resultMap> <select id="readAll" resultMap="BookResult"> SELECT b.prod_id "id", b.name, a.name "authorName", b.description "desc" FROM tab_products b left outer join tab_authors a on b.PROD_ID = a.AUT_ID </select> <select id="findByName" parameterType="String" resultMap="BookResult"> SELECT b.prod_id "id", b.name, a.name "authorName", b.description "desc" FROM tab_products b left outer join tab_authors a on b.PROD_ID = a.AUT_ID WHERE b.name = #{name} </select> <insert id="insert" parameterType="Book"> INSERT INTO tab_products(prod_id,name,description) VALUES(SEQ_PRD_ID.nextVal,#{name},#{desc}); </insert> </mapper>
我還有一個名為DBBookDao的類,該類實現所有適當的方法,例如“ read all”,“ findByName”,“ insert”:
public class DBBookDao implements BookDao{
private String resource = "mybatis.config.xml";
private InputStream inputStream;
private SqlSession sqlSession;
private SqlSessionFactory sqlSessionFactory;
public DBBookDao() {
try {
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
throw new BusinessException(e);
}
}
public List<Book> readAll() {
try {
sqlSession = sqlSessionFactory.openSession();
return sqlSession.selectList("com.kepler.learning.mybooks.dao.BookDao.readAll");
} finally {
sqlSession.close();
}
}
public Book findByName(String name) {
if (name == null) {
throw new BusinessException("No book name provided!");
}
try {
sqlSession = sqlSessionFactory.openSession();
List<Book> books = sqlSession.selectList("com.kepler.learning.mybooks.dao.BookDao.findByName", name);
return Optional.ofNullable(books).map(list -> list.get(0)).orElse(null);
}
finally {
sqlSession.close();
}
}
public boolean checkBookExists(Book book) {
List<Book> allBooks = readAll();
for(Book b : allBooks) {
if(b.getName().equals(book.getName())) {
return true;
}
}
return false;
}
public void insert(Book book) {
sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("com.kepler.learning.mybooks.dao.BookDao.insert",book);
}
}
在數據庫中,我有2個不同的表:-“ TAB_PRODUCTS”表用於保存有關書的信息,並帶有3列:PROD_ID,NAME,DESCRIPTION--“ TAB_AUTHORS”表用於保存有關作者的信息,其中3 col:AUT_ID,名稱,DESCRIPTION。
我成功地實現了realAll()和findByName()方法,我對插入過程不滿意。
有嵌套的插入物嗎? 如何在xml中配置插入配置以接受書中的作者列表?
您可以使用foreach
元素生成插入語句,如下所示:
<insert id="insert" parameterType="Book">
INSERT INTO tab_products(prod_id,name,description)
VALUES(SEQ_PRD_ID.nextVal,#{name},#{desc});
<foreach collection="authors" item="author" index="index">
INSERT INTO tab_authors(aut_id,name,description)
VALUES(SEQ_AUT_ID.nextVal,#{author.authorName},#{author.whateverDescProperty});
</foreach>
</insert>
請注意,您的作者類中沒有描述字段,因此您需要在其中指定正確的值,而且我也不知道作者標識符的序列名稱是什么,因此,這是用於說明此想法的草稿。
或者,您可以遍歷DAO中的作者列表:
public void insert(Book book) {
sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("com.kepler.learning.mybooks.dao.BookDao.insert",book);
for(Author author:book.getAuthors()) {
sqlSession.insert(
"com.kepler.learning.mybooks.dao.BookDao.insertAuthor",
author);
}
}
您將需要創建一個映射器方法insertAuthor
(或為作者提供另一個映射器)。
旁注 :不要像在checkBookExists
那樣通過查詢數據庫中的所有對象來檢查是否存在一個元素。 而是基於findByName
方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.