[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 ...
随机推荐
- linux 删除用户
userdel可删除用户帐号与相关的文件.若不加参数,则仅删除用户帐号,而不删除相关文件命 令: userdel 功能说明:删除用户帐号. 语 法:userdel [-r][用户帐号] 补充说明:us ...
- iOS基础篇(十五)——UIScrollView的基本用法
滚动视图(UIScrollView)通常用于显示内容尺寸大于屏幕尺寸的视图. 一.基本属性 1.CGSize contentSize :设置UIScrollView的滚动范围 2.CGPoint co ...
- JAVA OOP 基础知识提纲
OOP: 面向对象: 认识事物的一个过程,是整体(特征/行为) 认识事物的方式.人类认识事物的自然思维习惯. 对象及类 对象是实实在在具体存在的东西,主要是从两个角度(行为,特征)去观察 类:是一组具 ...
- Linux准确获取IP
有时搞一些跨网段的工程和应用,需要尽量准确的知道电信.网通.铁通等电信运营商的IP地址段分配情况,可网上的资料不但很少,而且经常都是N个月前的过期资料…… APNIC是管理亚太地区IP地址分配的机构, ...
- sql2008 无法附加数据库
sql2008 因为数据库正在使用,所以无法获得对数据库的独占访问权---还原或删除数据库的解决方法 数据库还原出现 3154错误 --主备份 --RESTORE DATABASE [NET_CN] ...
- jquery Mobile弹出窗
先创建一个窗体 <div data-role="popup" id="popupView" class="ui-content" da ...
- JVM-class文件完全解析-属性表集合
属性表集合 在前面魔数,次版本号,主板本号,常量池入口,常量池,访问标志,类索引,父类索引,接口索引集合,字段表集合,方法表集合,那么接下来就是属性表集合了. 在class文件,字段表,方法表都可 ...
- poj3660 floyd
//Accepted 176 KB 16 ms //一头牛,如果rank是能确定的,那么能打败他的牛的个数和被他打败的牛的个数的总和为n-1 #include <cstdio> #incl ...
- 关于Python脚本开头两行的:#!/usr/bin/python和# -*- coding: utf-8 -*-的作用 – 指定文件编码类型
#!/usr/bin/python指定用什么解释器运行脚本以及解释器所在的位置 # -*- coding: utf-8 -*-用来指定文件编码为utf-8的PEP 0263 -- Defining P ...
- C# 多线程写文件,时常写不成功
在项目中,做一个文本日志功能 为了不影响页面响应速度,所以使用了多线程,在测试的时候,风险文件写入时常不成功,经过一番周折, 发现th.IsBackground = true;后台线程不为主线程的子线 ...