簡體   English   中英

如何配置xml映射器以在mybatis中插入具有collection屬性的實體

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM