MyBatis由浅入深学习总结之二:MyBatis解决Java实体类和数据库表字段不一致方法总结
在此,首先说明一点任何持久性框架都需要解决一个问题,那就是Java实体类的字段一般来说基本上会与数据库表中字段不一致,那么它们是如何解决的呢?咱们以Hibernate和SpringJDBC为例说明一下;
1、Hibernate中一般通过XML映射和注解的方式解决不一致问题,看下面两个简单例子,
注解方式:
- @Entity
- @Table(name = "ACCOUNT")
- public class Account implements Serializable {
- private static final long serialVersionUID = 1L;
- @Id
- @GeneratedValue
- private int id;
- @Column(name="fld_number")
- private String number;
- @OneToMany(mappedBy="account")
- private Set<Client> clients;
- private double balance;
- }
- <?xml version="1.0"?>
- <!DOCTYPE hibernate-mapping PUBLIC
- "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <class name="org.hibernate.test.domain.Account" table="ACCOUNT" lazy="false">
- <id name="id" column="ACCOUNT_ID">
- <generator class="native"/>
- </id>
- <many-to-one name="person" class="org.hibernate.test.domain.Person" cascade="save-update,lock"
- column="person_id"
- unique="true"
- not-null="true"/>
- </class>
- </hibernate-mapping>
好的,了解完上述两种方式,咱们再来看看对于同样的问题,MyBatis是如何处理的?
对于这种问题,MyBatis主要提供了两种方式用来解决该问题;
一、通过对查询SQL采用字段别名的方式
1、新建表和插入数据
- DROP TABLE IF EXISTS `sl_company`;
- CREATE TABLE `sl_company` (
- `company_id` int(11) NOT NULL AUTO_INCREMENT,
- `company_name` varchar(50) DEFAULT NULL,
- `full_name` varchar(100) DEFAULT NULL,
- `address` varchar(100) DEFAULT NULL,
- `post_code` varchar(45) DEFAULT NULL,
- PRIMARY KEY (`company_id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
- -- ----------------------------
- -- Records of sl_company
- -- ----------------------------
- INSERT INTO `sl_company` VALUES ('1', '锐客科技', '上海锐客科技股份有限公司', '上海市浦东新区峨山路91弄97号陆家嘴软件园5号楼3层', '200127');
- package com.mybatis.entity;
- import java.io.Serializable;
- public class SlCompany implements Serializable {
- private static final long serialVersionUID = 1L;
- private int companyId;
- private String companyName;
- private String fullName;
- private String address;
- private String postCode;
- public SlCompany() {
- super();
- }
- public int getCompanyId() {
- return companyId;
- }
- public void setCompanyId(int companyId) {
- this.companyId = companyId;
- }
- public String getCompanyName() {
- return companyName;
- }
- public void setCompanyName(String companyName) {
- this.companyName = companyName;
- }
- public String getFullName() {
- return fullName;
- }
- public void setFullName(String fullName) {
- this.fullName = fullName;
- }
- public String getAddress() {
- return address;
- }
- public void setAddress(String address) {
- this.address = address;
- }
- public String getPostCode() {
- return postCode;
- }
- public void setPostCode(String postCode) {
- this.postCode = postCode;
- }
- }
- <?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.mybatis.mappings.slCompanyMapper">
- <!-- 通过使用字段别名的方式,AS关键字前面的是数据库表的字段名,后面对应的Java实体类对应的属性名称 -->
- <select id="getSlCompany" parameterType="int"
- resultType="com.mybatis.entity.SlCompany">
- SELECT company_id AS companyId,company_name AS
- companyName,full_name AS fullName, post_code AS postCode, address FROM
- sl_company WHERE company_id=#{id}
- </select>
- </mapper>
- <?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.mybatis.mappings.slCompanyMapper">
- <!-- 通过使用字段别名的方式,AS关键字前面的是数据库表的字段名,后面对应的Java实体类对应的属性名称 -->
- <!-- SlCompany字段映射列表 -->
- <sql id="getSlCompanyColumns">
- company_id AS companyId,
- company_name AS companyName,
- full_name AS fullName,
- post_code AS postCode,
- address
- </sql>
- <!-- 通过使用include元素的refid属性引入上面自定义的映射列表 -->
- <select id="getSlCompany" parameterType="int" resultType="com.mybatis.entity.SlCompany">
- SELECT <include refid="getSlCompanyColumns"/> FROM sl_company WHERE company_id=#{id}
- </select>
- </mapper>
1、表结构与java实体类同上,不在赘述。
2、下面来看看映射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.mybatis.mappings.slCompanyMapper">
- <!-- 通过使用结果映射的方式 -->
- <select id="getSlCompany2" parameterType="int" resultMap="slCompanyResultMap">
- SELECT * FROM sl_company WHERE company_id=#{id}
- </select>
- <!-- 通过使用resultMap元素自定义结果映射,该元素内部的id和result提供了javaType、jdbcType、typeHandler属性满足类型要求 -->
- <resultMap type="com.mybatis.entity.SlCompany" id="slCompanyResultMap">
- <!-- 通过id元素映射主键类型 -->
- <id column="company_id" property="companyId" />
- <!-- 通过result元素映射非主键类型 -->
- <result column="company_name" property="companyName"/>
- <result column="full_name" property="fullName"/>
- <!-- 当字段名和属性名一致是,可写可不写 -->
- <result column="address" property="address"/>
- <result column="post_code" property="postCode"/>
- </resultMap>
- </mapper>
- package com.mybatis.test;
- import java.io.IOException;
- import java.io.InputStream;
- 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 com.mybatis.entity.SlCompany;
- public class MyBatisTest {
- public static void main(String[] args) throws IOException {
- // mybatis提供了Resources类用来提供简易方式来获取各种来源的资源文件信息
- // 获取mybatis.xml的字节流
- InputStream is = Resources.getResourceAsStream("mybatis.xml");
- // 获取mybatis.xml的字符流
- //Reader reader = Resources.getResourceAsReader("mybatis.xml");
- // 构建SqlSessionFactory对象,传入字符流或字节流均可
- SqlSessionFactory SqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
- // 获取SqlSession对象
- SqlSession sqlSession = SqlSessionFactory.openSession();
- // 执行查询操作
- // selectOne()方法的第一个参数是由slCompanyMapper.xml里配置的mapper的namespace属性 + 该mapper下select元素的id属性值组成的
- SlCompany slCompany = sqlSession.selectOne("com.mybatis.mappings.slCompanyMapper.getSlCompany2", 1);
- // 用完SqlSession之后,不要忘记关闭
- sqlSession.close();
- System.out.println(slCompany.getAddress());
- }
- }
总结:无论上述哪一种方式都提供了一种解决不一致的途径,需要注意它俩的不同点;
第一种方式直接在查询SQL语句下手,通过采用别名的方式,也就是说这种方式在得到查询结果集之前就搞定了不一致问题,获取到了跟属性名称一致的结果集;
第二种方式是在获取结果集之后,对结果集下手;
博文转自:http://blog.****.net/yu102655/article/details/52437455