用過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。