用过hibernate的小伙伴都知道不管是采用注解仍是对象关系映射文件,都会把实体类的属性和数据表的列联系起来。好比说Student 就有一个Student.hbm.xml文件,这个对象关系映射文件有id 也有property等标签。这样就能很好的作到表和实体关联。java
MyBatis也须要进行表和实体 的关联。咱们查询的是表,返回的结果是实体类。这之间有一个对应关系。sql
若是说实体类的属性和表的列名一一对应,名字同样,那就自动解决了这个问题。可是若是实体类的属性和表的列名不一致,这就须要咱们手动的把它们关联起来。数据库
咱们查官方文档,能看到这样一个配置:是否开启驼峰命名规则,这个稍后再说。apache
先建立一个数据表booksession
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,这里我刻意的让实体类属性和表的列名不一致mybatis
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。app
我依旧采用xml和dao接口组合使用的方法进行数据表操做ide
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.xmlui
<?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。