MyBatis持久层框架使用总结

     MyBatis 本是 apache 的一个开源项目 iBatis, 2010 年这个项目由 apache software foundation 迁移到了 google code,并且改名为 MyBatis 。

2013 年 11 月迁移到 Github,MyBatis 的 Github 地址:https://github.com/mybatis/mybatis-3

     iBATIS 一词来源于“internet”和“abatis”的组合,是一个基于 Java 的持久层框架。iBATIS 提供的持久层框架包括 SQL Maps 和 Data Access Objects(DAO)。

     MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录。

     每个 MyBatis 应用程序主要都是使用 SqlSessionFactory 实例的,一个 SqlSessionFactory 实例可以通过 SqlSessionFactoryBuilder 获得。SqlSessionFactoryBuilder 可以从一个 xml 配置文件或者一个预定义的配置类的实例获得。

 1. 使用 Generator 自动生成 Dao 层,Model 层和 Mapper 层。

    MyBatis Generator 下载地址:http://www.mybatis.org/generator/ 

    MyBatis Generator 中文介绍:http://generator.sturgeon.mopaas.com/ 

    以下用 mybatis-generator-core-1.3.2.jar 插件加 jdbc 数据库连接包自动导出持久层 dao 包,model 包和 mapper 包。

    需要用到的 Java 包有: 

       mybatis-generator-core-1.3.2.jar,

       mysql-connector-java-5.1.34.jar,

       ojdbc14-10.2.0.1.0.jar,

       sqljdbc4-4.0.jar。

    配置文件: generator.xml

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
  3 <generatorConfiguration>
  4     <!-- 配置属性文件 用来在配置文件中引入变量 El 表达式 -->
  5     <!-- 如果是用 cmd 方式运行 这里应该写 url 方式写全路径 因为找不到 classpath 对于 resource 来说 -->
  6     <!-- 
  7     <properties url="file:///D:/workspaces/mybatisGen/bin/generatorConfig.properties"/>
  8     -->
  9     
 10     <!-- 数据库驱动包位置 -->
 11      
 12      <!-- SQL Server 数据驱动包 -->
 13      
 14      <classPathEntry location="D:\JavaProject\generator\sqljdbc4-4.0.jar" /> 
 15     
 16      <!-- Oracle 数据驱动包 -->
 17      <!--
 18      <classPathEntry location="D:\Java\m2\repository\com\oracle\ojdbc14\10.2.0.1.0\ojdbc14-10.2.0.1.0.jar" />
 19      -->
 20      
 21      <!-- MySQL 数据驱动包 -->
 22      <!--
 23      <classPathEntry location="D:\JavaProject\generator\mysql-connector-java-5.1.34.jar" /> 
 24      -->
 25      
 26      <!-- 此处指定生成针对 MyBatis3 的 DAO-->
 27      <!--  
 28          id: 必须配置。这个上下文的惟一标识符。该值将被用在一些错误消息。
 29          defaultModelType: 用来定义生成模型类型策略。
 30             1.conditional 默认策略,为每个表生成一个 Model class
 31             2.flat: 将所有的表中生成一个 Model class,即这个类将保存所有表中字段
 32             3.hierarchical :如果表有一个主键,该模型将生成一个主键类, 另一个类, 用于容纳任何 BLOB 列在表中, 和另一个类, 用于容纳其余的字段。这个是一个适当的继承类之间的关系。
 33 
 34         targetRuntime:此属性用于指定运行时目标生成的代码。
 35             1.MyBatis3 默认值 将生成对象兼容 MyBatis 版本 3.0 和更高版本, 和 JSE 5.0 和更高版本
 36              (例如 Java 模型和 mapper 接口将使用泛型类型)。
 37              “by example”方法在这些生成的对象支持几乎无限的动态 where 子句。
 38              此外,Java 对象与这些生成器生成支持许多 JSE 5.0 特性包括参数化的类型和注释。
 39             2.Ibatis2Java2
 40             3.Ibatis2Java5
 41      -->
 42      
 43      <context id="MySQLTables" targetRuntime="MyBatis3" defaultModelType="conditional">
 44         
 45         <!-- 
 46         <plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin" />
 47         -->
 48         
 49         <!-- 
 50             用来生成注释 
 51             1. suppressAllComments 默认是 false  此属性用于指定在生成的代码是否将包括任何注释。如果设置为 true 则不生成注释
 52             2. suppressDate 默认是 false  此属性用于指定在生成的注释是否将包括 MBG 代时间戳。
 53         -->
 54         
 55         <commentGenerator>
 56             <property name="suppressAllComments" value="true" />
 57         </commentGenerator>
 58         
 59         <!-- 数据库链接 URL、用户名、密码 -->
 60         
 61         <!-- MySQL 数据库链接 URL、用户名、密码 -->
 62         <!--
 63         <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3310/test" userId="test" password="1234"> 
 64          </jdbcConnection>
 65         -->
 66         
 67         <!-- Oracle 数据库链接 URL、用户名、密码 -->
 68         <!--
 69         <jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver" connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:orcl" userId="test" password="1234">
 70         </jdbcConnection>
 71         -->
 72         
 73         <!-- SQL Server 数据库链接 URL、用户名、密码 -->
 74          <jdbcConnection driverClass="com.microsoft.sqlserver.jdbc.SQLServerDriver" connectionURL="jdbc:sqlserver://127.0.0.1:1433;DatabaseName=test" userId="test" password="1234"> 
 75          </jdbcConnection>
 76          
 77         <!-- H2 
 78          <entry key="jdbc.url">jdbc:h2:tcp://localhost/test</entry>
 79          <entry key="jdbc.driver">org.h2.Driver</entry>
 80         -->
 81     
 82         <!-- SQLServer2000 
 83           <entry key="jdbc.url">jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=[database]</entry>
 84           <entry key="jdbc.driver">com.microsoft.jdbc.sqlserver.SQLServerDriver</entry>
 85         -->
 86         
 87         <!-- SQLServer2005 
 88           <entry key="jdbc.url">jdbc:sqlserver://192.168.0.98:1433;DatabaseName=[database]</entry>
 89           <entry key="jdbc.driver">com.microsoft.sqlserver.jdbc.SQLServerDriver</entry>
 90         -->
 91         
 92         <!-- JTDs for SQLServer 
 93           <entry key="jdbc.url">jdbc:jtds:sqlserver://192.168.0.102:1433/[database];tds=8.0;lastupdatecount=true</entry>
 94           <entry key="jdbc.driver">net.sourceforge.jtds.jdbc.Driver</entry>
 95         -->
 96         
 97         <!-- PostgreSql
 98           <entry key="jdbc.url">jdbc:postgresql://localhost/[database]</entry>
 99           <entry key="jdbc.driver">org.postgresql.Driver</entry>
