浏览 2899 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (1) :: 隐藏帖 (6)
|
|
---|---|
作者 | 正文 |
发表时间:2009-04-04
项目地址为http://code.google.com/p/catstorage/ 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间: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中集成“仓库猫”是非常简单的事情,大家有什么疑问和建议,请和我联系。 |
|
返回顶楼 | |
发表时间:2009-08-21
问一下你的这个框架为什么叫“仓库猫”。。。。
|
|
返回顶楼 | |
发表时间:2009-08-21
之所以叫仓库猫是因为第一,本人超级爱猫;第二,持久化部分在领域驱动设计中被称为“仓储”。所以就叫仓库猫了。
仓库猫已经发展到0.4版了,我这一两天就发布。也可以直接下载源代码。 |
|
返回顶楼 | |