`
周一Monday
  • 浏览: 342853 次
  • 来自: 北京
社区版块
存档分类
最新评论

Spring之Spring2.5集成Hibernate3.6

阅读更多

 搭建开发环境:

Spring2.5需要的JAR文件:

spring-framework-2.5.6\dist\spring.jar

spring-framework-2.5.6\lib\jakarta-commons\commons-logging.jar

spring-framework-2.5.6\lib\aspectj\aspectjweaver.jar

 

Hibernate3.6需要的JAR文件

hibernate-distribution-3.6.0.Final\hibernate3.jar

hibernate-distribution-3.6.0.Final\lib\required\*

hibernate-distribution-3.6.0.Final\lib\jpa\hibernate-jpa-2.0-api-1.0.0.Final.jar

 

数据库驱动包

mysql-connector-java-5.1.7-bin.jar

 

方式一:

 

1.实体类与映射文件

package org.monday.hibernate1;

import java.util.Date;

public class Emp {

	private int id; // 编号
	private String name; // 姓名
	private int age; // 年龄
	private double salary; // 薪水
	private Date birthday; // 生日

	public Emp() {
	}

	public Emp(int id, String name, int age, double salary, Date birthday) {
		this.id = id;
		this.name = name;
		this.age = age;
		this.salary = salary;
		this.birthday = birthday;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	@Override
	public String toString() {
		return "Emp [id=" + id + ", name=" + name + ", age=" + age
				+ ", salary=" + salary + ", birthday=" + birthday + "]";
	}

}

 

 

Emp.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.monday.hibernate1">
	<class name="Emp" table="EMP">
		<id name="id">
			<generator class="assigned" />
		</id>
		<property name="name" />
		<property name="age" />
		<property name="salary" />
		<property name="birthday" />
	</class>
</hibernate-mapping>

 

2.开发Dao

package org.monday.hibernate1;

import java.util.List;

public interface EmpDao {

	/** 插入 */
	public void insert(Emp emp);

	/** 更新*/
	public void update(Emp emp);

	/** 删除*/
	public void delete(Emp emp);
	
	/** 根据id删除 */
	public void delete(int id);

	/** 根据id查询雇员的详细信息 */
	public Emp findById(int id);

	/** 查询全部雇员信息 */
	public List<Emp> findAll();

	/** 根据雇员姓名查询其薪水 */
	public double findSalary(String name);

	/** 查询部总记录数 */
	public int totalCount();

	/** 批量插入 */
	public void insertBatch(List<Emp> emps);

	/** 批量删除 */
	public void deleteBatch(int... ids);
}

 

3.开发Dao实现类

package org.monday.hibernate1;

import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository("empDao")
public class EmpDaoImpl implements EmpDao {

	@Resource
	private SessionFactory sessionFactory;

	/*
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}
	*/
	
	/** 取得当前可用的Session */
	private Session getSession(){
		return sessionFactory.getCurrentSession();
	}
	
	/** 插入 */
	@Transactional
	public void insert(Emp emp) {
		getSession().save(emp);
	}

	/** 更新 */
	@Transactional
	public void update(Emp emp) {
		getSession().update(emp);
	}

	/** 删除 */
	@Transactional
	public void delete(Emp emp) {
		getSession().delete(emp);
	}

	/** 根据id删除 */
	@Transactional
	public void delete(int id) {
		/** 方法一 */
		/*
		Emp emp=(Emp) getSession().get(Emp.class,id);
		getSession().delete(emp);
		*/
		/** 方法二*/
		getSession().createQuery("delete from Emp where id=?").setParameter(0, id).executeUpdate();
	}

	/** 根据id查询雇员的详细信息 */
	@Transactional(readOnly=true)
	public Emp findById(int id) {
		return (Emp) getSession().get(Emp.class,id);
	}

	/** 查询全部雇员信息 */
	@Transactional(readOnly=true)
	public List<Emp> findAll() {
		return getSession().createQuery("from Emp").list();
	}

	/** 根据雇员姓名查询其薪水 */
	@Transactional(readOnly=true)
	public double findSalary(String name) {
		return (Double) getSession().createQuery("select e.salary from Emp e where e.name=?").setParameter(0, name).uniqueResult();
	}

	/** 查询部总记录数 */
	@Transactional(readOnly=true)
	public int totalCount() {
		return Integer.parseInt( getSession().createQuery("select count(id) from Emp").uniqueResult()+"");
		
		//return (Integer) getSession().createQuery("select count(id) from Emp").uniqueResult();
		//会抛出java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
	}

	/** 批量插入 */
	@Transactional
	public void insertBatch(List<Emp> emps) {
		for (int i = 0; emps != null && i < emps.size(); i++) {
			getSession().save(emps.get(i));
			if(i%20==0){
				getSession().flush();
				getSession().clear();
			}
		}	
	}

	/** 批量删除 */
	@Transactional
	public void deleteBatch(int... ids) {
		/** 方法一 */
		for (int i = 0; ids != null && i < ids.length; i++) {
			Emp emp=(Emp) getSession().get(Emp.class,ids[i]);
			getSession().delete(emp);
			if(i%20==0){
				getSession().flush();
				getSession().clear();
			}
		}
		
		/** 方法二*/
		/*
		StringBuffer hql=new StringBuffer();
		hql.append("delete from Emp where id in");
		hql.append("(");
		for (int i = 0; ids != null && i < ids.length; i++) {
			if(i==ids.length-1){
				hql.append("?");
			}else{
				hql.append("?,");
			}
		}
		hql.append(")");
		Query query=getSession().createQuery(hql.toString());
		for (int j=0; ids != null && j < ids.length; j++) {
			query.setParameter(j, ids[j]);
		}
		query.executeUpdate();
		*/
		
		/** 方法三*/
		/*
		StringBuffer hql=new StringBuffer();
		hql.append("delete from Emp where id in");
		hql.append("(");
		for (int i = 0; ids != null && i < ids.length; i++) {
			if(i==ids.length-1){
				hql.append(ids[i]);
			}else{
				hql.append(ids[i]+",");
			}
		}
		hql.append(")");
		getSession().createQuery(hql.toString()).executeUpdate();
		*/
	}
}

 

这里的操作需要通过Spring容器来注入SessionFactory,从而获取Session进行一系列Hibernate操作,而不依赖于Spring的API,只不过SessionFactory要依赖Spring容器来注入。而事务使用注解配置。

 

4.Spring的配置文件beans.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:tx="http://www.springframework.org/schema/tx"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
	http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/tx
	http://www.springframework.org/schema/tx/spring-tx.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd">

	<!-- 配置注解扫描器 -->
	<context:annotation-config/>
	<!-- 指定要扫描的包 -->
	<context:component-scan base-package="org.monday.hibernate1"/>
	<!-- 将Hibernate的异常转变成Spring的DataAccessException异常 -->
	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

	<!-- 配置sessionFactory -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
		<property name="mappingLocations" value="org/monday/hibernate1/*.hbm.xml"/>
	</bean>
	
	<!-- 配置事务 -->
	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"/>
	</bean>
	<tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

 5.测试

package org.monday.hibernate1;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

	private ApplicationContext ctx = new ClassPathXmlApplicationContext("org/monday/hibernate1/beans1.xml");
	private EmpDao empDao = (EmpDao) ctx.getBean("empDao");

	@Test
	public void testInsert() {
		Emp emp = new Emp(101, "zy_test1", 21, 3000, randomDate("1980-01-01","1999-12-31"));
		empDao.insert(emp);
	}

	@Test
	public void testUpdate() {
		Emp emp = new Emp(1, "zy_test", 19, 1000, randomDate("1980-01-01","1999-12-31"));
		empDao.update(emp);
	}

	@Test
	public void testDeleteEmp() {
		Emp emp = new Emp();
		emp.setId(100);
		empDao.delete(emp);
	}

	@Test
	public void testDeleteInt() {
		empDao.delete(99);
	}

	@Test
	public void testFindById() {
		Emp emp = empDao.findById(1);
		System.out.println(emp);
	}

	@Test
	public void testFindAll() {
		List<Emp> list = empDao.findAll();
		for (Emp e : list) {
			System.out.println(e);
		}
	}

	@Test
	public void testFindSalary() {
		double salary = empDao.findSalary("zy_test");
		System.out.println(salary);
	}

	@Test
	public void testTotalCount() {
		int count = empDao.totalCount();
		System.out.println("共" + count + "条记录");
	}

	@Test
	public void testInsertBatch() {
		List<Emp> emps = new ArrayList<Emp>();
		for (int i = 1; i <= 100; i++) {
			int age = (int) (Math.random() * 100) + 1;
			double salary = (int) (Math.random() * 3000) + 1;
			Emp emp = new Emp(i, "zy_test" + i, age, salary, randomDate("1980-01-01", "1999-12-31"));
			emps.add(emp);
		}
		empDao.insertBatch(emps);
	}

	@Test
	public void testDeleteBatch() {
		int[] ids = {96,95};
		empDao.deleteBatch(ids);
	}

	/** 在给定的日期范围内生成随即日期 */
	private static Date randomDate(String beginDate, String endDate) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		try {
			long start = format.parse(beginDate).getTime();
			long end = format.parse(endDate).getTime();
			long time = Math.abs(start + (long) (Math.random() * (end - start)));
			return new Date(time);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}

 

方式二:

直接看Dao实现类吧

package org.monday.hibernate2;

import java.util.List;

import org.springframework.orm.hibernate3.HibernateTemplate;

public class EmpDaoImpl implements EmpDao {

	private HibernateTemplate hibernateTemplate;

	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

	/** 插入 */
	public void insert(Emp emp) {
		hibernateTemplate.save(emp);
	}

	/** 更新 */
	public void update(Emp emp) {
		hibernateTemplate.update(emp);
	}

	/** 删除 */
	public void delete(Emp emp) {
		hibernateTemplate.delete(emp);
	}

	/** 根据id删除 */
	public void delete(int id) {
		Emp emp = (Emp) hibernateTemplate.get(Emp.class, id);
		hibernateTemplate.delete(emp);
	}

	/** 根据id查询雇员的详细信息 */
	public Emp findById(int id) {
		return (Emp) hibernateTemplate.get(Emp.class, id);
	}

	/** 查询全部雇员信息 */
	public List<Emp> findAll() {
		return hibernateTemplate.find("from Emp");
	}

	/** 根据雇员姓名查询其薪水 */
	public double findSalary(String name) {
		List<Double> list = hibernateTemplate.find("select e.salary from Emp e where e.name=?", name);
		return list.size() > 0 ? list.get(0) : 0;
	}

	/** 查询部总记录数 */
	public int totalCount() {
		List<Long> list = hibernateTemplate.find("select count(*) from Emp");
		return list.size() > 0 ? Integer.parseInt(list.get(0)+"") : 0;
	}

	/** 批量插入 */
	public void insertBatch(List<Emp> emps) {
		for (int i = 0; emps != null && i < emps.size(); i++) {
			hibernateTemplate.save(emps.get(i));
			if (i % 20 == 0) {
				hibernateTemplate.flush();
				hibernateTemplate.clear();
			}
		}
	}

	/** 批量删除 */
	public void deleteBatch(int... ids) {
		/** 方法一 */
		for (int i = 0; ids != null && i < ids.length; i++) {
			Emp emp = (Emp) hibernateTemplate.get(Emp.class, ids[i]);
			hibernateTemplate.delete(emp);
			if (i % 20 == 0) {
				hibernateTemplate.flush();
				hibernateTemplate.clear();
			}
		}
	}
}

 这里注入的不在是SessionFactory而是HibernateTemplate,这是Spring为辅助Hibernate开发提供的模版类。

而事务不用注解了(之前写过了),用XML配置注解

此时Spring的配置文件编写如下:

<?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: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.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd
	http://www.springframework.org/schema/tx
	http://www.springframework.org/schema/tx/spring-tx.xsd">

	
	<!-- 配置数据库连接信息 -->
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
		<property name="url" value="jdbc:mysql://localhost:3306/spring"/>
		<property name="username" value="root"/>
		<property name="password" value="root"/>
	</bean>

	<!-- 配置sessionFactory -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource"/>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop>
			</props>
		</property>
		<!-- 
			个人觉得这么配置方便,不用将所有的映射文件都列出来,因为有时会忘记配置映射文件
		 -->
		 <property name="mappingLocations" value="org/monday/hibernate2/*.hbm.xml"/>
		<!-- 
			或者
			<property name="mappingResources">
			<list>
				<value>org/monday/hibernate2/Emp.hbm.xml</value>
			</list>
		</property>
		 -->
		
	</bean>
	
	<!-- 配置DAO -->
	<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
		<property name="sessionFactory" ref="sessionFactory"/>
	</bean>
	<bean id="empDao" class="org.monday.hibernate2.EmpDaoImpl">
		<property name="hibernateTemplate" ref="hibernateTemplate"/>
	</bean>
	
	<!-- 配置事务 -->
	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"/>
	</bean>
	<tx:advice id="tx" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="*"/>
			<tx:method name="find*" read-only="true"/>
		</tx:attributes>
	</tx:advice>
	<aop:config>
		<aop:pointcut id="perform" expression="execution( * org.monday.hibernate2.*.*(..))" />
		<aop:advisor advice-ref="tx" pointcut-ref="perform"/>
	</aop:config>

</beans>

 

方式三:

直接看Dao实现类吧。

package org.monday.hibernate3;

import java.util.List;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class EmpDaoImpl extends HibernateDaoSupport implements EmpDao {

	/** 插入 */
	public void insert(Emp emp) {
		getHibernateTemplate().save(emp);
	}

	/** 更新 */
	public void update(Emp emp) {
		getHibernateTemplate().update(emp);
	}

	/** 删除 */
	public void delete(Emp emp) {
		getHibernateTemplate().delete(emp);
	}

	/** 根据id删除 */
	public void delete(int id) {
		Emp emp = (Emp) getHibernateTemplate().get(Emp.class, id);
		getHibernateTemplate().delete(emp);
	}

	/** 根据id查询雇员的详细信息 */
	public Emp findById(int id) {
		return (Emp) getHibernateTemplate().get(Emp.class, id);
	}

	/** 查询全部雇员信息 */
	public List<Emp> findAll() {
		return getHibernateTemplate().find("from Emp");
	}

	/** 根据雇员姓名查询其薪水 */
	public double findSalary(String name) {
		List<Double> list = getHibernateTemplate().find("select e.salary from Emp e where e.name=?", name);
		return list.size() > 0 ? list.get(0) : 0;
	}

	/** 查询部总记录数 */
	public int totalCount() {
		List<Long> list = getHibernateTemplate().find("select count(*) from Emp");
		return list.size() > 0 ? Integer.parseInt(list.get(0)+"") : 0;
	}

	/** 批量插入 */
	public void insertBatch(List<Emp> emps) {
		for (int i = 0; emps != null && i < emps.size(); i++) {
			getHibernateTemplate().save(emps.get(i));
			if (i % 20 == 0) {
				getHibernateTemplate().flush();
				getHibernateTemplate().clear();
			}
		}
	}

	/** 批量删除 */
	public void deleteBatch(int... ids) {
		/** 方法一 */
		for (int i = 0; ids != null && i < ids.length; i++) {
			Emp emp = (Emp) getHibernateTemplate().get(Emp.class, ids[i]);
			getHibernateTemplate().delete(emp);
			if (i % 20 == 0) {
				getHibernateTemplate().flush();
				getHibernateTemplate().clear();
			}
		}
	}
}

 

继承了HibernateDaoSupport,这也是Spring提供的一个辅助类

而Spring的配置文件变动如下:

 

<!-- 配置DAO -->
	<!-- 
		<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
			<property name="sessionFactory" ref="sessionFactory"/>
		</bean>
		<bean id="empDao" class="org.monday.hibernate2.EmpDaoImpl">
			<property name="hibernateTemplate" ref="hibernateTemplate"/>
		</bean>
	-->
	<bean id="empDao" class="org.monday.hibernate3.EmpDaoImpl">
			<property name="sessionFactory" ref="sessionFactory"/>
	</bean>

 

三种方式,我个人喜欢第一种。

因为不用依赖Spring的API,不过反过来一想,既然开发都依赖Spring框架了,那这点依赖又算什么。

哈,确实不算什么,只是觉得使用Hibernate的原生API比Spring的好用。(一家之言,欢迎拍转,呵呵~)

而关于配置文件,我认为还是不要写在一起的好,Hibernate的配置就用hibernate.cfg.xml,而Spring就用beans.xml将组件组装起来。类似于Struts2的“分离关注”思想吧。(谁该做的,就让谁做,不要大杂烩。)

最好JDBC的数据库连接配置也单独写在一个配置文件中。

关于实体类的映射文件建议还是配置在beans.xml中吧。不用每次开发完实体类都要在hibernate.cfg.xml中配置,有时太忙了就忘记了。(自己犯过这样的错误...

在Sping中写成类似

<property name="mappingLocations" value="org/monday/hibernate3/*.hbm.xml"/>

通配符的形式,就不怕忘记啦。

 

分享到:
评论
1 楼 gary052402 2015-01-16  
不错,赞一个。

相关推荐

Global site tag (gtag.js) - Google Analytics