100         -->
101         
102         <!-- Sybase
103           <entry key="jdbc.url">jdbc:sybase:Tds:localhost:5007/[database]</entry>
104           <entry key="jdbc.driver">com.sybase.jdbc.SybDriver</entry>
105         -->
106         
107         <!-- DB2 
108           <entry key="jdbc.url">jdbc:db2://localhost:5000/[database]</entry>
109           <entry key="jdbc.driver">com.ibm.db2.jdbc.app.DB2Driver</entry>
110         -->
111      
112         <!-- HsqlDB 
113           <entry key="jdbc.url">jdbc:hsqldb:mem:generatorDB</entry>
114           <entry key="jdbc.driver">org.hsqldb.jdbcDriver</entry>
115         -->
116         
117         <!-- Derby 
118           <entry key="jdbc.url">jdbc:derby://localhost/databaseName</entry>
119           <entry key="jdbc.driver">org.apache.derby.jdbc.ClientDriver</entry>     
120         -->
121         
122         <!-- java 类型解析器 可选配置 -->
123         <!-- 
124           <javaTypeResolver type=""> 
125             type 属性: 这可用于指定一个用户提供的 Java 类型解析器。这个类必须实现接口 org.mybatis.generator.api。
126             JavaTypeResolver, 必须有一个公共的默认构造函数。属性还可以接受特殊的值默认在这种情况下, 将使用默认的实现 (这同样的效果不指定类型)。
127           该标签支持的属性:
128            forceBigDecimals:默认是 false 是否强制使用 BigDecimal 来表示所有的十进制和数值字段。
129            •如果规模很大,长度大于 18, 将使用 BigDecimal 类型。
130            •如果其长度为 10 到 18, 则 Java 类型解析器将 java.lang.Long 来代替了。
131            •如果长度为 5 到 9, 然后 Java 类型解析器将替换为一个 Java.lang.integer。
132            •如果其长度小于 5, 则 Java 类型解析器将以 java.lang.Short 替代。 
133         -->
134         
135         <javaTypeResolver>
136             <property name="forceBigDecimals" value="false" />
137         </javaTypeResolver>
138         
139         <!-- 生成 vo 对象 -->
140         <!-- 
141          < javaModelGenerator > 元素用于定义 Java 模型生成的属性。
142           Java 模型生成器建立主键类, 记录类, 和查询示例类相匹配的表进行自省。这个元素是所需的子元素 < 上下文 > 元素。
143           支持的属性:
144             constructorBased:
145               此属性用于选择是否 MyBatis 生成器将生成一个类的构造函数, 它接受一个值类中的每个字段。同时,SQL 结果地图将建成投入使用构造函数而不是“setter”每个字段。
146               这个属性是只适用于 MyBatis3 和将被忽略了 iBATIS2。
147               默认值是 false。
148             immutable: 
149               不可变,此属性用于选择是否 MyBatis 生成器将产生不可变模型类——这意味着类不会有“setter”方法和构造函数会接受类中每个字段的值。默认为 false。
150             trimStrings:
151               此属性用于选择 MyBatis 生成器是否添加代码来修剪的字符字段从数据库返回的空白空间。
152               这很有用, 如果您的数据库将数据存储在字符字段而不是 VARCHAR 字段。MyBatis 生成器将插入代码来削减字符字段。
153               默认值是 false。
154         -->
155         <!-- 生成实体类的包名和位置,这里配置将生成的实体类放在 com.ouc.model 这个包下 -->
156         <javaModelGenerator targetPackage="com.ouc.model" targetProject="D:\JavaProject\generator\src">
157             <property name="enableSubPackages" value="true" />
158             <property name="trimStrings" value="true" />
159         </javaModelGenerator>
160         
161         <!-- 生成用于查询的 mapping 对象 -->
162         <!-- 生成的 SQL 映射文件包名和位置,这里配置将生成的 SQL 映射文件放在 com.ouc.mapping 这个包下 -->
163         <sqlMapGenerator targetPackage="com.ouc.mapping" targetProject="D:\JavaProject\generator\src">
164             <property name="enableSubPackages" value="true" />
165         </sqlMapGenerator>
166         
167         <!-- 生成 DAO 的类文件以及配置文件 -->
168         <!-- 
169           < javaClientGenerator > 元素是用来定义 Java 客户机代码生成器的属性。
170            Java 客户机生成器用来建立 Java 接口和类, 以便可以方便地使用生成的 Java 模型和 XML 映射文件。
171            对于 iBATIS2 目标环境, 这些生成的对象采用形式的 DAO 接口和实现类。
172            对于 MyBatis, 生成的对象采用 mapper 形式的接口。
173            这个元素是一个可选的子元素。
174            如果你不指定这个元素,MyBatis 生成器 (MBG) 不会生成 Java 客户端接口和类。
175            其中的 type 属性:
176              如果 targetRuntime 为 MyBatis3
177              XMLMAPPER:生成的对象将 Java 接口 MyBatis 3.x mapper 基础设施。接口将会依赖生成的 XML 映射器文件。一般都是使用这个 XMLMAPPER.
178         -->
179         <!-- 生成 DAO 的包名和位置,这里配置将生成的 dao 类放在 com.ouc.dao 这个包下 -->
180         <javaClientGenerator type="XMLMAPPER" targetPackage="com.ouc.dao" targetProject="D:\JavaProject\generator\src">
181             <property name="enableSubPackages" value="true" />
182         </javaClientGenerator>
183         
184         <!-- 
185           <table> 元素用于选择数据库中的一个表。选择的表将导致为每个表生成以下对象:
186           •一个 MyBatis / iBATIS•格式化的 SQL 的映射文件
187           •一组类, 形成了“模型”表包括:
188           •一个类来匹配•表的主键 (如果表有一个主键)。
189           •表中字段匹配的, 不是在主键, 而非 BLOB 字段。这个类将扩展主键, 如果有一个。
190           •一个类来持有任何表中的 BLOB 字段 (如果有的话)。这个类将扩展其中一个的前面两个类取决于表的配置。
191           •一个类, 用于生成动态 where 子句, 在不同的“by Example”方法 (selectByExample,deleteByExample)。
192           •(可选)DAO 接口和类
193      
194           tableName: 必须配置  指定表的名称
195           domainObjectName:生成 javabean 对象的基本名称。如果未指定,MBG 将自动基于表名生成。
196           这个名字 (无论是在这里指定, 或自动生成) 将被用来作为域类名和 DAO 类的名字。
197           enableInsert:是否生成插入语句。默认是 true
198           enableSelectByPrimaryKey:是否通过主键生成选择语句。不管是否有这种设置, 如果该表没有一个主键将不会生成。
199           enableUpdateByPrimaryKey:是否通过主键生成更新语句。如果该表没有主键,不管是否设置该属性, 语句将不会生成。
200           enableDeleteByPrimaryKey:是否通过主键生成删除语句。如果该表没有主键,不管这种设置该属性, 语句将不会生成。
201           enableDeleteByExample:是否通过 example 对象生成删除语句。这个声明使得许多不同的动态删除在运行时生成。
202           enableCountByExample:是否通过 example 对象生成计算行数语句。该语句将返回一个表中的行数相匹配的 example。
203           enableUpdateByExample:是否通过 example 对象生成更新语句。该语句将更新一个表中相匹配的记录。
204 
205           selectByPrimaryKeyQueryId:这个值将被添加到选择列表中选择通过主键的声明在本表格:“' < 值 > 作为 QUERYID”。这可以用于识别查询在 DBA 在运行时跟踪工具。如果你需使用, 你应该指定一个唯一的 id 为每个不同的查询生成 MBG。
206           selectByExampleQueryId:这个值将被添加到选择列表中选择通过例子的声明在本表格:“' < 值 > 作为 QUERYID”。这可以用于识别查询在 DBA 在运行时跟踪工具。如果你需使用, 你应该指定一个唯一的 id 为每个不同的查询生成 MBG。
207           enableSelectByExample: 是否应该生成通过 example 的选择语句。这个声明使得许多不同的动态查询是在运行时生成。
208      
209           modelType:此属性用于覆盖默认的模型类型, 如果你想对这张表这么做。如果未指定,MBG 将生成的域对象基于上下文默认的模型类型。
210             该模型类型定义了如何将生成 MBG 域类。
211             一些模型类型 MBG 将生成一个单一的域类为每个表, 和其他可能产生不同的类 MBG 取决于表的结构。
212          escapeWildcards:排除通配符。这意味着无论 SQL 通配符 ('_' 和 '%') 的模式和表名都应该避免在搜寻列。
213          这是一些驱动要求如果模式或表包含一个 SQL 通配符 (例如, 如果一个表的名字是 MY_TABLE, 一些驱动要求的下划线字符进行转义)。
214         -->
215         
216         <!-- 要生成那些表 (更改 tableName 和 domainObjectName 就可以) -->
217         <table tableName="V_SupplyUser" domainObjectName="VSupplyUser" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" />
218         <table tableName="WJ_GateList" domainObjectName="WJGateList" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" />
219     </context>
220 </generatorConfiguration>
View Code

     打开 cmd 命令行,转到配置文件所在的文件下,执行如下生成语句:

