• [Hibernate]


    使用泛型写了一个通用的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>
  • 相关阅读:
    react中关于render渲染次数的性能优化
    ES6中六种常用的传出调用方式
    在Vue-cli中得xxx.vue文件中快速生成组件模板
    如何在Vue-cli中关闭ESLint以及关闭部分ESLint验证
    使用ES6删除对象中某些属性
    React中使用遍历
    git commit报错解决,绕过代码检查
    React学习——子组件给父组件传值
    React学习——通过模态框中的表单,学习父子组件之间传值
    学习axios
  • 原文地址:https://www.cnblogs.com/HD/p/3975250.html
Copyright © 2020-2023  润新知