• 使用如Hibernate或者JPA作为持久化的解决方案时,设计一个泛型的DAO抽象父类可以方便各个实体的通用CRUD操作。由于此时大部分实体DAO的CRUD操作基本一样,采用泛型设计解决这个问题,带来了简洁代码的好处。
  • 问题的关键在于我们需要在代码中获取抽象DAO父类(BaseEntityDAOImpl<T>)中的泛型信息。
  • 由于Java的泛型是基于泛型擦除实现的,因此无法直接获取如果直接获取,在Java中,如果子类继承一个泛型的父类,会保存父类中泛型的信息,因此可以采用如下方法获取泛型信息。
    public abstract class BaseEntityDAOImpl<T> {
    protected Class<T> entityClass;
    public BaseEntityDAOImpl() {
    // 由于Java 方法的动态绑定getClass()调用的是子类方法
    // getGenericSuperclass()返回直接父类的Type类型,并保存了泛型参数的实际类型信息。
    Type genType = getClass().getGenericSuperclass();
    Type[] params = ((ParameterizedType)genType).getActualTypeArguments();
       // 获取实际的泛型参数的类型信息。
    entityClass = (Class<T>) params[0];
    } }
  • 在获取了泛型参数实际类型之后,以下使用JPA的EntityManager来对通用CRUD操作实现,如下:
public class BaseEntityDAOImpl<T> {
protected Class<T> entityClass;
//@PersistenceContext注解后,entityManager由Spring负责注入
@PersistenceContext
protected EntityManager entityManager;
public BaseEntityDAOImpl() {
Type genType = getClass().getGenericSuperclass();
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
entityClass = (Class<T>) params[0];
} public EntityManager getEntityManager(){
return entityManager;
}
public void setEntityManager(EntityManager entityManager){
this.entityManager=entityManager;
} public void add(T t){
entityManager.persist(t);
}
public void update(T t){
entityManager.merge(t);
}
public T getById(long id){
return entityManager.find(entityClass, id);
}
public void deleteById(long id){
T t=getById(id);
if(t!=null){
entityManager.remove(t);
}
}
public void delete(T t){
entityManager.remove(t);
} public List<T> getListByPage(int offset,int maxResult){ return (List<T>)getEntityManager().createQuery("from "+entityClass.getSimpleName()).setFirstResult(offset).setMaxResults(maxResult).getResultList();
} public List<T> getAll(){
return (List<T>)getEntityManager().createQuery("from "+entityClass.getSimpleName()).getResultList();
} }
  • 使用客户Customer和订单Order两个实体的作为例子,我们可以通过继承泛型的DAO抽象父类来实现实体DAO接口的CRUD,而DAOImpl中没有相关的代码,类图如下:

  • Spring 和JPA集成如下,事务的配置使用注解实现:
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="cn.cjtblog.jpatest"/>
<context:property-placeholder location="classpath:jdbc.properties" />
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url"
value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- 对注解Jpa EntityManager的@PersistenceContext,进行注入 -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="cn.cjtblog.jpatest" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
<property name="jpaDialect" ref="jpaDialect" />
<property name="persistenceProvider" ref="persistenceProvider" />
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property> </bean>
<bean id="persistenceProvider" class="org.hibernate.jpa.HibernatePersistenceProvider" />
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL" />
<property name="showSql" value="true" />
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" /> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>
</beans>

JPA的泛型DAO设计及使用的更多相关文章

  1. 泛型DAO与泛型Service

    泛型Dao与Service 看了几个帖子,泛型Dao与Service的主要目的就是要减少重复代码.具体的说明如下: 1. 定义一个BaseDao接口,此接口包含了一些通用的DAO操作,例如:增加.删除 ...

  2. 一个好用的hibernate泛型dao

    以前从springside2.0上搞下来的很好用的,基本实现dao零编码只要配置xml文件就行了. 先看图: 一共4层,com.demonstration.hibernate.basedao是我加的用 ...

  3. SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装

    SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装 >>>>>>>& ...

  4. 泛型DAO

    最近正在学习泛型DAO,通过网上查阅资料,汇总并自己整理了一下.提前需要学习的知识java反射.泛型 用到的反射如下: Class<T>类 是java.lang包下,Class类的实例表示 ...

  5. 《项目架构那点儿事》——Hibernate泛型Dao,让持久层简洁起来

    [前言]hibernate作为持久层ORM技术,它对JDBC进行非常轻量级对象封装,使得我们可以随心所欲的使用面向对象的思想来操作数据 库.同时,作为后台开发的支撑,的确扮演了一个举足轻重的角色,那么 ...

  6. 自己动手写泛型dao

    在经过一系列的问题得到解决之后,泛型dao终于写出来了.泛型dao相比于以前写的dao最大的好处就是,大大提高了代码的复用性,以往我们要对数据库中表中的数据进行操作的时候,每张表都需要写一个dao来操 ...

  7. 浅谈Java——泛型DAO

    首先解释一下为什么要学习泛型DAO.平时在写DAO的时候是一个接口对应一个实现类,实现类里面要写很多的操作数据库的方法.当我们有很多的javaben的时候我们会写很多的接口和实现类,并且里面的代码都是 ...

  8. Hibernate也须要呵护——Hibernate的泛型DAO

    众所周之.面向对象的基础是抽象.也能够说,抽象促使编程在不断发展. 对于数据库的訪问,以前写过HqlHelper.EFHelper.编写Spring+Hibernate框架下的应用.也相同离不了编写一 ...

  9. 泛型DAO模型设计

    aaarticlea/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKC

随机推荐

  1. 怎么加 一个 hyperlink 到 e-mail template for CRM

    Recently I had a client inquire as to how one would insert a hyperlink into a CRM email template. Wh ...

  2. Script.NET Perl解释器代码已经在GitHub开源发布

    Script.NET Perl解释器的代码已经提交到GitHub网站.GitHub项目地址: https://github.com/blueantst/Script.NET Perl解释器代码在Src ...

  3. 操作系统课堂笔记(2)操作系统的硬件环境之I/O技术和时钟

    I/O技术 1.程序控制I/O技术 有处理器提供相关的IO指令来实现的.主要缺陷是,处理器必须关注IO处理单元的状态,因而它会耗费大量的时间轮询以获得这个信息,这严重降低了系统性能. 2.中断驱动I/ ...

  4. Windows 自己主动关机命令 shuntdown

    以下介绍一个在Windows XP下实现定时关机的简单方法. 一 .倒计时关机:      指定系统在10分钟后自己主动关闭:点击“開始→执行”,输入命令“Shutdown -s -t 60”(注意: ...

  5. mysqltuner

    http://mysqltuner.com/ MySQLTuner-perl MySQLTuner is a script written in Perl that will assist you w ...

  6. careercup-递归和动态规划 9.1

    9.1 有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶.2阶或3阶.实现一个方法,计算小孩有多少种上楼梯的方法. 解法: 我们可以采用自上而下的方式来解决这个问题.小孩上楼梯的最后一步,也就是 ...

  7. Bash String Manipulation Examples – Length, Substring, Find and Replace--reference

    In bash shell, when you use a dollar sign followed by a variable name, shell expands the variable wi ...

  8. WPF柱状图(支持数据库动态更新)

    之前我们讲到wpf组件基类以及组件开发,现在我们围绕之前的内容去开发一个组件. 效果图请加群查看,在群共享里面. 做出这个呢  是比较繁琐的. 首先要使用我们的基类 继承基类的模板自动生成如下几个文件 ...

  9. How to add route for IPV6 interface

    Firewall : ifconfig eth1 inet6 add 2000::1/64 ifconfig eth4 inet6 add 5000::1/64 ------------------- ...

  10. Debian 6解决中文乱码

    DEBIAN下中文显示 一.首先检查LOCALE情况 说明:DEBIAN因为基于GNU所以,对不同地域进行了不同的包支持,以LOCALE形式存在. 1.挂载ISO文件包,前8个ISO包就可以(这里不在 ...