zoukankan      html  css  js  c++  java
  • Spring3整合Hibernate4-我们到底能走多远系列(30)

    我们到底能走多远系列(30)

    扯淡:

      30篇啦!从2012-08-15开始的系列,东平西凑将近一年的时间也就这么几篇。目标的100篇,按这个速度也要再搞两年呢。

      发博客果然不是件容易的事,怪不得更多的人愿意玩微博,125个字,写一个字也可以发了。

      向那些依然坚持稳定码博客的朋友致敬!

    主题:

      用spring整合hibernate也算是java web开发的入门必学的东西了,多年下来没怎么用过hibernate。

      所以记录下基础的整合知识,以及如何构建一些共通的代码,减少dao层的工作量。

      项目使用maven构建,关于maven的构建知识可以参考:摸我

      整合只使用了一个配置文件,hibernate方面使用注解方式映射数据库表。

    data-source.xml:

    <?xml version="1.0" encoding="UTF-8" ?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:jdbc="http://www.springframework.org/schema/jdbc"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
             http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
        "
        default-autowire="byName">
        <context:component-scan base-package="com.sz.sh.dal.dao.hibernate,com.sz.sh.dal.dao.dateobject">
        </context:component-scan>
        <!-- 使用常规的BasicDataSource 来配置DataSource-->
        <bean id="shDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName" value="com.mysql.jdbc.Driver" />
            <property name="url" value="${sh.jdbc.url}" />
            <property name="username" value="${sh.jdbc.username}" />
            <property name="password" value="${sh.jdbc.password}" />
            <property name="initialSize" value="1" />
            <property name="maxIdle" value="30" />
            <property name="maxWait" value="10000" />
            <property name="minIdle" value="1" />
            <property name="removeAbandoned" value="true" />
            <property name="removeAbandonedTimeout" value="180" />
            <!-- validate connection 检测配置 -->
            <property name="testWhileIdle" value="true" />
            <property name="testOnBorrow" value="false" />
            <property name="testOnReturn" value="false" />
            <property name="validationQuery">
                <value>SELECT @@SQL_MODE</value>
            </property>
            <property name="numTestsPerEvictionRun">
                <value>30</value>
            </property>
            <property name="timeBetweenEvictionRunsMillis">
                <value>60000</value>
            </property>
            <property name="minEvictableIdleTimeMillis">
                <value>1800000</value>
            </property>
        </bean>
        <bean id="transactionManager"
            class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="shDataSource" />
        </bean>
    
        <bean id="transactionTemplate"
            class="org.springframework.transaction.support.TransactionTemplate">
            <property name="transactionManager" ref="transactionManager" />
        </bean>
        <bean id="shSessionFactory"
            class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
            <property name="dataSource" ref="shDataSource" />
            <property name="packagesToScan">
                <list>
                    <value>com.sz.sh.dal.dao.dateobject</value>
                </list>
            </property>
            <!--  如果用xml来描述hibernate的bean,就需要以下的配置
            <property name="mappingResources"> 
                <list> 
                    <value>cn/sh/model/user.hbm.xml</value> 
                   </list> 
            </property>
            -->
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.default_schema">wxassistant</prop>
                    <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
                    <prop key="hibernate.show_sql">true</prop>
                    <prop key="hibernate.format_sql">true</prop>
                    <prop key="hibernate.hbm2ddl.auto">update</prop>
                    <prop key="hibernate.query.substitutions">false</prop>
                    <prop key="hibernate.default_batch_fetch_size">20</prop>
                    <prop key="hibernate.max_fetch_depth">2</prop>
                    <prop key="hibernate.generate_statistics">true</prop>
                </props>
            </property>
        </bean>
        <aop:aspectj-autoproxy expose-proxy="true" /><!-- 开启注解事务 只对当前配置文件有效 -->
        <tx:annotation-driven transaction-manager="txManager" />
        <bean id="txManager"
            class="org.springframework.orm.hibernate4.HibernateTransactionManager">
            <property name="sessionFactory" ref="shSessionFactory" />
        </bean>
        <tx:advice id="txAdvice" transaction-manager="txManager">
            <tx:attributes>
                <tx:method name="save*" propagation="REQUIRED" />
                <tx:method name="add*" propagation="REQUIRED" />
                <tx:method name="create*" propagation="REQUIRED" />
                <tx:method name="insert*" propagation="REQUIRED" />
                <tx:method name="update*" propagation="REQUIRED" />
                <tx:method name="merge*" propagation="REQUIRED" />
                <tx:method name="del*" propagation="REQUIRED" />
                <tx:method name="remove*" propagation="REQUIRED" />
                <tx:method name="put*" propagation="REQUIRED" />
                <tx:method name="use*" propagation="REQUIRED" />
                <tx:method name="get*" propagation="REQUIRED" read-only="true" />
                <tx:method name="count*" propagation="REQUIRED" read-only="true" />
                <tx:method name="find*" propagation="REQUIRED" read-only="true" />
                <tx:method name="list*" propagation="REQUIRED" read-only="true" />
                <tx:method name="*"  propagation="REQUIRED" read-only="true" />
            </tx:attributes>
        </tx:advice>
        <aop:config expose-proxy="true"><!-- 只对业务逻辑层实施事务 -->
            <aop:pointcut id="txPointcut"
                expression="execution(* com.sz.sh.dal.dao.hibernate.*.*(..))" />
            <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
        </aop:config>
        <!--hibernate4必须配置为开启事务 否则 getCurrentSession()获取不到  -->
        <aop:config expose-proxy="true">
            <aop:pointcut id="basePointcut"
                expression="execution(* com.sz.sh.dal.common.*.*(..))" />
            <aop:advisor advice-ref="txAdvice" pointcut-ref="basePointcut" />
        </aop:config>
    </beans>
    View Code

    项目目录结构:

    基础DAO:

    定义最基本的方法。

    public interface BaseDAO<M extends java.io.Serializable, PK extends java.io.Serializable> {
    
        public PK save(M model);
        
        public void saveOrUpdate(M model);
        
        public void update(M model);
        
        public List<M> findByExample(M model);
        
        public List<M> findByCriterion(Criterion criterion, Order order, Integer offset, Integer length);
        
        public List<M> findByProperty(Map<String, Object> param, int offset, int length);
        
        public void merge(M model);
        
        public void delete(PK id);
        
        public boolean exists(PK id);
        
        public M get(PK id);
        
        public List<M> getALL();
        
        public Long countALL();
    }

    基础DAO实现:核心的实现类

    本抽象类中,实现了一些安主键查询,分页查询,添删改,等一些基本的操作。

    而且,基本涵盖了一些常用的利用hibernate处理数据库的不同方法。

    /**
     * @0 getSession().createQuery HQL查询
     * @1 getSession().createSQLQuery NATIVE sql 查询 使用 NATIVE sql可能出现属性类型
     * sess.createSQLQuery("SELECT * FROM CATS").addScalar("ID", Hibernate.LONG).addScalar("NAME")
     * sess.createSQLQuery("SELECT ID NAME, BIRTHDATE FROM CATS").addEntity(Cat.class
     * @2 getSession().createCriteria Criteria 查询 @ *
     * @param <M>
     * @param <PK>
     */
    @MappedSuperclass
    public abstract class BaseDAOHib<M extends java.io.Serializable, PK extends java.io.Serializable> implements BaseDAO<M , PK>{
    
        protected static final Logger LOGGER = LoggerFactory.getLogger(BaseDAOHib.class);
    
        private Class<M>              entityClass;
        private String                HQL_LIST_ALL;
        private String                HQL_COUNT_ALL;
        private String                pkName = "Id";
    
        @SuppressWarnings("unchecked")
        public BaseDAOHib(){
            this.entityClass = (Class<M>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
            // TODO @Entity name not null
            HQL_LIST_ALL = "from " + this.entityClass.getSimpleName() + " order by " + pkName + " desc";
            HQL_COUNT_ALL = " select count(*) from " + this.entityClass.getSimpleName();
        }
    
        @Autowired
        @Qualifier("shSessionFactory")
        private SessionFactory sessionFactory;
    
        public Session getSession() {
            // 事务必须是开启的(Required),否则获取不到
            return sessionFactory.getCurrentSession();
        }
    
        @SuppressWarnings("unchecked")
        public PK save(M model) {
            return (PK) getSession().save(model);
        }
    
        public void saveOrUpdate(M model) {
            getSession().saveOrUpdate(model);
        }
    
        public void update(M model) {
            getSession().update(model);
    
        }
    
        public List<M> findByExample(M model) {
            List<M> results = getSession().createCriteria(this.entityClass).add(Example.create(model)).list();
            return results;
        }
    
        public List<M> findByCriterion(Criterion criterion, Order order, Integer offset, Integer length) {
            Criteria criteria = getSession().createCriteria(this.entityClass);
            criteria.add(criterion);
    
            if (order != null) {
                criteria.addOrder(order);
            }
            if (offset != null) {
                criteria.setFirstResult(offset);
            }
            if (length != null) {
                criteria.setMaxResults(length);
            }
            return criteria.list();
        }
    
        public List<M> findByProperty(Map<String, Object> param, int offset, int length) {
    
            StringBuffer queryString = new StringBuffer("from " + this.entityClass.getSimpleName() + "  where ");
            List<Object> values = new ArrayList<Object>();
            boolean firstparam = true;
            for (Map.Entry<String, Object> entry : param.entrySet()) {
                values.add(entry.getValue());
                if (!firstparam) {
                    queryString.append(" and ");
                }
                queryString.append(entry.getKey() + "= ? ");
                firstparam = false;
            }
            Query queryObject = getSession().createQuery(queryString.toString());
    
            for (int i = 0; i < values.size(); i++) {
                queryObject.setParameter(0, values.get(i));
            }
    
            return queryObject.list();
    
        }
    
        public void merge(M model) {
            getSession().merge(model);
        }
    
        public void delete(PK id) {
            getSession().delete(this.get(id));
    
        }
    
        public boolean exists(PK id) {
            return get(id) != null;
        }
    
        public M get(PK id) {
            return (M) getSession().get(this.entityClass, id);
        }
    
        public List<M> getALL() {
            return getSession().createQuery(HQL_LIST_ALL).list();
        }
    
        public Long countALL() {
            return (Long) getSession().createQuery(HQL_COUNT_ALL).uniqueResult();
        }
    
    }

    具体对应表的DAO:注意继承BaseDAO 这样默认接口继承者实现基础类的共通方法。

    public interface CategoryDAO extends BaseDAO<CategoryDO,Long>{
    
        public List<CategoryDO> getAllCategory();
        
        public CategoryDO getCategoryById(Long id);
    }

    具体对应表的DAO接口继承者: 继承了基础DAO的实现,这样一来就不需要自己实现了。

    如此就实现了,所有对应表的DAO都公用了一份基础DAO实现。大大的减少了DAO层的开发时间,降低了DAO层的bug率。

    @Repository("categoryDAO")
    public class CategoryDAOHibernate extends BaseDAOHib<CategoryDO,Long> implements CategoryDAO{
    
        @Override
        public List<CategoryDO> getAllCategory() {
            return super.getALL();
        }
    
        @Override
        public CategoryDO getCategoryById(Long id) {
            return get(id);
        }
    }

    另外贴上pom.xml:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>work</groupId>
      <artifactId>Spring_Hibernate</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>jar</packaging>
    
      <name>Spring_Hibernate</name>
      <url>http://maven.apache.org</url>
        
        <profiles>
            <!-- 开发环境,默认激活 -->
            <profile>
                <id>dev</id>
                <properties>
                    <env>dev</env>
                    <maven.test.skip>true</maven.test.skip>
                </properties>
                <activation>
                    <activeByDefault>true</activeByDefault>
                </activation>
            </profile>
        </profiles>
        
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-version>3.1.1.RELEASE</spring-version>
      </properties>
    
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.7.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.10</version>
        </dependency>
        <!-- ================================================= -->
        <!-- Spring框架 -->
        <!-- ================================================= -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring-version}</version>
        </dependency>
    
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <!-- ================================================= -->
        <!-- Hibernate -->
        <!-- ================================================= -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.1.9.Final</version>
        </dependency>
        
        <!-- ================================================= -->
        <!-- 日志及相关依赖(用slf4j+logback代替jcl+log4j) -->
        <!-- ================================================= -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.1</version>
        </dependency>
        <!-- 将现有的jakarta commons logging的调用转换成lsf4j的调用。 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.6.1</version>
        </dependency>
        <!-- Hack:确保commons-logging的jar包不被引入,否则将和jcl-over-slf4j冲突 -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
            <scope>provided</scope>
        </dependency>
        <!-- slf4j的实现:logback,用来取代log4j。更快、更强! -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>0.9.24</version>
            <scope>runtime</scope>
        </dependency>
      </dependencies>
      <build>            
    
            <defaultGoal>install</defaultGoal>
            <filters>
                <filter>${user.dir}/env/filter-${env}.properties</filter>
            </filters>
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                    <filtering>true</filtering>
                </resource>    
            </resources>    
    
        </build>
    </project>
    View Code

    让我们继续前行

    ----------------------------------------------------------------------

    努力不一定成功,但不努力肯定不会成功。
    共勉。

  • 相关阅读:
    9.Vue技术栈开发实战-使用Mock模拟Ajax请求
    8.Vue技术栈开发实战-Ajax请求实战
    7.Vue技术栈开发实战-状态管理Vuex进阶
    6.Vue技术栈开发实战-状态管理Vuex(二)
    5.Vue技术栈开发实战-状态管理Vuex(一)
    4.Vue技术栈开发实战-状态管理bus的使用
    3.Vue技术栈开发实战-路由进阶篇
    2.Vue技术栈开发实战-路由基础篇
    Vue技术栈开发实战_汇总贴
    1.Vue技术栈开发实战-使用vue-cli3创建项目
  • 原文地址:https://www.cnblogs.com/killbug/p/3187099.html
Copyright © 2011-2022 走看看