MyBatis表和實體關聯

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

相關文章
相關標籤/搜索