首页 > 代码库 > String框架整合Hibernate
String框架整合Hibernate
在前一个项目SpringDemo的基础上加以改进,将Hibernate整合到项目中。
1、导入Hibernate所需jar包,这里我用的是Hibernate3.3.2版本的。
主要导入这几个包:antlr-2.7.6.jar、commons-collections-3.1.jar、dom4j.jar、ejb3、hibernate3.jar、hibernate-annotations、hibernate-common-annotations、javassist-3.9.0.GA.jar、jta-1.1.jar、slf4j-api.jar、slf4j-nop.jar;此外还有cglib。
缺少jar包,会在运行时出现各奇怪缺包的错误,需根据控制台信息添加jar包。比如ERROR:Ljavax/transaction/TransactionManager;是因为缺少jta.jar包。
我确实还不是很清楚Hibernate中各jar包的功能,好几个包都是根据错误信息逐个添加进去的。
2、这里我采用Spring风格的配置,无需新建hibernate.cfg.html文件,直接在在applicationContext.xml中对Hibernate进行配置。
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 启动包扫描功能,将带有@Controller、@Service、@repository、@Component等注解的类 自动转化为成为spring的bean --> <context:component-scan base-package="com.demo.service" /> <context:component-scan base-package="com.demo.dao" /> <!-- 数据源配置的文件,引入spring容器 --> <context:property-placeholder location="classpath:database.properties" /> <!-- dataSource,配置构建基于DBCP的数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" lazy-init="false" p:driverClassName="${dataSource.driverClassName}" p:url="${dataSource.url}" p:username="${dataSource.username}" p:password="${dataSource.password}" p:maxActive="${dataSource.maxActive}" p:maxIdle="${dataSource.maxIdle}" p:maxWait="${dataSource.maxWait}" /> <!-- 定义jdbcTemplate模版的Bean <bean class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource" /> --> <!-- sessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" p:dataSource-ref="dataSource"> <!-- 这里使用AnnotationSessionFactoryBean,以使用实体类的注解获取ORM配置信息 --> <!-- 若使用LocalSessionFactoryBean,则用mappingLocations属性和xml文件获取配置 --> <property name="annotatedClasses"> <!-- name="packageToScan",则加载包类的带注解实体类 --> <list> <value>com.demo.domain.Account</value> </list> </property> <!-- 指定hibernate配置属性 --> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </prop> <prop key="hibernate.show_sql"> true </prop> </props> </property> </bean> <!-- 定义hibernateTemplete的Bean --> <bean id="hibernateTemplete" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 更改后的Hibernate事务管理配置 --> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <tx:annotation-driven transaction-manager="txManager"/> <!-- 事务管理配置 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource" /> <tx:annotation-driven transaction-manager="transactionManager" /> --> </beans>
注:这里主要是配置了sessionFactory;Spring框架为创建SessionFactory提供了FactoryBean工厂类。
LocalSessionFactoryBean或AnnotationSessionFactoryBean可利用Hibernate配置文件创建SessionFactory代理对象,以便和Spring的事务机制配合工作。
3、在Account实体类中添加注解,使之能被hibernate持久化。package com.demo.domain; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity //@Entity表示该类能被hibernate持久化 @Table(name="user") public class Account { @Id //指定该列为主键 @GeneratedValue(strategy=GenerationType.AUTO) //auto为自增长 private Integer id; @Column(name="name") private String username; @Column(name="password") private String password; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Account(){} }4、修改AccountDaoImpl;把原来的函数注释掉,用注入的hibernateTemplate来进行数据库操作。
修改后的AccountDaoImpl.java代码如下:
package com.demo.dao.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.orm.hibernate3.HibernateTemplate; import org.springframework.stereotype.Repository; import com.demo.dao.AccountDao; import com.demo.domain.Account; @Repository public class AccountDaoImpl implements AccountDao { /*@Autowired private JdbcTemplate jdbcTemplate;*/ @Autowired private HibernateTemplate hibernateTemplate; @Override public int getMatchCount(String username, String password) { return hibernateTemplate.find("from Account a where a.username = ? " + " and a.password = ? ",username, password).size(); } @Override public Account getAcoountById(int id) { return hibernateTemplate.get(Account.class, id); } @Override public Account getAccountByName(String username) { //return hibernateTemplate.get(Account.class, username); //error return (Account) hibernateTemplate.find("from Account a where a.username = ?", username).get(0); } /*@Override public int getMatchCount(String username, String password) { String strSql = "select count(*) from user " + " where name = ? and password = ?";//?为参数占位符 return jdbcTemplate.queryForInt(strSql, new Object[]{ username, password}); } @Override public Account getAcoountById(int id) { String strSql = "select id,name from user " + " where id = ?"; System.out.println("##########execute sql: "+strSql); final Account account = new Account(); jdbcTemplate.query(strSql, new Object[]{ id }, //匿名方式实现的回调函数 new RowCallbackHandler(){ @Override public void processRow(ResultSet rs) throws SQLException { //将查询结果封装到对象实例中 account.setId(rs.getInt("id")); account.setUsername(rs.getString("name")); } }); return account; } @Override public Account getAccountByName(String username) { String strSql = "select id,name from user " + " where name = ?"; System.out.println("##########execute sql: "+strSql); final Account account = new Account(); jdbcTemplate.query(strSql, new Object[]{ username }, //匿名方式实现的回调函数 new RowCallbackHandler(){ @Override public void processRow(ResultSet rs) throws SQLException { //将查询结果封装到对象实例中 account.setId(rs.getInt("id")); account.setUsername(rs.getString("name")); } }); return account; } */ }
注:代码明显短了不少,是不是~~~。
基于模版类使用Hibernate是最简单的方式,HibernateTemplate代理了Hibernate Session的大多数持久化操作,调用也确实简单。
5、运行效果跟之前SpringDemo一样。[2014-11-27 17:40:40,578][DEBUG][org.hibernate.hql.ast.AST:266] - --- HQL AST --- \-[QUERY] 'query' +-[SELECT_FROM] 'SELECT_FROM' | \-[FROM] 'from' | \-[RANGE] 'RANGE' | +-[DOT] '.' | | +-[DOT] '.' | | | +-[DOT] '.' | | | | +-[IDENT] 'com' | | | | \-[IDENT] 'demo' | | | \-[IDENT] 'domain' | | \-[IDENT] 'Account' | \-[ALIAS] 'a' \-[WHERE] 'where' \-[EQ] '=' +-[DOT] '.' | +-[IDENT] 'a' | \-[IDENT] 'username' \-[PARAM] '?' [2014-11-27 17:40:40,579][DEBUG][org.hibernate.hql.ast.ErrorCounter:68] - throwQueryException() : no errors ...... [2014-11-27 17:40:40,716][DEBUG][org.hibernate.SQL:401] - select account0_.id as id0_, account0_.password as password0_, account0_.name as name0_ from user account0_ where account0_.name=? Hibernate: select account0_.id as id0_, account0_.password as password0_, account0_.name as name0_ from user account0_ where account0_.name=? ...... [2014-11-27 17:40:40,812][DEBUG][org.hibernate.jdbc.ConnectionManager:421] - opening JDBC connection [2014-11-27 17:40:40,813][DEBUG][org.hibernate.SQL:401] - select account0_.id as id0_0_, account0_.password as password0_0_, account0_.name as name0_0_ from user account0_ where account0_.id=? Hibernate: select account0_.id as id0_0_, account0_.password as password0_0_, account0_.name as name0_0_ from user account0_ where account0_.id=? ......通过控制台信息,可以看到整合了Hibernate后的运行流程。
用Hibernate作为持久化技术还是比Spring JDBC便捷不少的。
6、总结:通过在Spring中整合Hibernate的Demo,可以发现框架有其各自的优势和不足,整合时的配置方式多样。
Java框架也是巨多,在实际开发,根据需求选择合适的框架即可,不必拘泥于其中一两个。
后面,将继续把Struts2整合到该项目中,这样就搭建起了一个完整基于SSH框架的项目,万里长征第一步。
String框架整合Hibernate