MyBatis由浅入深学习总结之二:MyBatis解决Java实体类和数据库表字段不一致方法总结

在此,首先说明一点任何持久性框架都需要解决一个问题,那就是Java实体类的字段一般来说基本上会与数据库表中字段不一致,那么它们是如何解决的呢?咱们以Hibernate和SpringJDBC为例说明一下;

1、Hibernate中一般通过XML映射和注解的方式解决不一致问题,看下面两个简单例子,

注解方式:

[java] view plain copy
  1. @Entity  
  2. @Table(name = "ACCOUNT")  
  3. public class Account implements Serializable {  
  4.     private static final long serialVersionUID = 1L;  
  5.   
  6.     @Id  
  7.     @GeneratedValue  
  8.     private int id;  
  9.   
  10.     @Column(name="fld_number")  
  11.     private String number;  
  12.       
  13.     @OneToMany(mappedBy="account")  
  14.     private Set<Client> clients;  
  15.       
  16.     private double balance;  
  17.   
  18. }  
XML映射文件配置方式:

[html] view plain copy
  1. <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC  
  3.         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  5.   
  6. <hibernate-mapping>  
  7.   
  8.     <class name="org.hibernate.test.domain.Account" table="ACCOUNT" lazy="false">  
  9.         <id name="id" column="ACCOUNT_ID">  
  10.             <generator class="native"/>  
  11.         </id>  
  12.   
  13.         <many-to-one name="person" class="org.hibernate.test.domain.Person" cascade="save-update,lock"  
  14.                      column="person_id"  
  15.                      unique="true"  
  16.                      not-null="true"/>  
  17.     </class>  
  18.   
  19. </hibernate-mapping>  
2、Spring JDBC一般通过使用RowCallbackHandler和RowMapper,编写回调函数的方式处理不一致,各种方法如下所示:

MyBatis由浅入深学习总结之二:MyBatis解决Java实体类和数据库表字段不一致方法总结
好的,了解完上述两种方式,咱们再来看看对于同样的问题,MyBatis是如何处理的?

对于这种问题,MyBatis主要提供了两种方式用来解决该问题;

一、通过对查询SQL采用字段别名的方式

1、新建表和插入数据

