如何配置xml映射器以插入mybatis中具有collection属性的实体



我开始学习myBatis的概念,并试图在xml中制作一个简单的(或不是那么简单的(插入配置。我有一个java应用程序,它可以根据数据库读取、插入和更新一些书籍。与数据库连接的xml配置已经完成。

在java中,我有两个简单的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);
}
}

在数据库中,我有两个不同的表:-"TAB_PRODUCTS"表,我在其中保存有关这本书的信息,共有3列:PROD_ID、NAME、DESCRIPTION,-"TAB_AUTHORS"表,我在其中保存有关作者的信息,有3个col:AUT_ID,NAME,DESCRIPTION。

我成功地实现了realAll((和findByName((方法,我不适合插入过程。

是否有嵌套插入?如何配置xml中的insert confoguration以接受书中的作者列表?

您可以使用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>

请注意,author类中没有描述字段,因此需要在其中指定正确的值,而且我不知道author标识符的序列名是什么,所以这是一个说明这一想法的草案。

或者,您可以迭代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方法。

最新更新