MyBatis表和实体关联

Posted 假寐的我

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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。

 

以上是关于MyBatis表和实体关联的主要内容,如果未能解决你的问题,请参考以下文章

Mybatis--02

不会还有人不知道mybatis的关联查询吧?

MyBatis关联映射

Mybatis关联映射

mybatis中映射文件和实体类的关联性

MyBatis之关联关系