我开始学习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列 :AUT_ID,名称,DESCRIPTION。
我成功地实现了realAll()和findByName()方法,但我对插入过程并不满意。
是否有嵌套插入?如何在xml中配置插入配置以接受书中的作者列表?
答案 0 :(得分:0)
您可以使用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>
请注意,您的作者类中没有描述字段,因此您需要在其中指定正确的值,而且我也不知道作者标识符的序列名称是什么,因此,这是用于说明此想法的草案。 / p>
或者,您可以遍历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
方法。