Activiti入门之三--ORM框架MyBatis的基础及使用

1. 概述
上篇我们介绍了构建Activiti的环境基础及与Spring的整合,本篇则着重介绍Activiti中的底层ORM框架,以使得我们在后续的扩展Activiti的实现提供了基础的数据库访问功能。
2. 引入MyBatis依赖库
 
Activiti入门之三--ORM框架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的代码模板功能,可以满足所有的子类实现数据库的基础访问处理功能。如下所示:
  Activiti入门之三--ORM框架MyBatis的基础及使用

3.2.1数据库分页实现
只需要接收其分页的页码与页大小就可以实现分页处理,鉴于此,借用mbatis的分页的rowbounds,传给mybatis的本身底层的封装则可以。若需要支持更多的不同数据库的有效分页,本文不作介绍,宏天的BPM X3产品有更深入的使用及扩展。

package com.hotent.page;

import org.apache.ibatis.session.RowBounds;
/**
 * 
 * <pre> 
 * 描述:数据库分页类
 * 构建组:activiti
 * 作者:csx
 * 日期:2014年5月12日-下午12:18:43
 * </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
 * </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

 * 日期:2014年5月12日-上午9:31:02

 * </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
 * </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());
		}
		
	}
	
	
}

执行如下结果如下所示:
  Activiti入门之三--ORM框架MyBatis的基础及使用

【总结】
通过以上整合后,可以看到借助Mybatis实现数据库的访问其实很简单,但若手工来编写Mybatis的映射mapping文件其实是很繁琐的工作,宏天X3平台则提供代码生成器的方式来生成这些配置文件,甚至包括各个层次的代码部分。在本文则不作介绍,后续的Activiti的任务查询扩展我们则可以 基于该类进行二次开发。

具体的实现代码如附件:

spring-mybatis-activiti代码下载

更多资讯请加QQ了解3102760881

更多了解

http://redxun.iteye.com/blog/2406509

相关推荐