java -jar mybatis-generator-core-1.3.2.jar -configfile generator.xml -overwrite

    命令执行完毕,可以看到对应路径下生成 dao 包,model 包和 mapper 包文件。

 2.MyBatis 框架整合

  1)MyBatis 使用参数配置:sqlMapConfig.xml。

    ① 缓存配置 (Cache):cacheEnabled:全局开关:默认是 true,如果它配成 false,其余各个 Mapper XML 文件配成支持 cache 也没用。

    ② 延迟加载:

         lazyLoadingEnabled:true 使用延迟加载,false 禁用延迟加载,默认为 true,当禁用时, 所有关联对象都会即时加载。 

         aggressiveLazyLoading:true 启用时,当延迟加载开启时访问对象中一个懒对象属性时,将完全加载这个对象的所有懒对象属性。false,当延迟加载时,按需加载对象属性(即访问对象中一个懒对象属性,不会加载对象中其他的懒对象属性)。默认为 true。

     ③ multipleResultSetsEnabled:允许和不允许单条语句返回多个数据集(取决于驱动需求)。默认为 true。

     ④ useColumnLabel:使用列标签代替列名称。不同的驱动器有不同的做法。参考一下驱动器文档,或者用这两个不同的选项进行测试一下。

     ⑤ useGeneratedKeys:允许 JDBC 生成主键。需要驱动器支持。如果设为了 true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。

     ⑥ autoMappingBehavior:指定 MyBatis 是否并且如何来自动映射数据表字段与对象的属性。PARTIAL 将只自动映射简单的,没有嵌套的结果。FULL 将自动映射所有复杂的结果。

    ⑦ defaultExecutorType:配置和设定执行器,SIMPLE 执行器执行其它语句。REUSE 执行器可能重复使用 prepared statements 语句,BATCH 执行器可以重复执行语句和批量更新。

    ⑧ defaultStatementTimeout:设置一个时限,以决定让驱动器等待数据库回应的多长时间为超时。

    完整 sqlMapConfig.xml 配置文件如下:

  1 <?xml version="1.0" encoding="UTF-8" ?>
  2 <!DOCTYPE configuration
  3   PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4   "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5 
  6 <configuration>
  7     <settings>
  8         <setting name="cacheEnabled" value="true" />
  9         <setting name="lazyLoadingEnabled" value="true" />
 10         <setting name="multipleResultSetsEnabled" value="true" />
 11         <setting name="useColumnLabel" value="true" />
 12         <setting name="useGeneratedKeys" value="false" />
 13         <setting name="autoMappingBehavior" value="PARTIAL" />
 14         <setting name="defaultExecutorType" value="SIMPLE" /><!-- SIMPLE REUSE BATCH -->
 15         <!-- <setting name="defaultExecutorType" value="BATCH" /> -->
 16         <setting name="defaultStatementTimeout" value="25000" />
 17         <setting name="safeRowBoundsEnabled" value="false" />
 18         <setting name="mapUnderscoreToCamelCase" value="false" />
 19         <setting name="localCacheScope" value="SESSION" />
 20         <!-- <setting name="jdbcTypeForNull" value="OTHER" /> -->
 21         <setting name="jdbcTypeForNull" value="NULL" />
 22         <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString" />
 23     </settings>
 24     <typeAliases>
 26         <!-- 模块 -->
 37         <typeAlias alias="User" type="com.ouc.mkhl.platform.authority.model.User"/> 
 39         <typeAlias alias="Role" type="com.ouc.mkhl.platform.authority.model.Role"/>
 73         <typeAlias alias="Equipment" type="com.ouc.mkhl.platform.basedata.model.Equipment"/>
 74         <typeAlias alias="Factory" type="com.ouc.mkhl.platform.basedata.model.Factory"/>
