论坛首页 Java企业应用论坛

工具框架“仓库猫”发布0.2重构版,希望大家多多试用,多多提意见和BUG

浏览 2899 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (1) :: 隐藏帖 (6)
作者 正文
   发表时间:2009-04-04  
DAO
大家好,继上月底发布“仓库猫”0.1版后,猫咪在昨天发布0.2版。对整个框架结构进行了重构并修复了发现的BUG。欢迎大家下载试用。大家在使用中发现BUG或者有什么好的建议请和猫咪联络。
项目地址为http://code.google.com/p/catstorage/
   发表时间:2009-04-06   最后修改:2009-04-06
下面我提供一个“仓库猫”和Spring集成的例子。这是猫咪正在编写的一个完整使用示例的一部分,该示例将于0.3版时一同发布。
本文使用了Spring MVC、Spring和Hibernate EntityManager分别作为3层的框架。如何创建工程和引用jar包我就不说了,这些东西大家应该都很熟悉。
首先是在Spring中编写“仓库猫”组件的配置。
<bean id="storage" class="org.miao.catstorage.Storage" init-method="config">
    <property name="resource" value="classpath:statement.json" />
</bean>

非常简单,要注意init-method方法和Resource属性。我这个例子的资源文件放在了classpath路径中,Spring能够自动找到它。
然后是编写一个持久化层的接口,我这个接口是我从一个以前编写的项目中修改来的,大家也可以提提建议,需要哪些方法。
/*
 *  @(#)Repository.java    0.1 06/04/2009
 */
package org.miao.repository;

import java.util.List;
import java.util.Map;

/**
 * 通用Repository接口对象
 * 规定了基本的持久化操作
 * @author Miao
 * @version 0.1
 * @since 0.1
 */
public interface Repository<T> {

    /**
     * 持久化指定对象
     * @param entity 持久化对象
     * @since 0.1
     */
    public void persist(T entity);

    /**
     * 持久化上下文受管
     * @param <T> 返回的受管对象类型
     * @param entity 要被上下文管理的对象
     * @return 受管对象
     * @since 0.1
     */
    public <T> T merge(T entity);

    /**
     * 移除受管对象
     * @param entity 移除的对象
     * @since 0.1
     */
    public void remove(T entity);

    /**
     * 移除受管对象
     * @param entityClass 指定类
     * @param id id主键
     * @since 0.1
     */
    public void remove(Class entityClass, Object id);

    /**
     * 判断该对象是否存在
     * @param entity 判断的对象
     * @return 是否存在
     * @since 0.1
     */
    public boolean contains(T entity);

    /**
     * 刷新受管对象状态
     * 从数据库更新受管对象
     * @param entity 刷新的对象
     * @since 0.1
     */
    public void refresh(T entity);

    /**
     * 刷新受管对象,更新数据库
     * @since 0.1
     */
    public void flush();

    /**
     * 清理上下文中的受管对象
     * @since 0.1
     */
    public void clear();

    /**
     * 查询指定类的指定对象
     * @param entityClass 指定类
     * @param id 主键
     * @return 对象
     * @since 0.1
     */
    public T find(Class entityClass, Object id);

    /**
     * 命名查询
     * @param name 命名名称
     * @return 对象列表
     * @since 0.1
     */
    public List<T> findByByNamedQuery(String name);
    
    /**
     * 带参数的命名查询
     * @param name 命名名称
     * @param parameters 参数
     * @return 对象列表
     * @since 0.1
     */
    public List<T> findByByNamedQuery(String name, Object... parameters);

    /**
     * 通过预定义语句查询
     * @param name 预定义语句名
     * @param parameters 参数
     * @return 对象列表
     * @since 0.1
     */
    public List<T> findByNamed(String name, Map<String, Object> parameters);

    /**
     * 通过预定义语句进行分页查询
     * @param name 预定义语句名
     * @param parameters 参数
     * @param currentPage 当前页
     * @param pageSize 单页记录数量
     * @return 分页组件
     * @since 0.1
     */
    public PageBean<T> findPageByNamed(String name, Map<String, Object> parameters, int currentPage, int pageSize);

    /**
     * 对对象使用读锁
     * @param entity 对象
     * @since 0.1
     */
    public void lockByRead(T entity);

    /**
     * 对对象使用写锁
     * @param entity 对象
     * @since 0.1
     */
    public void lockByWrite(T entity);
}

下面是其实现:
/*
 *  @(#)RepositoryImpl.java    0.1 06/04/2009
 */
package org.miao.repository;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.PersistenceException;
import javax.persistence.Query;
import org.miao.catstorage.Storage;
import org.springframework.orm.jpa.JpaCallback;
import org.springframework.orm.jpa.support.JpaDaoSupport;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * 持久化仓储对象,实现了Repository接口
 * @author Miao
 * @version 0.1
 * @since 0.1
 */
@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
public class RepositoryImpl<T> extends JpaDaoSupport implements Repository<T> {

    /**
     * 用于对查询语句进行count统计的匹配正则表达式
     */
    private Pattern countRegex = Pattern.compile("(SELECT) +(\\w+) +(FROM.*)", Pattern.CASE_INSENSITIVE);
    /**
     * 预定义语句库
     */
    private Storage storage;

    @Transactional(readOnly = false)
    public void persist(T entity) {
        getJpaTemplate().persist(entity);
    }

    @Transactional(readOnly = false)
    public <T> T merge(T entity) {
        return getJpaTemplate().merge(entity);

    }

    @Transactional(readOnly = false)
    public void remove(T entity) {
        getJpaTemplate().remove(entity);
    }

    @Transactional(readOnly = false)
    public void remove(Class entityClass, Object id) {
        getJpaTemplate().remove(find(entityClass, id));
    }

