论坛首页 Java企业应用论坛

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

浏览 10579 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2014-05-12  

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代码下载

 

  • 大小: 51.2 KB
  • 大小: 60.6 KB
  • 大小: 19.1 KB
   发表时间:2014-05-13  
mybatis是面向接口编程,其实无需再用基类进行继承
0 请登录后投票
   发表时间:2014-05-14  
用基类的好处是子类不需要再增加CRUD及组合查询的实现,用IDAO接口,是为业务逻辑处理层增加基础的实现,也使业务逻辑处理层具备CRUD及组合查询的能力
1 请登录后投票
   发表时间:2014-05-14  
请问“宏天X3平台”:你们花了多少钱才能上ITEye头条的?
0 请登录后投票
   发表时间:2014-07-15  
关键是activiti 的jpa 不支持 Mybatis

只能用写死form的方式,来实现业务的数据管理
0 请登录后投票
   发表时间:2014-07-17  
ktmhate 写道
关键是activiti 的jpa 不支持 Mybatis

只能用写死form的方式,来实现业务的数据管理

兄弟你搞错了, activiti的orm本身就是用mybatis,jbpm5的orm才是用jpa,
activiti的表单是需要通过扩展外部来做的,一般不会用它的内置表单的处理模式。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics