[Hibernate] - Generic Dao
使用泛型写了一个通用的Hibernate DAO类。
GenericDao接口
package com.my.dao; import java.io.Serializable;
import java.util.List; /**
* Generic DAO interface
* @author Robin
*
* @param <T>
* @param <PK>
*/
public interface GenericDao<T extends Serializable, PK extends Serializable> {
/**
* Create entity
* @param entity
*/
void create(T entity); /**
* Update entity
* @param entity
*/
void update(T entity); /**
* Create or Update entity
* @param entity POJO
*/
void saveOrUpdate(T entity); /**
* Delete entity
* @param entity
*/
void delete(T entity); /**
* Find entity by id
* @param id ID
* @return Entity
*/
T find(PK id); /**
* Find all entities
* @return
*/
List<T> findAll(); /**
* Find all entities by paging
* @param pageNumber
* @param pageSize
* @return
*/
List<T> findList(int pageNumber, int pageSize); /**
* All row count
* @return
*/
Long count();
}
GenericDaoSupport主类:
package com.my.dao; import javax.annotation.Resource; import org.hibernate.Session;
import org.hibernate.SessionFactory; /**
* Generic Dao Base Class
* @author Robin
*
*/
public abstract class GenericDaoSupport {
@Resource
protected SessionFactory sessionFactory; /**
* Get Hibernate Session
* @return
*/
public Session getSession() {
return this.sessionFactory.getCurrentSession();
}
}
通用DAO类实现:
package com.my.dao.impl; import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List; import org.hibernate.criterion.Projections; import com.my.dao.GenericDao;
import com.my.dao.GenericDaoSupport; /**
* Generic DAO class
* @author Robin
*
* @param <T>
* @param <PK>
*/
@SuppressWarnings("all")
public class GenericDaoImpl<T extends Serializable, PK extends Serializable>
extends GenericDaoSupport implements GenericDao<T, PK> {
// Entity class
private Class<T> entityClass; /**
* Constructor
*/
public GenericDaoImpl() {
// 通过反射获取T的类型信息实例
this.entityClass = (Class<T>) ((ParameterizedType) this.getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
} /**
* Create entity
* @param entity
*/
@Override
public void create(T entity) {
getSession().save(entity);
} /**
* Update entity
* @param entity
*/
@Override
public void update(T entity) {
getSession().update(entity);
} /**
* Create or Update entity
* @param entity
*/
@Override
public void saveOrUpdate(T entity) {
getSession().saveOrUpdate(entity);
} /**
* Delete entity
* @param entity
*/
public void delete(T entity){
getSession().delete(entity);
} /**
* Find entity by id
* @param id
* @return Entity
*/
@Override
public T find(PK id) {
return (T) getSession().get(entityClass, id);
} /**
* Find all entities
* @return
*/
@Override
public List<T> findAll() {
return getSession().createCriteria(entityClass).list();
} /**
* Find all entities by paging
* @param pageNumber
* @param pageSize
* @return
*/
public List<T> findList(int pageNumber, int pageSize) {
return getSession().createCriteria(entityClass)
.setFirstResult((pageNumber - 1) * pageSize)
.setMaxResults(pageSize)
.list();
} /**
* All row count
* @return
*/
public Long count() {
Long count = (Long)getSession().createCriteria(entityClass)
.setProjection(Projections.rowCount())
.uniqueResult();
if(count == null) {
return (long)0;
}
else {
return count;
}
}
}
Hibernate实体:
package com.my.entity; import java.io.Serializable; import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table; @SuppressWarnings("serial")
@Entity
@Table(name = "account")
public class Account implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id; @Column(name = "name", length = 200)
private String name; public long getId() {
return id;
} public void setId(long id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
实体类必需继承Serializable接口。
使用方法例子:
写一个AccountDao接口
package com.my.dao; import org.springframework.stereotype.Repository; import com.my.entity.Account; @Repository
public interface AccountDao extends GenericDao<Account, Long> {
}
AccountDao接口的实现:
package com.my.dao.impl; import org.springframework.stereotype.Repository;
import com.my.dao.AccountDao;
import com.my.entity.Account; @Repository(value = "accountDao")
public class AccountDaoImpl extends GenericDaoImpl<Account, Long> implements AccountDao {
}
Service的实现和使用:
package com.my.service;
import java.util.List;
import com.my.entity.Account;
public abstract class AccountService {
/**
* Add new account
* @param account Account
*/
public abstract void add(Account account);
/**
* Find entity by id
* @param id
* @return
*/
public abstract Account find(long id);
/**
* Find all entities
* @return
*/
public abstract List<Account> findAll();
/**
* Find all entities by paging
* @param pageNumber
* @param pageSize
* @return
*/
public abstract List<Account> findList(int pageNumber, int pageSize);
/**
* All row count
* @return
*/
public abstract long count();
}
package com.my.service.impl; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Service; import com.my.dao.AccountDao;
import com.my.entity.Account;
import com.my.service.AccountService; @Service(value = "accountService")
public class AccountServiceImpl extends AccountService {
@Resource(name = "accountDao")
private AccountDao accountDao; public void add(Account account) {
accountDao.saveOrUpdate(account);
} @Override
public Account find(long id) {
return accountDao.find(id);
} @Override
public List<Account> findAll(){
return accountDao.findAll();
} @Override
public List<Account> findList(int pageNumber, int pageSize) {
return accountDao.findList(pageNumber, pageSize);
} @Override
public long count() {
return accountDao.count();
}
}
可以看到上面Service的调用对应的AccountDao中,不需要再写其它方法。因为在通用DAO中已经实现了。AccountDao只需要加入其它额外的方法即可,比如说特例的查询。
当然可以把通用DAO封装得更加“完美”,比如把查询条件都写上。
网上有一些通用的DAO写法,会把HQL写在Service层,这种破坏了BLL和DAO的分离。
附上Spring的xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1/test" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>com.my.entity</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.hbm2ddl.auto=update
hibernate.show_sql=true
hibernate.format_sql=false
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=false
hibernate.cache.provider_class=org.hibernate.cache.internal.NoCacheProvider
hibernate.current_session_context_class= org.springframework.orm.hibernate4.SpringSessionContext
</value>
</property>
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean> <context:component-scan base-package="com.my" /> <tx:annotation-driven transaction-manager="txManager" />
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*" read-only="true"/>
<tx:method name="add*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="create*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="remove*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="save*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="modify*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="change*" propagation="REQUIRED" rollback-for="Exception"/>
</tx:attributes>
</tx:advice> <aop:config>
<aop:pointcut id="allServiceMethods" expression="execution(* com.my.service.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="allServiceMethods"/>
</aop:config> </beans>
[Hibernate] - Generic Dao的更多相关文章
- Hibernate Generic DAO的介绍安装和使用
java 的包挺多,比c#多 . jar包一个名,解压缩出来又出来又叫另一个名 .搜索起来,内容都分散的很 http://mvnrepository.com maven库搜索 com.googlec ...
- hibernate基础dao类
此文章是基于 搭建SpringMVC+Spring+Hibernate平台 功能:数据库的保存.更新.删除:sql.hql查询:分页查询:调用存储过程 创建hibernate基础dao类: BaseD ...
- hibernate的dao中参数的传递取值
hibernate的dao中参数的传递取值 private Query setParameter(Query query, Map<String, Object> map) { if (m ...
- 《项目架构那点儿事》——Hibernate泛型Dao,让持久层简洁起来
[前言]hibernate作为持久层ORM技术,它对JDBC进行非常轻量级对象封装,使得我们可以随心所欲的使用面向对象的思想来操作数据 库.同时,作为后台开发的支撑,的确扮演了一个举足轻重的角色,那么 ...
- SSH框架整合中Hibernate实现Dao层常用结构
一.疑惑 一直以来,我在使用SSH框架的时候经常会发现后者有疑虑到底使用hibernate的那种方法或者如何配置hibernate来操作数据库,经过 一段时间的学习下面我来总结一下,常用的dao层配置 ...
- Hibernate的Dao层通用设计
hibernate作为一款优秀的数据库持久化框架,在现实的运用中是非常广泛的.它的出现让不熟悉sql语法的程序员能开发数据库连接层成为一种可能,但是理想与现实永远是有差距的.开发过程中如果只使用hql ...
- 一个好用的hibernate泛型dao
以前从springside2.0上搞下来的很好用的,基本实现dao零编码只要配置xml文件就行了. 先看图: 一共4层,com.demonstration.hibernate.basedao是我加的用 ...
- Hibernate通用Dao
1. 接口 package com.coder163.main.dao; import org.hibernate.criterion.DetachedCriteria; import java.io ...
- hibernate的dao操作不能提交到数据库问题的解决
刚学的时候总是各种错误,解决方法也无厘头的很 将UserDAO里面的的save方法修改try { getSession().save(transientInstance); log.debug(&qu ...
随机推荐
- shopex最新版前台一处想不到的SQL注入漏洞
shopex代码核心的地方都做了加密处理,找漏洞就需要一点想象空间了,比如这个SQL注入… 存在于用户注册(想不到的位置吧?) /core/shop/controller/ctl.passport ...
- uva 1151(最小生成树,枚举子集)
题意:平面上有n个点(1<=N<=1000),你的任务是让所有n个点连通,为此,你可以新建一些边,费用等于两个端点的欧几里得距离的平方.另外还有q(0<=q<=8)个套餐,可以 ...
- ios批量打包
最近我们接到了新的需求,需要打出类似xx001-xx100共100个这样的ipa渠道包,不需要签名.(这批ipa包后续会用企业证书签名,不会影响AppStore的) 这些包所有的功能.内容都是一样的, ...
- 安装Pod时提示ERROR: While executing gem ... (Errno::EPERM) Operation not permitted - /usr/bin/pod
环境:OSX EI 10.11.1 昨天切换gem源后,招待pod安装没有任何问题,也可以正常用$ gem sources --add https://ruby.taobao.org/ --remov ...
- SQL Server Profiler教程
SQL Server Profiler是SQL Server企业版自带的一个sql 语句跟踪和分析工具,功能十分强大.熟练地使用它,对我们分析数据库性能问题很有帮助,比如当数据访问使用EF等ORM框架 ...
- 关于MediaPlayer的详细介绍
1)如何获得MediaPlayer实例:可以使用直接new的方式:MediaPlayer mp = new MediaPlayer();也可以使用create的方式,如:MediaPlayer mp ...
- Android的学习——ubuntu下android5.1源码的make编译
在repo sync下载源码后,经历了漫长的时间,终于可以进行下一步了. 在进行make之前还需要三个步骤. 1> source build/envsetup.sh:加载命令 ...
- 单例模式(Singleton Pattern)
动机: 在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性.以及良好的效率. 如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例? 这应该是类设 ...
- c/c++面试题(4)字符串翻转/打印任意进制格式/类型转换
1.字符串的翻转,这里一般是字符数组.不包括字符串字面值. char* reversal_str(char* str,size_t size); 翻转之后的字符串是原来的字符串的翻转. #includ ...
- Android RadioGroup 及资源文件 & selector
RadioGroup :单选组 RadioButton :单选按钮 RadioButton和CheckBox的区别: 1.单个RadioButton在选中后,通过点击无法变为未选中 单 ...