标签:spring web java javaweb 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框架的项目,万里长征第一步。
标签:spring web java javaweb hibernate
原文地址:http://blog.csdn.net/dutsoft/article/details/41548537