152     </typeAliases>
153     
154     <typeHandlers>
155       <typeHandler handler="com.ouc.openplatform.dao.mybatis.SerializableTypeHandler"/>
156     </typeHandlers>
157 </configuration>

    序列化特殊值处理:SerializableTypeHandler

 1 package com.ouc.openplatform.dao.mybatis;
 2 
 3 import java.io.Serializable;
 4 import java.sql.CallableStatement;
 5 import java.sql.PreparedStatement;
 6 import java.sql.ResultSet;
 7 import java.sql.SQLException;
 8 
 9 import org.apache.ibatis.type.BaseTypeHandler;
10 import org.apache.ibatis.type.JdbcType;
11 
12 /**
13  * @author WuPing
14  */
15 public class SerializableTypeHandler extends BaseTypeHandler<Serializable> {
16 
17       @Override
18       public void setNonNullParameter(PreparedStatement ps, int i, Serializable parameter, JdbcType jdbcType)
19           throws SQLException {
20         ps.setObject(i, parameter);
21       }
22 
23       @Override
24       public Serializable getNullableResult(ResultSet rs, String columnName)
25           throws SQLException {
26         return (Serializable)rs.getObject(columnName);
27       }
28 
29       @Override
30       public Serializable getNullableResult(ResultSet rs, int columnIndex)
31           throws SQLException {
32         return (Serializable)rs.getObject(columnIndex);
33       }
34 
35       @Override
36       public Serializable getNullableResult(CallableStatement cs, int columnIndex)
37           throws SQLException {
38         return (Serializable)cs.getObject(columnIndex);
39       }
40 
41 }
View Code

   2)结果集 resultMap:

    MyBatis 中在查询进行 select 映射的时候,返回类型可以用 resultType,也可以用 resultMap,resultType 是直接表示返回类型的,而 resultMap 则是对外部 ResultMap 的引用,但是 resultType 跟 resultMap 不能同时存在。在 MyBatis 进行查询映射的时候,其实查询出来的每一个属性都是放在一个对应的 Map 里面的,其中键是属性名,值则是其对应的值。当提供的返回类型属性是 resultType 的时候,MyBatis 会将 Map 里面的键值对取出赋给 resultType 所指定的对象对应的属性。所以其实 MyBatis 的每一个查询映射的返回类型都是 ResultMap,只是当我们提供的返回类型属性是 resultType 的时候,MyBatis 对自动的给我们把对应的值赋给 resultType 所指定对象的属性,而当我们提供的返回类型是 resultMap 的时候,因为 Map 不能很好表示领域模型,我们就需要自己再进一步的把它转化为对应的对象,这常常在复杂查询中很有作用。

    示例:UserBaseResultMap

<resultMap id="UserBaseResultMap" type="User" >
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="userName" property="userName" jdbcType="VARCHAR" />
    <result column="password" property="password" jdbcType="VARCHAR" />
    <result column="email" property="email" jdbcType="VARCHAR" />
    <result column="trueName" property="trueName" jdbcType="VARCHAR" />
    <result column="sex" property="sex" jdbcType="VARCHAR" />
    <result column="age" property="age" jdbcType="INTEGER" />
    <result column="telephone" property="telephone" jdbcType="VARCHAR" />
  </resultMap>

   model 类:User

 1 package com.ouc.mkhl.platform.authority.model;
 2 
 3 import java.io.Serializable;
 4 
 5 //用户信息
 6 public class User implements Serializable {
 7 
 8     private static final long serialVersionUID = 1098321123L;
 9 
10     private Integer id;    //用户 Id
11 
12     private String userName;   //用户名
13 
14     private String password;    //未加密密码
15 
16     private String email;    //邮箱
17     
18     private String trueName;  //真实姓名
19 
20     private String sex;   //性别
21 
22     private Integer age;   //年龄
23 
24     private String telephone;  //手机
25 
26     public Integer getId() {
27     return id;
28     }
29 
30     public void setId(Integer id) {
31     this.id = id;
32     }
33 
34     public String getUserName() {
35     return userName;
36     }
37 
38     public void setUserName(String userName) {
39     this.userName = userName == null ? null : userName.trim();
40     }
41 
42     public String getPassword() {
43     return password;
44     }
45 
46     public void setPassword(String password) {
47     this.password = password == null ? null : password.trim();
48     }
49 
50     public String getEmail() {
51     return email;
52     }
53 
54     public void setEmail(String email) {
55     this.email = email == null ? null : email.trim();
56     }
57 
58     public String getTrueName() {
59     return trueName;
60     }
61 
62     public void setTrueName(String trueName) {
63     this.trueName = trueName == null ? null : trueName.trim();
64     }
65     
66     public String getSex() {
67     return sex;
68     }
69 
70     public void setSex(String sex) {
71     this.sex = sex == null ? null : sex.trim();
72     }
73 
74     public Integer getAge() {
75     return age;
76     }
77 
78     public void setAge(Integer age) {
79     this.age = age;
80     }
81 
82     public String getTelephone() {
83     return telephone;
84     }
85 
86     public void setTelephone(String telephone) {
87     this.telephone = telephone == null ? null : telephone.trim();
88     }
89    
90 }
View Code

  3)增删改查:

  (1)select 查询: 

      ① id:在这个模式下唯一的标识符,可被其它语句引用。

      ② parameterType:传给此语句的参数的完整类名或别名。

      ③ resultType:语句返回值类型的整类名或别名。注意,如果是集合,那么这里填写的是集合的项的整类名或别名,而不是集合本身的类名。(resultType 与 resultMap 不能并用)

      ④ resultMap:引用的外部 resultMap 名。结果集映射是 MyBatis 中最强大的特性。许多复杂的映射都可以轻松解决。(resultType 与 resultMap 不能并用)

      ⑤ flushCache:如果设为 true,则会在每次语句调用的时候就会清空缓存。select 语句默认设为 false。

      ⑥ useCache:如果设为 true,则语句的结果集将被缓存。select 语句默认设为 false。

      ⑦ timeout :设置驱动器在抛出异常前等待回应的最长时间,默认为不设值,由驱动器自己决定。

    示例:查询所有用户信息:selectUsers

<select id="selectUsers" resultMap="UserBaseResultMap">
    select id,userName,email from user 
</select>

   (2) insert 插入:saveUser

    此处数据库表使用主键自增,主键为 id。

     ① fetchSize:设置一个值后,驱动器会在结果集数目达到此数值后,激发返回,默认为不设值,由驱动器自己决定。

     ② statementType:statement,preparedstatement,callablestatement。预准备语句、可调用语句。

     ③ useGeneratedKeys:使用 JDBC 的 getGeneratedKeys 方法来获取数据库自己生成的主键(MySQL、SQLSERVER 等关系型数据库会有自动生成的字段)。

     ④ keyProperty:标识一个将要被 MyBatis 设置进 getGeneratedKeys 的 key 所返回的值,或者为 insert 语句使用一个 selectKey 子元素。

<insert id="saveUser" parameterType="User" >
    insert into user (userName, password, email, trueName, sex, age, telephone)
    values (#{userName,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 
      #{email,jdbcType=VARCHAR}, #{trueName,jdbcType=VARCHAR}, 
      #{sex,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER}, #{telephone,jdbcType=VARCHAR})
</insert>

    (3)update 更新:动态更新 SQL:updateUser

  <update id="updateUser" parameterType="User" >
    update user
    <set >
      <if test="userName != null" >
        userName = #{userName,jdbcType=VARCHAR},
      </if>
      <if test="password != null" >
        password = #{password,jdbcType=VARCHAR},
      </if>
      <if test="email != null" >
        email = #{email,jdbcType=VARCHAR},
      </if>
      <if test="trueName != null" >
        trueName = #{trueName,jdbcType=VARCHAR},
      </if>
      <if test="sex != null" >
        sex = #{sex,jdbcType=VARCHAR},
      </if>
      <if test="age != null" >
        age = #{age,jdbcType=INTEGER},
      </if>
      <if test="telephone != null" >
        telephone = #{telephone,jdbcType=VARCHAR},
      </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
  </update>

    (4)delete 删除:deleteUser

<delete id="deleteUser" parameterType="Integer">
    delete from user
    where id = #{id,jdbcType=INTEGER}
</delete>

    (5)sql: Sql 元素用来定义一个可以复用的 SQL 语句段,供其它语句调用。

<sql id="UserBaseColumnList" >
    userName, password, email, telephone
</sql>
<select id="getUsers" resultMap="UserBaseResultMap">
    select 
    <include refid="UserBaseColumnList" />
    from user
</select>

   (6)参数:parameters:MyBatis 可以使用基本数据类型和 Java 的复杂数据类型。
       基本数据类型,String,int,date 等。
       使用基本数据类型,只能提供一个参数,所以需要使用 Java 实体类,或 Map 类型做参数类型。通过 #{} 可以直接得到其属性。

      ① 基本数据类型参数:String

<select id="getUserByName" resultType="User" parameterType="String" >
    select id, userName, email  from user
    where userName = #{userName,jdbcType=VARCHAR}
</select>

     Java 代码:

public User getUserByName(String name); // 根据用户名获取用户信息

     ② Java 实体类型参数:User

<insert id="saveUser" parameterType="User" >
    insert into user (userName, password, email, trueName, sex, age, telephone)
    values (#{userName,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 
      #{email,jdbcType=VARCHAR}, #{trueName,jdbcType=VARCHAR}, 
      #{sex,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER}, #{telephone,jdbcType=VARCHAR})
</insert>

    Java 代码:

public int saveUser(User user); // 插入用户信息

    ③ Map 参数:Map<String, Object> recordMap

<select id="selectChildGroupTotalNum" resultType="Integer" >
    select count(*) from groupinfo
     <trim prefix="WHERE" prefixOverrides="AND|OR">
        and id in 
        <foreach collection="idStr" item="ids" open="(" separator="," close=")">     
           #{ids}      
        </foreach>    
        <if test="name!= null and name!='' " >
           and name LIKE CONCAT(CONCAT('%', #{name}),'%')
        </if>
        <if test="description!= null and description!='' " >
           AND description LIKE CONCAT(CONCAT('%', #{description}),'%')
        </if>
        <if test="type != null and type!=-1" >
           AND type = #{type,jdbcType=INTEGER}
        </if>
        <if test="category != null and category!=-1" >
           AND category = #{category,jdbcType=INTEGER}
        </if>
     </trim> 
  </select>

    Java 代码:

//获取子组总记录数
public int selectChildGroupTotalNum(Map<String, Object> recordMap);  
Map<String, Object> recordMap = new HashMap<String, Object>();
        recordMap.put("idStr", group.getChildgroupids().split(","));
        recordMap.put("name", name);
        recordMap.put("description", description);
        recordMap.put("type", -1);
        recordMap.put("category", -1);
        childGroupTotalNum = groupDao.selectChildGroupTotalNum(recordMap);

    ④ 多参数:

     方法一:按顺序传递参数。

<!-- 根据参数名查询参数 -->
  <select id="selectSensorNobySensorName" resultType="Integer" useCache="false" flushCache="true">
     select SensorNo from sensorconfig 
     where Name = #{0} and TestunitNo = #{1} and LABCODE = #{2}
  </select>

      Java 代码:

//根据参数名查询参数 ID
public int selectSensorNobySensorName(String sensorName, int testUnitNo, String labCode);

    方法二:接口参数上添加 @Param 注解。

<select id="selectByUserNameAndVCode" resultMap="UserBaseResultMap">
        select id, userName from user
        <trim prefix="WHERE" prefixOverrides="AND|OR">
            <if test="userName!= null and userName!='' ">
                and userName LIKE CONCAT(CONCAT('%', #{userName}),'%')
            </if>
            <if test="supplierno!= null and supplierno!='' ">
                and supplierNo LIKE CONCAT(CONCAT('%', #{supplierno}),'%')
            </if> 
            and supplierNo != 'test'
        </trim>
        LIMIT #{startIndex},#{pageSize}
</select>

    Java 代码:

 // 根据用户名和 V 码查询用户信息
 public List<User> selectByUserNameAndVCode(
        @Param("userName") String userName,
        @Param("supplierno") String supplierno,
        @Param("startIndex") int startIndex, @Param("pageSize") int pageSize);

 4)动态 SQL 语句

    selectKey 标签,if 标签,if + where 的条件判断,if + set 的更新语句,if + trim 代替 where/set 标签,trim 代替 set,choose (when, otherwise),foreach 标签。动态 SQL 语句算是 MyBatis 最灵活的部分吧,用好了非常方便。

    示例:selectTotalNumByAccountType

<select id="selectTotalNumByAccountType" resultType="Integer" >
        select count(*) from user
        <trim prefix="WHERE" prefixOverrides="AND|OR">
            and id not in 
            <foreach collection="idStr" item="ids" open="(" separator="," close=")">     
              #{ids}      
            </foreach>     
            <if test="userName!= null and userName!='' ">
                and userName LIKE CONCAT(CONCAT('%', #{userName}),'%')
            </if>
            <if test="supplierno!= null and supplierno!='' ">
                and supplierNo LIKE CONCAT(CONCAT('%', #{supplierno}),'%')
            </if> 
            <if test="trueName!= null and trueName!='' ">
                and trueName LIKE CONCAT(CONCAT('%', #{trueName}),'%')
            </if>
            AND accountType = #{accountType}
        </trim>
</select>

    可以查看的文章:

    1. MyBatis 学习 之 三、动态 SQL 语句:http://limingnihao.iteye.com/blog/782190

    2.MyBatis 和 Hibernate 相比,优势在哪里?  https://www.zhihu.com/question/21104468

    3.【持久化框架】Mybatis 简介与原理: http://blog.csdn.net/jiuqiyuliang/article/details/45286191

    4.MyBatis 学习总结 (一)——MyBatis 快速入门: http://www.cnblogs.com/xdp-gacl/p/4261895.html

    5. 利用 mybatis-generator 自动生成代码: http://www.cnblogs.com/yjmyzz/p/4210554.html

    6.MyBatis 魔法堂:即学即用篇: http://www.cnblogs.com/fsjohnhuang/p/4014819.html

    7.mybatis 使用经验小结: http://www.cnblogs.com/yjmyzz/p/4261024.html