    public boolean contains(T entity) {
        return getJpaTemplate().contains(entity);
    }

    @Transactional(readOnly = false)
    public void refresh(T entity) {
        getJpaTemplate().refresh(entity);
    }

    @Transactional(readOnly = false)
    public void flush() {
        getJpaTemplate().flush();
    }

    @Transactional(readOnly = false)
    public void clear() {
        getJpaTemplate().getEntityManager().clear();
    }

    public T find(Class entityClass, Object id) {
        return (T) getJpaTemplate().find(entityClass, id);
    }

    public List<T> findByByNamedQuery(String name) {
        return getJpaTemplate().findByNamedQuery(name);
    }

    public List<T> findByByNamedQuery(String name, Object... parameters) {
        return getJpaTemplate().findByNamedQuery(name, parameters);
    }

    public List<T> findByNamed(String name, Map<String, Object> parameters) {
        String statement = storage.get(name, parameters);
        if (statement != null) {
            return query(statement, parameters);
        } else {
            throw new PersistenceException("没有找到指定的预定义语句");

        }
    }

    public PageBean<T> findPageByNamed(String name, Map<String, Object> parameters, int currentPage, int pageSize) {
        String statement = storage.get(name, parameters);
        String countStatement = countRegex.matcher(statement).replaceAll("$1 count\\($2\\) $3");
        if (statement != null) {
            int first = PageBean.getFirstResult(currentPage, pageSize);
            long totalResult = (Long) queryStat(countStatement, parameters);
            return new PageBean<T>(currentPage, pageSize, totalResult, query(statement, parameters, first, pageSize));
        } else {
            throw new PersistenceException("没有找到指定的预定义语句");
        }
    }

    /**
     * 查询
     * @param statenemt 查询语句
     * @param parameters 参数
     * @return 查询结果
     * @since 0.1
     */
    private List<T> query(final String statenemt, final Map<String, Object> parameters) {
        return getJpaTemplate().executeFind(
                new JpaCallback() {

                    public Object doInJpa(EntityManager arg0) throws PersistenceException {
                        Query query = arg0.createQuery(statenemt);
                        Iterator<Entry<String, Object>> iterator = parameters.entrySet().iterator();
                        while (iterator.hasNext()) {
                            Entry<String, Object> entry = iterator.next();
                            query.setParameter(entry.getKey(), entry.getValue());
                        }
                        return query.getResultList();
                    }
                });
    }

    /**
     * 分页查询
     * @param statenemt 查询语句
     * @param parameters 参数
     * @param first 起始记录
     * @param pageSize 单页记录数量
     * @return 查询结果
     * @since 0.1
     */
    private List<T> query(final String statenemt, final Map<String, Object> parameters, final int first, final int pageSize) {
        return getJpaTemplate().executeFind(
                new JpaCallback() {

                    public Object doInJpa(EntityManager arg0) throws PersistenceException {
                        Query query = arg0.createQuery(statenemt);
                        Iterator<Entry<String, Object>> iterator = parameters.entrySet().iterator();
                        while (iterator.hasNext()) {
                            Entry<String, Object> entry = iterator.next();
                            query.setParameter(entry.getKey(), entry.getValue());
                        }
                        return query.setFirstResult(first).setMaxResults(pageSize).getResultList();
                    }
                });
    }

    /**
     * 统计查询
     * @param statStatenemt 统计查询语句
     * @param parameters 参数
     * @return 查询结果
     * @since 0.1
     */
    private Object queryStat(final String statStatenemt, final Map<String, Object> parameters) {
        return getJpaTemplate().executeFind(
                new JpaCallback() {

                    public Object doInJpa(EntityManager arg0) throws PersistenceException {
                        Query query = arg0.createQuery(statStatenemt);
                        Iterator<Entry<String, Object>> iterator = parameters.entrySet().iterator();
                        while (iterator.hasNext()) {
                            Entry<String, Object> entry = iterator.next();
                            query.setParameter(entry.getKey(), entry.getValue());
                        }
                        return query.getSingleResult();
                    }
                });
    }

    @Transactional(readOnly = false)
    public void lockByRead(T entity) {
        getJpaTemplate().getEntityManager().lock(entity, LockModeType.READ);
    }

    @Transactional(readOnly = false)
    public void lockByWrite(T entity) {
        getJpaTemplate().getEntityManager().lock(entity, LockModeType.WRITE);
    }

    /**
     * 获得预定义语句库
     * @return 预定义语句库
     * @since 0.1
     */
    public Storage getStorage() {
        return storage;
    }

    /**
     * 设置预定义语句库
     * @param storage 预定义语句库
     * @since 0.1
     */
    public void setStorage(Storage storage) {
        this.storage = storage;
    }
}

该实现使用了Spring的JpaDaoSupport?类,最后在配置文件中把它配置好。
<bean id="repository" class="org.miao.repository.RepositoryImpl">
    <property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>



我本来打算用注释来处理这个Bean,但是entityManagerFactory我无法自动注入,可能是因为JpaDaoSupport?里没有采用注释的原因。 总的来说,在Spring中集成“仓库猫”是非常简单的事情,大家有什么疑问和建议,请和我联系。
0 请登录后投票
   发表时间:2009-08-21  
问一下你的这个框架为什么叫“仓库猫”。。。。
0 请登录后投票
   发表时间:2009-08-21  
之所以叫仓库猫是因为第一,本人超级爱猫;第二,持久化部分在领域驱动设计中被称为“仓储”。所以就叫仓库猫了。
仓库猫已经发展到0.4版了,我这一两天就发布。也可以直接下载源代码。
0 请登录后投票
论坛首页 Java企业应用版

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