|
1. 概述
上篇我们介绍了构建Activiti的环境基础及与Spring的整合,本篇则着重介绍Activiti中的底层ORM框架,以使得我们在后续的扩展Activiti的实现提供了基础的数据库访问功能。
2. 引入MyBatis依赖库
增加mybatis-spring依赖包,如上图所示,具体的pom.xml文件如附件中的文件所示,在这里不贴代码了。
3. 配置MyBatis与Spring的基础配置组件
MyBatis已经提供了与Spring的整合,其依赖包为mybatis-spring,具体整合如下连接所示:
http://mybatis.github.io/spring/zh/
3.1. 配置SqlSessonFactoryBean及事务管理
<!-- Mybatis的SessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath*:com/hotent/**/mapping/*.xml"/>
</bean>
【说明】其中mapperLocations指向Mybatis的Mapping XML文件
3.2 编写MyBatis基础访问类
我们提供数据库访问的底层的基础封装,如CRUD的处理,借助JAVA的代码模板功能,可以满足所有的子类实现数据库的基础访问处理功能。如下所示:
3.2.1数据库分页实现
只需要接收其分页的页码与页大小就可以实现分页处理,鉴于此,借用mbatis的分页的rowbounds,传给mybatis的本身底层的封装则可以。若需要支持更多的不同数据库的有效分页,本文不作介绍,宏天的BPM X3产品有更深入的使用及扩展。
package com.hotent.page;
import org.apache.ibatis.session.RowBounds;
/**
*
* <pre>
* 描述:数据库分页类
* 构建组:activiti
* 作者:csx
* 邮箱:chensx@jee-soft.cn
* 日期:2014年5月12日-下午12:18:43
* 版权:广州宏天软件有限公司版权所有
* 网址:http://www.jee-soft.cn
* </pre>
*/
public class DefaultPage extends RowBounds{
/**
* 最多显示页码数
*/
public static final int DEFAULT_PAGE_SIZE = 20;
//页码大小
private Integer pageSize=DEFAULT_PAGE_SIZE;
//总记录数
private Integer totalItems=0;
//当前页码
private Integer pageNo=1;
private boolean isShowTotal=true;
public DefaultPage() {
}
public DefaultPage(Integer pageNo,Integer pageSize){
this.pageNo=pageNo;
this.pageSize=pageSize;
}
@Override
public int getOffset() {
return getStartIndex();
}
@Override
public int getLimit() {
return getPageSize();
}
public Integer getStartIndex(){
return (pageNo-1)*pageSize;
}
public Integer getPageSize() {
return pageSize;
}
public Integer getTotalItems() {
return totalItems;
}
public void setTotalItems(Integer totalItems) {
this.totalItems = totalItems;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getPageNo() {
return pageNo;
}
public void setPageNo(Integer pageNo) {
this.pageNo = pageNo;
}
public boolean isShowTotal() {
return isShowTotal;
}
public void setShowTotal(boolean isShowTotal) {
this.isShowTotal = isShowTotal;
}
}
3.2.2 IDAO 接口
package com.hotent.dao;
import java.io.Serializable;
import java.util.List;
import com.hotent.page.DefaultPage;
/**
*
* <pre>
* 描述:TODO
* 构建组:activiti
* 作者:csx
* 邮箱:chensx@jee-soft.cn
* 日期:2014年5月12日-上午9:23:26
* 版权:广州宏天软件有限公司版权所有
* </pre>
*/
public interface IDao<T,PK extends Serializable> {
/**
* 按ID获取实体
* @param id
* @return
*/
public T get(PK id);
/**
* 按ID删除实体
* @param id
*/
public void remove(PK id);
/**
* 按ID创建实体
* @param entity
*/
public void create(T entity);
/**
* 更新实体
* @param entity
*/
public void update(T entity);
/**
* 查询所有实体列表
* @return
*/
public List<T> getAll();
/**
* 按分页查询所有实体
* @param page
* @return
*/
public List<T> getAllByPage(DefaultPage page);
}
3.2.3 MyBatisDAO实现
package com.hotent.dao;
import java.io.Serializable;
import java.util.List;
import javax.annotation.Resource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import com.hotent.page.DefaultPage;
/**
*
* <pre>
* 描述:TODO
* 构建组:activiti
* 作者:csx
* 邮箱:chensx@jee-soft.cn
* 日期:2014年5月12日-上午9:31:02
* 版权:广州宏天软件有限公司版权所有
* 网址:http://www.jee-soft.cn
* </pre>
*/
public abstract class MyBatisDao<T,PK extends Serializable> extends SqlSessionDaoSupport{
/**
* 按ID获取单一记录
*/
protected final String OP_GET=".get";
/*
* 按ID删除记录
*/
protected final String OP_DEL=".remove";
/**
* 按ID更新记录
*/
protected final String OP_UPD=".update";
/**
* 添加记录
*/
protected final String OP_CREATE=".create";
/**
* 查询记录列表
*/
protected final String OP_GETALL=".getAll";
/**
* 返回当前实体的命名空间字符串名称
*/
public abstract String getNamespace();
public void create(T entity) {
this.getSqlSession().insert(getNamespace() + OP_CREATE, entity);
}
public void update(T entity) {
this.getSqlSession().update(getNamespace() + OP_UPD, entity);
}
public void remove(PK entityId) {
this.getSqlSession().delete(getNamespace() + OP_DEL, entityId);
}
public T get(PK entityId) {
return this.getSqlSession().selectOne(getNamespace() + OP_GET,entityId);
}
public List<T> getAll() {
return this.getSqlSession().selectList(getNamespace() + OP_GETALL, null);
}
public List<T> getAllByPage(DefaultPage page){
return this.getSqlSession().selectList(getNamespace() + OP_GETALL, null,page);
}
}
【说明】通过继承Mybatis的SqlSessionDaoSupport, 以及其获取的getSqlSession()来实现数据库的访问,但要注意一点,后续的所有的继承该基类的Dao,需要注入 sqlSessionFactory或sqlSessionTemplate。因此,如我们写一个学生的DAO,在使用上我们则需要在Spring配置文 件中按如下配置:
<bean id="studentDao" class="com.hotent.example.dao.StudentDao">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
3.3 配置基础AOP的事务
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 事务AOP拦截控制配置 -->
<aop:config proxy-target-class="true">
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.hotent.dao.MyBatisDao.*(..))"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="is*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="query*" read-only="true"/>
<tx:method name="*" isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>
4. 编写访问学生表的DAO配置测试的Dao,如下所示:
在Spring中增加该Dao的配置,如下所示:
<bean id="studentDao" class="com.hotent.example.dao.StudentDao">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
注意其引用了sqlSessionFactory
5. 编写测试用例编写一学生DAO测试用例,实现基础的数据库访问功能,如创建、获取列表等。
代码如下所示:
package com.hotent.example.dao;
import com.hotent.dao.MyBatisDao;
import com.hotent.example.entity.Student;
public class StudentDao extends MyBatisDao<Student, String>{
@Override
public String getNamespace() {
return Student.class.getName();
}
}
编写测试用例:
package com.hotent.test.example;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.annotation.Resource;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.test.annotation.Rollback;
import com.hotent.example.dao.StudentDao;
import com.hotent.example.entity.Student;
import com.hotent.page.DefaultPage;
import com.hotent.test.BaseTestCase;
/**
*
* <pre>
* 描述:TODO
* 构建组:activiti
* 作者:csx
* 邮箱:chensx@jee-soft.cn
* 日期:2014年5月12日-上午10:35:20
* 版权:广州宏天软件有限公司版权所有
* 网址:http://www.jee-soft.cn
* </pre>
*/
public class StudentDaoTest extends BaseTestCase{
@Resource
StudentDao studentDao;
@Test
@Rollback(false)
public void testCreateStudent(){
String guid=UUID.randomUUID().toString();
int ranId=new Double(10000*Math.random()).intValue();
Student student=new Student();
student.setId(guid);
student.setName("张三"+ranId);
student.setSex(new Short("1"));
student.setBirthday(new Date());
student.setDesc("张三个人简介");
studentDao.create(student);
Student student2=studentDao.get(guid);
Assert.assertNotNull(student2);
}
@Test
public void testGetAll(){
List<Student> list=studentDao.getAllByPage(new DefaultPage(1, 10));
Assert.assertTrue(list.size()>0);
for(Student student:list){
System.out.println("student:" + student.getName());
}
}
}
执行如下结果如下所示:
【总结】
通过以上整合后,可以看到借助Mybatis实现数据库的访问其实很简单,但若手工来编写Mybatis的映射mapping文件其实是很繁琐的工作,宏天X3平台则提供代码生成器的方式来生成这些配置文件,甚至包括各个层次的代码部分。在本文则不作介绍,后续的Activiti的任务查询扩展我们则可以 基于该类进行二次开发。
具体的实现代码如附件:
spring-mybatis-activiti代码下载
更多资讯请加QQ了解3102760881 |
|
|