MyBatis也需要进行表和实体 的关联。我们查询的是表,返回的结果是实体类。这之间有一个对应关系。
如果说实体类的属性和表的列名一一对应,名字一样,那就自动解决了这个问题。但是如果实体类的属性和表的列名不一致,这就需要我们手动的把它们关联起来。

先创建一个数据表book
create table book(
book_id int not null auto_increment COMMENT '书籍ID',
book_name varchar(120) not null COMMENT '书籍名称',
primary key(book_id)
)ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT '书籍';
insert into book(book_name) values('冰与火之歌');
再创建一个实体类Book,这里我刻意的让实体类属性和表的列名不一致
package com.zhao.entity;
public class Book {
private int id;
private String bookName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
@Override
public String toString() {
return "Book [id=" + id + ", bookName=" + bookName + "]";
}
}
现在能看到 表book 列 book_id book_name; 实体类Book 属性 id bookName。
我依旧采用xml和dao接口组合使用的方法进行数据表操作
package com.zhao.dao;
import com.zhao.entity.Book;
public interface BookDao {
/*
* 插入书籍信息
*/
public int insertBook(Book book);
/*
* 根据Id查询Book信息
*/
public Book queryById(int id);
}
在接口中我们定义了两个方法,一个插入 一个查询。
接下来看BookDao.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.zhao.dao.BookDao">
<insert id="insertBook" parameterType="Book">
insert into
book(book_name) values(#{bookName})
</insert>
<select id="queryById" resultType="Book">
select * from book where book_id=#{id}
</select>
</mapper>
现在进行简答的测试
package com.zhao.dao;
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.zhao.entity.Book;
public class BookDaoTest {
private String resource = "mybatis-config.xml";
private Reader reader;
private SqlSessionFactory sqlSessionFactory;
private SqlSession sqlSession;
private BookDao bookDao;
@Before
public void before() throws IOException {
reader = Resources.getResourceAsReader(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
sqlSession = sqlSessionFactory.openSession();
bookDao=(BookDao)sqlSession.getMapper(BookDao.class);
}
@After
public void after() {
sqlSession.close();
}
@Test
public void testInsertBook() {
Book book=new Book();
book.setBookName("冰与火之歌");
int insertCount=bookDao.insertBook(book);
//一定要记得提交 事务
sqlSession.commit();
System.out.println("InsertCount: "+insertCount);
}
@Test
public void testQueryById() {
Book book=bookDao.queryById(3);
System.out.println(book);
}
}
测试结果

思路特别简单,就是把从数据表book查到结果赋给Book对象。程序运行没有报错,结果不正确只是因为数据表和实体类没有进行关联。实际上我们已经从表中查出了数据,只是在赋给Book这一步失败了。
解决办法:
1:给数据表的列定义别名
修改BookDao.xml
<select id="queryById" resultType="Book">
select book_id as id, book_name as bookName from book where book_id=#{id}
</select>
把刚才的select * 进行了修改,把结果增加了别名。这个别名对应着Book的属性。
查看结果

2:resultMap手动配置关联
我们的目的依旧是把表的列和实体类的属性进行关联,上面也提到hibernate的对象关系映射,其实mybatis的配置resultMap和hibernate的对象关系映射很相似。
修改BookDao.xml
<select id="queryById" resultMap="BookResultMap">
select * from book where book_id=#{id}
</select>
<resultMap type="Book" id="BookResultMap">
<id property="id" column="book_id"/>
<result property="bookName" column="book_name"/>
</resultMap>
只用select * 肯定是失败的。但是我们可以配置实体类的属性和数据表的列之间的一一对应关系。
查询结果

3:用了上面两种方法,我觉得还是有点繁琐。有没有更简单的方法 ,有。
就用上面提到的是否开启驼峰规则。
一般情况下,数据库表的列是以 A_column的格式定义的,而实体类的属性是以aColumn的格式定义的。就像上面用到的
book_name和bookName。
这两天我整理的xml和dao层组合使用进行mybatis操作,并没有使用上面所说的定义别名或者定义resultMap。而是使用了开启驼峰规则。
在mybatis-config.xml中
<settings>
<setting name="mapUnderscoreToCamelCase" value="true" />
<setting name="useGeneratedKeys" value="true" />
</settings>
当然,在设计表和创建实体类的时候,还要注意book_name 和 bookName这种对应关系。
其实,开启驼峰规则的本质还是给表定义了别名。不过这种别名是有规范的,book_name的别名就说bookName。
浙公网安备 33010602011771号