[html] view plain copy
  1. DROP TABLE IF EXISTS `sl_company`;  
  2. CREATE TABLE `sl_company` (  
  3.   `company_id` int(11) NOT NULL AUTO_INCREMENT,  
  4.   `company_name` varchar(50) DEFAULT NULL,  
  5.   `full_name` varchar(100) DEFAULT NULL,  
  6.   `address` varchar(100) DEFAULT NULL,  
  7.   `post_code` varchar(45) DEFAULT NULL,  
  8.    PRIMARY KEY (`company_id`)  
  9. ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;  
  10.   
  11. -- ----------------------------  
  12. -- Records of sl_company  
  13. -- ----------------------------  
  14. INSERT INTO `sl_company` VALUES ('1', '锐客科技', '上海锐客科技股份有限公司', '上海市浦东新区峨山路91弄97号陆家嘴软件园5号楼3层', '200127');  
2、创建对应的实体类

[java] view plain copy
  1. package com.mybatis.entity;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. public class SlCompany implements Serializable {  
  6.   
  7.     private static final long serialVersionUID = 1L;  
  8.   
  9.     private int companyId;  
  10.   
  11.     private String companyName;  
  12.   
  13.     private String fullName;  
  14.   
  15.     private String address;  
  16.   
  17.     private String postCode;  
  18.   
  19.     public SlCompany() {  
  20.         super();  
  21.     }  
  22.   
  23.     public int getCompanyId() {  
  24.         return companyId;  
  25.     }  
  26.   
  27.     public void setCompanyId(int companyId) {  
  28.         this.companyId = companyId;  
  29.     }  
  30.   
  31.     public String getCompanyName() {  
  32.         return companyName;  
  33.     }  
  34.   
  35.     public void setCompanyName(String companyName) {  
  36.         this.companyName = companyName;  
  37.     }  
  38.   
  39.     public String getFullName() {  
  40.         return fullName;  
  41.     }  
  42.   
  43.     public void setFullName(String fullName) {  
  44.         this.fullName = fullName;  
  45.     }  
  46.   
  47.     public String getAddress() {  
  48.         return address;  
  49.     }  
  50.   
  51.     public void setAddress(String address) {  
  52.         this.address = address;  
  53.     }  
  54.   
  55.     public String getPostCode() {  
  56.         return postCode;  
  57.     }  
  58.   
  59.     public void setPostCode(String postCode) {  
  60.         this.postCode = postCode;  
  61.     }  
  62.       
  63. }  
3、上述创建完成后可以很明显发现字段名称与属性名称不一致,继续看如何解决该问题,找到slCompanyMapper.xml文件,修改文件内容如下:

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
  3. <mapper namespace="com.mybatis.mappings.slCompanyMapper">  
  4.     <!-- 通过使用字段别名的方式,AS关键字前面的是数据库表的字段名,后面对应的Java实体类对应的属性名称 -->  
  5.     <select id="getSlCompany" parameterType="int"  
  6.         resultType="com.mybatis.entity.SlCompany">  
  7.         SELECT company_id AS companyId,company_name AS  
  8.         companyName,full_name AS fullName, post_code AS postCode, address FROM  
  9.         sl_company WHERE company_id=#{id}  
  10.     </select>  
  11. </mapper>  
4、执行测试类,发现通过上述方式,仍然执行出既定结果,需要说明的是如果字段过多、过长,我们可以继续采用下面方式,将字段列表单独映射出来,用的时候直接导入即可,如下所示:

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
  3. <mapper namespace="com.mybatis.mappings.slCompanyMapper">  
  4.     <!-- 通过使用字段别名的方式,AS关键字前面的是数据库表的字段名,后面对应的Java实体类对应的属性名称 -->  
  5.     <!-- SlCompany字段映射列表 -->  
  6.     <sql id="getSlCompanyColumns">  
  7.         company_id AS companyId,  
  8.         company_name AS companyName,  
  9.         full_name AS fullName,   
  10.         post_code AS postCode,   
  11.         address   
  12.     </sql>  
  13.     <!-- 通过使用include元素的refid属性引入上面自定义的映射列表 -->  
  14.     <select id="getSlCompany" parameterType="int" resultType="com.mybatis.entity.SlCompany">  
  15.         SELECT <include refid="getSlCompanyColumns"/> FROM    sl_company WHERE company_id=#{id}  
  16.     </select>  
  17. </mapper>  
二、通过在xml中自定义结果映射的方式

1、表结构与java实体类同上,不在赘述。

2、下面来看看映射xml中的变化;

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
  3. <mapper namespace="com.mybatis.mappings.slCompanyMapper">  
  4.     <!-- 通过使用结果映射的方式 -->  
  5.     <select id="getSlCompany2" parameterType="int" resultMap="slCompanyResultMap">  
  6.         SELECT * FROM sl_company WHERE company_id=#{id}  
  7.     </select>  
  8.       
  9.     <!-- 通过使用resultMap元素自定义结果映射,该元素内部的id和result提供了javaType、jdbcType、typeHandler属性满足类型要求 -->  
  10.     <resultMap type="com.mybatis.entity.SlCompany" id="slCompanyResultMap">  
  11.         <!-- 通过id元素映射主键类型 -->  
  12.         <id column="company_id" property="companyId" />  
  13.         <!-- 通过result元素映射非主键类型 -->  
  14.         <result column="company_name" property="companyName"/>  
  15.         <result column="full_name" property="fullName"/>  
  16.         <!-- 当字段名和属性名一致是,可写可不写 -->  
  17.         <result column="address" property="address"/>  
  18.         <result column="post_code" property="postCode"/>  
  19.     </resultMap>  
  20.       
  21. </mapper>  
3、执行简单输出类

[java] view plain copy
  1. package com.mybatis.test;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5.   
  6. import org.apache.ibatis.io.Resources;  
  7. import org.apache.ibatis.session.SqlSession;  
  8. import org.apache.ibatis.session.SqlSessionFactory;  
  9. import org.apache.ibatis.session.SqlSessionFactoryBuilder;  
  10.   
  11. import com.mybatis.entity.SlCompany;  
  12.   
  13. public class MyBatisTest {  
  14.       
  15.     public static void main(String[] args) throws IOException {  
  16.           
  17.         // mybatis提供了Resources类用来提供简易方式来获取各种来源的资源文件信息  
  18.         // 获取mybatis.xml的字节流  
  19.         InputStream is = Resources.getResourceAsStream("mybatis.xml");  
  20.         // 获取mybatis.xml的字符流  
  21.         //Reader reader = Resources.getResourceAsReader("mybatis.xml");  
  22.           
  23.         // 构建SqlSessionFactory对象,传入字符流或字节流均可  
  24.         SqlSessionFactory SqlSessionFactory = new SqlSessionFactoryBuilder().build(is);  
  25.         // 获取SqlSession对象  
  26.         SqlSession sqlSession = SqlSessionFactory.openSession();  
  27.           
  28.         // 执行查询操作  
  29.         // selectOne()方法的第一个参数是由slCompanyMapper.xml里配置的mapper的namespace属性 + 该mapper下select元素的id属性值组成的  
  30.         SlCompany slCompany = sqlSession.selectOne("com.mybatis.mappings.slCompanyMapper.getSlCompany2"1);  
  31.           
  32.         // 用完SqlSession之后,不要忘记关闭  
  33.         sqlSession.close();  
  34.           
  35.         System.out.println(slCompany.getAddress());  
  36.     }  
  37. }  
输出既定信息;

总结:无论上述哪一种方式都提供了一种解决不一致的途径,需要注意它俩的不同点;

第一种方式直接在查询SQL语句下手,通过采用别名的方式,也就是说这种方式在得到查询结果集之前就搞定了不一致问题,获取到了跟属性名称一致的结果集;

第二种方式是在获取结果集之后,对结果集下手;


博文转自:http://blog.csdn.net/yu102655/article/details/52437455