我们到底能走多远系列(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>

项目目录结构:

基础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>

让我们继续前行

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

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

最新文章

  1. html基本知识点
  2. Leetcode 9 Palindrome Number 数论
  3. JS正则表达式基础
  4. [转]GCC参数详解
  5. Ubuntu 64位系统安装StarUML之最佳实践
  6. hdu5773--The All-purpose Zero(LIS变形)
  7. ARCGIS二维三维放大缩小
  8. sql查询当天数据
  9. Java Socket 入门1
  10. angularjs入门学习【指令篇】
  11. MySQL注射的过滤绕过技巧
  12. libevent之event_base
  13. struts.xml,报错 1 c.opensymphony.xwork2.util.DomHelper
  14. 2156: 中南大学2018年ACM暑期集训前期训练题集(入门题) D: 机器人的指令
  15. myEclipse开发内存溢出解决办法myEclipse调整jvm内存大小java.lang.OutOfMemoryError: PermGen space及其解决方法
  16. 【BZOJ】3143: [Hnoi2013]游走
  17. 吴裕雄 20-MySQL NULL 值处理
  18. Hadoop生态圈-Azkaban实战之Command类型执行指定脚本
  19. angular之service、factory预provider区别
  20. 基于Promise规范的fetch API的使用

热门文章

  1. jdk和tomcat环境部署
  2. 监听TelephonyManager的通话状态来监听手机的所有的来电
  3. uva 1428
  4. appjs desktop
  5. VisualSVN SERVER的安装和使用
  6. 【C语言学习】-02 分支结构
  7. POJ 2559 Program C
  8. eval函数的缺陷
  9. iOS 使用两个tableview的瀑布流
  10. Event Handling on Mac