[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笔记:shell基础-bash基本功能
历史命令的调用: 命令和文件补全(如果当前有多个可选的补全,则按2次tab键,可以列出所有的可选项): 命令别名: 让别名永久生效: 删除别名: bash常用快捷键: 标准输入输出: 输出重定向: 输 ...
- <select>的下拉样式
今天做一个专题,其中,select标签的样式要做成下图的模样,但是默认情况是下下图的模样: 如何实现呢,实现的办法竟然比我想象中的简单好多: select{ border: solid 1px #00 ...
- c语言完成分块查找
首先要把一系列数组均匀分成若干块(最后一个可以不均匀) 每块中元素任意排列,即块中数字无序,但是整个块之间要有序.因此也存在局限性. #include<stdio.h> //分块查找法 v ...
- 给一个div绝对定位后,如何让它水平居中
<style> .footer{position:absolute;left:0;right:0} </style> <div classs="footer&q ...
- 使用OpenFileDialog会更改默认程序目录
这个问题可能只有在特定的程序中会发现:当我们在程序中使用相对路径时是依赖于当前目录的.所以在使用类似代码: XElement rootNode = XElement.Load(@"zips/ ...
- git add 命令添加所有改动内容
git add xx命令可以将xx文件添加到暂存区,如果有很多改动可以通过 git add -A .来一次添加所有改变的文件. 注意 -A 选项后面还有一个句点. git add -A表示添加所有内容 ...
- Java MVC Controller 中通过不同方式获取 @PathVariable 参数值
1.最常用,也是最直接使用方法,通过@PathVariable注解获取 @RequestMapping(value = "/test/{a}") public @ResponseB ...
- ionic 安装遇到的问题以及解决方案
公司里要用到 Ionic 做移动App 混合开发 一个环境搭建折腾了好几天.一是公司权限问题,二是网络问题,你懂得. Ionic 环境搭建官网有教程.本来几行命令就能搞定的事,一旦遇到网络问题,就蛋疼 ...
- IT公司100题-27-跳台阶问题
问题描述: 一个台阶总共有n阶,一次可以跳1级或者2级.求总共有多少种跳法. 分析: 用f(n)表示n阶台阶总共有多少种跳法.n阶台阶,第一可以选择跳1阶或者2阶,则f(n) = f(n-1) + ...
- 计算机网络(1)-----网络层IP协议概述
网络层(Network Layer) 概念 网络层是OSI参考模型中的第三层,介于传输层和数据链路层之间,它在数据链路层提供的两个相邻端点之间的数据帧的传送功能上,进一步管理网络中的数据通信,将数据设 ...