MyBatis表和實體關聯


  用過hibernate的小伙伴都知道無論是采用注解還是對象關系映射文件,都會把實體類的屬性和數據表的列聯系起來。比如說Student 就有一個Student.hbm.xml文件,這個對象關系映射文件有id 也有property等標簽。這樣就能很好的做到表和實體關聯。

  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。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM