Mybatis持久化组件
业务需求
在业务应用的持久化工作中,有时会选用MyBatis作为持久化框架支持。MyBatis的Sql语句写在XML配置文件里,将Sql语句与程序代码解耦,便于统一管理和优化。但是MyBatis并没有完善的分页支持,需要业务自己来实现。
解决方案
iuap平台使用iuap-mybatis作为MyBatis持久化的支持并提供了统一的Spring扫描注解和分页插件来支持分页的实现。
在前面的iuap-persistence组件中已经对Mybatis的基础使用做了介绍说明,iuap-persistence同时依赖了基础的Spring Data JPA和Mybatis,如果项目上明确只使用Mybatis,则不需要引入iuap-persistence组件,直接依赖iuap-mybatis组件即可,注意要和iuap其他组件的版本保持一致。
功能说明
- 提供统一的Spring扫描注解;
- 提供Mybatis分页插件;
整体设计
依赖环境
- spring 4.0.5.RELEASE
- mybatis 3.3.0
- mybatis-spring 1.2.3
功能特性
iuap-mybatis提供了统一的Spring扫描注解和分页插件。通过@MyBatisRepository确定mybatis提供服务的接口,再使用mybatis的xml文件管理实现mybatis服务的sql语句。
分页插件支持MyBatis3.2.0~3.3.0(包含)
使用说明
Maven依赖配置
<dependency>
<groupId>com.yonyou.iuap</groupId>
<artifactId>iuap-mybatis</artifactId>
<version>${iuap.modules.version}</version>
</dependency>
简单示例
实体类
public class DemoEntity implements Serializable {
private static final long serialVersionUID = 6794214450179665569L;
private String id;
private String name;
private Integer age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
}
接口
//使用@MyBatisRepository注解,确定服务接口
@MyBatisRepository
public interface DemoEntityMapper {
public DemoEntity findPeploeByID(String ID);
}
mybatis xml文件
与接口类同名的xml文件DemoEntityMapper.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.zhu.example.interfaces.DemoEntityMapper"> <resultMap id="BaseResultMap" type="com.zhu.example.entity.DemoEntity"> <id column="id" property="id" jdbcType="CHAR" /> <result column="name" property="name" jdbcType="CHAR" /> <result column="age" property="age" jdbcType="VARCHAR" /> </resultMap> <sql id="Base_Column_List"> id,name,age </sql> <select id="findPeploeByID" parameterType="java.lang.String" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from my_entity where id = #{id} </select> </mapper>
配置文件设置
<!-- 使用annotation定义事务 -->
<aop:aspectj-autoproxy/>
<!-- 单独使用mybatis时候,可以使用DataSourceTransactionManager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- MyBatis配置 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 自动扫描entity目录, 省掉Configuration.xml里的手工配置 -->
<property name="typeAliasesPackage" value="com.yonyou.iuap.entity"/>
<!-- 显式指定Mapper文件位置 -->
<property name="mapperLocations" value="classpath:/mybatis/**/*Mapper.xml"/>
<property name="plugins">
<array>
<bean id="paginationInterceptor"
class="com.yonyou.iuap.persistence.mybatis.plugins.PaginationInterceptor">
<property name="properties">
<props>
<prop key="dbms">mysql</prop>
<prop key="sqlRegex">.*retrievePage.*</prop>
</props>
</property>
</bean>
</array>
</property>
</bean>
<!-- 扫描basePackage下所有以@MyBatisRepository标识的 接口-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.yonyou.iuap.repository"/>
<property name="annotationClass" value="com.yonyou.iuap.persistence.mybatis.anotation.MyBatisRepository"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
示例工程说明
开发工具包中包含对iuap-mybatis组件的使用示例(DevTool/examples/example-iuap-mybatis),请参考示例工程中的具体配置和使用示例。
实体类示例
public class IpuQuotation implements Serializable { private static final long serialVersionUID = -9169987729255268660L; private String ipuquotaionid; private Date buyoffertime; private String contact; private Date createtime; private String description; private String phone; private Date processtime; private String processor; private Date qtexpiredate; private String subject; private Date ts; private Short dr; private List<IpuQuotationDetail> datailentitylist; public String getIpuquotaionid() { return ipuquotaionid; } public void setIpuquotaionid(String ipuquotaionid) { this.ipuquotaionid = ipuquotaionid == null ? null : ipuquotaionid.trim(); } public Date getBuyoffertime() { return buyoffertime; } public void setBuyoffertime(Date buyoffertime) { this.buyoffertime = buyoffertime; } ... ... public List<IpuQuotationDetail> getDatailentitylist() { return datailentitylist; } public void setDatailentitylist(List<IpuQuotationDetail> datailentitylist) { this.datailentitylist = datailentitylist; } }
数据库操作类示例
@MyBatisRepository public interface IpuQuotationMapper extends PageMapper<IpuQuotation> { int deleteByPrimaryKey(String id); int insert(IpuQuotation record); IpuQuotation selectByPrimaryKey(String id); IpuQuotation selectChildrenByPrimaryKey(String id); int updateByPrimaryKeySelective(IpuQuotation record); int updateByPrimaryKey(IpuQuotation record); PageResult<IpuQuotation> retrievePage(PageRequest pageRequest, @Param("subject") String subject); }
映射文件示例(注意spring配置文件中对mybatis映射文件的位置)
<?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.yonyou.iuap.repository.quotation.IpuQuotationMapper"> <resultMap id="BaseResultMap" type="com.yonyou.iuap.entity.quotation.IpuQuotation"> <id column="ipuquotaionid" property="ipuquotaionid" jdbcType="CHAR"/> <result column="buyoffertime" property="buyoffertime" jdbcType="TIMESTAMP"/> <result column="contact" property="contact" jdbcType="VARCHAR"/> <result column="createtime" property="createtime" jdbcType="TIMESTAMP"/> <result column="description" property="description" jdbcType="VARCHAR"/> <result column="phone" property="phone" jdbcType="VARCHAR"/> <result column="processtime" property="processtime" jdbcType="TIMESTAMP"/> <result column="processor" property="processor" jdbcType="VARCHAR"/> <result column="qtexpiredate" property="qtexpiredate" jdbcType="TIMESTAMP"/> <result column="subject" property="subject" jdbcType="VARCHAR"/> <result column="ts" property="ts" jdbcType="TIMESTAMP"/> <result column="dr" property="dr" jdbcType="SMALLINT"/> </resultMap> <resultMap id="childrenMap" type="com.yonyou.iuap.entity.quotation.IpuQuotation"> <id column="ipuquotaionid" property="ipuquotaionid" jdbcType="CHAR"/> <result column="buyoffertime" property="buyoffertime" jdbcType="TIMESTAMP"/> <result column="contact" property="contact" jdbcType="VARCHAR"/> <result column="createtime" property="createtime" jdbcType="TIMESTAMP"/> <result column="description" property="description" jdbcType="VARCHAR"/> <result column="phone" property="phone" jdbcType="VARCHAR"/> <result column="processtime" property="processtime" jdbcType="TIMESTAMP"/> <result column="processor" property="processor" jdbcType="VARCHAR"/> <result column="qtexpiredate" property="qtexpiredate" jdbcType="TIMESTAMP"/> <result column="subject" property="subject" jdbcType="VARCHAR"/> <result column="ts" property="ts" jdbcType="TIMESTAMP"/> <result column="dr" property="dr" jdbcType="SMALLINT"/> <collection property="datailentitylist" ofType="com.yonyou.iuap.entity.quotation.IpuQuotationDetail"> <id column="c_id" property="ipuquotationdetailid" jdbcType="CHAR"/> <result column="c_productdesc" property="productdesc" jdbcType="VARCHAR"/> <result column="c_productname" property="productname" jdbcType="VARCHAR"/> <result column="c_purchaseamount" property="purchaseamount" jdbcType="NUMERIC"/> <result column="c_unit" property="unit" jdbcType="VARCHAR"/> <result column="c_ipuquotaionid" property="ipuquotaionid" jdbcType="CHAR"/> <result column="c_ts" property="ts" jdbcType="TIMESTAMP"/> <result column="c_dr" property="dr" jdbcType="SMALLINT"/> </collection> </resultMap> <sql id="Base_Column_List"> ipuquotaionid, buyoffertime, contact, createtime, description, phone, processtime, processor, qtexpiredate, subject, ts, dr </sql> <sql id="oneToManyColumn"> t.ipuquotaionid, t.buyoffertime, t.contact, t.createtime, t.description, t.phone, t.processtime, t.processor, t.qtexpiredate, t.subject, t.ts, t.dr, tc.ipuquotationdetailid as c_id, tc.productdesc as c_productdesc,tc.productname as c_productname, tc.purchaseamount as c_purchaseamount, tc.unit as c_unit, tc.ipuquotaionid as c_ipuquotaionid, tc.ts as c_ts,tc.dr as c_dr </sql> <select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap"> select <include refid="Base_Column_List"/> from ipuquotation where ipuquotaionid = #{ipuquotaionid} </select> <select id="selectChildrenByPrimaryKey" parameterType="java.lang.String" resultMap="childrenMap"> select <include refid="oneToManyColumn"/> from ipuquotation t LEFT OUTER JOIN ipuquotationdetail tc on t.ipuquotaionid=tc.ipuquotaionid where t.ipuquotaionid = #{ipuquotaionid} </select> <select id="count" parameterType="map" resultType="int"> select count(*) from ipuquotation where 1=1 <if test="subject != null and subject!=''"> and subject like concat('%',#{subject}) </if> </select> <select id="queryPage" parameterType="map" resultMap="BaseResultMap"> select <include refid="Base_Column_List"/> from ipuquotation where 1=1 <if test="subject != null and subject!=''"> and subject like concat('%',#{subject}) </if> <if test="page.sort!=null"> order by <foreach collection="page.sort" item="item" separator=" "> ${item.property} ${item.direction} </foreach> </if> limit #{page.size} offset #{page.offset} </select> <delete id="deleteByPrimaryKey" parameterType="java.lang.String"> delete from ipuquotation where ipuquotaionid = #{ipuquotaionid} </delete> <insert id="insert" parameterType="com.yonyou.iuap.entity.quotation.IpuQuotation"> insert into ipuquotation (ipuquotaionid, buyoffertime, contact, createtime, description, phone, processtime, processor, qtexpiredate, subject, ts, dr) values (#{ipuquotaionid,jdbcType=CHAR}, #{buyoffertime,jdbcType=TIMESTAMP}, #{contact,jdbcType=VARCHAR}, #{createtime,jdbcType=TIMESTAMP}, #{description,jdbcType=VARCHAR}, #{phone,jdbcType=VARCHAR}, #{processtime,jdbcType=TIMESTAMP}, #{processor,jdbcType=VARCHAR}, #{qtexpiredate,jdbcType=TIMESTAMP}, #{subject,jdbcType=VARCHAR}, #{ts,jdbcType=TIMESTAMP}, #{dr,jdbcType=SMALLINT}) </insert> <update id="updateByPrimaryKeySelective" parameterType="com.yonyou.iuap.entity.quotation.IpuQuotation"> update ipuquotation <set> <if test="buyoffertime != null"> buyoffertime = #{buyoffertime,jdbcType=TIMESTAMP}, </if> <if test="contact != null"> contact = #{contact,jdbcType=VARCHAR}, </if> <if test="createtime != null"> createtime = #{createtime,jdbcType=TIMESTAMP}, </if> <if test="description != null"> description = #{description,jdbcType=VARCHAR}, </if> <if test="phone != null"> phone = #{phone,jdbcType=VARCHAR}, </if> <if test="processtime != null"> processtime = #{processtime,jdbcType=TIMESTAMP}, </if> <if test="processor != null"> processor = #{processor,jdbcType=VARCHAR}, </if> <if test="qtexpiredate != null"> qtexpiredate = #{qtexpiredate,jdbcType=TIMESTAMP}, </if> <if test="subject != null"> subject = #{subject,jdbcType=VARCHAR}, </if> <if test="ts != null"> ts = #{ts,jdbcType=TIMESTAMP}, </if> <if test="dr != null"> dr = #{dr,jdbcType=SMALLINT}, </if> </set> where ipuquotaionid = #{ipuquotaionid,jdbcType=CHAR} </update> <update id="updateByPrimaryKey" parameterType="com.yonyou.iuap.entity.quotation.IpuQuotation"> update ipuquotation set buyoffertime = #{buyoffertime,jdbcType=TIMESTAMP}, contact = #{contact,jdbcType=VARCHAR}, createtime = #{createtime,jdbcType=TIMESTAMP}, description = #{description,jdbcType=VARCHAR}, phone = #{phone,jdbcType=VARCHAR}, processtime = #{processtime,jdbcType=TIMESTAMP}, processor = #{processor,jdbcType=VARCHAR}, qtexpiredate = #{qtexpiredate,jdbcType=TIMESTAMP}, subject = #{subject,jdbcType=VARCHAR}, ts = #{ts,jdbcType=TIMESTAMP}, dr = #{dr,jdbcType=SMALLINT} where ipuquotaionid = #{ipuquotaionid,jdbcType=CHAR} </update> <select id="retrievePage" parameterType="map" resultMap="BaseResultMap"> select <include refid="Base_Column_List"/> from ipuquotation where 1=1 <if test="subject != null and subject!=''"> and subject like concat(#{subject},'%') </if> </select> </mapper>
分页支持说明
该插件目前支持以下数据库的物理分页:
Oracle
Mysql
配置dialect
属性时,可以使用小写形式:
oracle
,mysql
版本迁移
如果您正在使用其他分页插件,想迁移到iuap-mybatis分页插件,iuap-mybatis为您提供了方便的迁移方案。
查询条件转换接口
RequestConvertor
应用通过该接口实现类,将自定义的查询条件转换为iuap-mybatis插件的分页条件,包括数据获取区间,排序条件等等。<property name="requestConvertor"> <bean class="xxx.xxx.xxxRequestConvertor"/> </property>
查询结果转换接口
ResultConvertor
应用通过实现该接口,将iuap-mybatis的返回结果PageResult转换为应用自己的page对象。<property name="resultConvertor"> <bean class="xxx.xxx.xxxResultConvertor"/> </property>