关于Spring整合Hibernate实例

关于Spring整合Hibernate实例

1.概述

  1. 由IOC容器来生成hibernate的sessionFactory.
  2. 让hibernate使用spring的声明式事务

2.整合步骤

2.1导入所需要的包

关于Spring整合Hibernate实例
由于我是使用Maven搭建工程,但是有些依赖怎么下都下不了,最后迫不得已还是新建一个lib来导入所需要的jar包。

2.2在Java中定义数据库表
关于Spring整合Hibernate实例
这里是由Hibernate来创建数据库表,若直接在数据库中定义则可无视该项

2.3利用Spring在applicaiton.xml配置文件中整合Hibernate
新建外部文件db.properties中定义连接数据库所需要的属性(首先在数据库中新建一个数据库)

jdbc.user=root
jdbc.password=LGZxiaozi123
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///spring2
jdbc.initalPoolSize=5
jdbc.maxPoolSize=10
#...

在application.xml中配置下面相关代码

	<bean id = "dataSource" class = "com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name = "user" value = "${jdbc.user}"></property>
		<property name = "password" value = "${jdbc.password}"></property>
		<property name = "driverClass" value = "${jdbc.driverClass}"></property>
		<property name = "jdbcUrl" value = "${jdbc.jdbcUrl}"></property>
		<property name = "initialPoolSize" value = "${jdbc.initalPoolSize}"></property>
		<property name = "maxPoolSize" value = "${jdbc.maxPoolSize}"></property>
	</bean>

倘若不想这样配置的话,也可以在hibernate.cgf.xml配置文件中写好数据库连接属性,可达效果一致。不过会造成代码冗余,不建议使用

也在hibernate.cgf.xml配置文件中配置hibernate的一些基本属性:方言,生成数据表的策略以及二级缓存等

        <property name = "hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
		<property name="hibernate.show_sql">true</property>
		<property name="hibernate.format_sql">true</property>
		<property name="hibernate.hbm2ddl.auto">update</property>

再回到applicaiton.xml中配置sessionFactory实例。(这里得导入org.springframework.orm的jar包)

	<bean id = "sessionFactory" class = "org.springframework.orm.hibernate3.LocalSessionFactoryBean">
	<!-- 配置数据源属性 -->
		<property name="dataSource" ref = "dataSource"></property>
		<!-- 配置hibernate配置文件的位置及名称 -->
		<!--
		<property name="configLocation" value = "classpath:hibernate.cfg.xml"></property>
		-->
		
		<!-- 使用hibernateProperties 属性来配置hibernate原生属性 -->
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
				<prop key="hibernate.show_sql">false</prop>
				<prop key="hibernate.format_sql">ture</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop>
			</props>
		</property>
		<!-- 配置hibernate映射文件的位置及名称,可以使用通配符,有时直接在数据库中定义好表格,该项可去除 -->
		<property name="mappingLocations" value = "classpath:com/waston/spring/hibernate/entities/*.hbm.xml"></property>
	</bean>

上面代码中,若使用hibernateProperties属性来配置hibernate原生属性的话,完全可以将hibernate.cfg.xml这个配置文件给完全取代,全凭个人喜好决定是否保留.cfg.xml文件。

此时跑一个测试,代码如下:
关于Spring整合Hibernate实例
若控制台输出如下文字,则代表数据库连接成功:
关于Spring整合Hibernate实例
创建持久层DAO接口:
绑定各种操作

package com.waston.spring.hibernate.dao;

public interface BookShopDao {
	public int findBookPriceByIsbn(String isbn);
	
	public void updateBookStock(String isbn);
	
	public void updateUserAccount(String username, int price);
}

实现该接口:
使用@Repository 与 @Autowired实现自动装配
并且为当前线程绑定sessionFactory,以实现对数据库的各种操作。

package com.waston.spring.hibernate.dao.impl;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.waston.spring.hibernate.dao.BookShopDao;

@Repository
public class BookShopDaoImpl implements BookShopDao{
	
	@Autowired
	private SessionFactory sessionFactory;
	
	
	//获取跟当前线程绑定的session
	private Session getSession() {
		return sessionFactory.getCurrentSession();
	}
	
	public int findBookPriceByIsbn(String isbn) {
		String hql = "Select b.price FROM Book b where b.isbn = ?";
		Query query = getSession().createQuery(hql).setString(0, isbn);
		return (Integer)query.uniqueResult();
	}

	public void updateBookStock(String isbn) {
		String hql2 = "SELECT b.stock FROM Book b where b.isbn = ?";
		int stock = (Integer) getSession().createQuery(hql2).setString(0, isbn).uniqueResult();
		if(stock == 0) {
			System.out.println("库存不足");
		}
		
		String hql = "UPDATE Book b Set b.stock = b.stock - 1 where b.isbn = ?";
		getSession().createQuery(hql).setString(0, isbn).executeUpdate();
	}

	public void updateUserAccount(String username, int price) {
		// TODO Auto-generated method stub
		String hql1 = "Select a.balance from Account a where a.username = ?";
		int balance = (Integer) getSession().createQuery(hql1).setString(0, username).uniqueResult();
		if(balance < price) {
			System.out.println("余额不足");
		}
		
		String hql = "Update Account a set a.balance = a.balance - ? where a.username = ?";
		getSession().createQuery(hql).setInteger(0, price).setString(1, username).executeUpdate();
	}
	
}

创建业务层Service接口:
绑定各种操作

package com.waston.spring.hibernate.service;

public interface BookShopService {
	public void purchase(String username, String isbn);
}

实现该接口:
使用@Service与 @Autowired实现自动装配

package com.waston.spring.hibernate.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.waston.spring.hibernate.dao.BookShopDao;
import com.waston.spring.hibernate.service.BookShopService;

@Service
public class BookShopServiceImpl implements BookShopService {
	
	@Autowired
	private BookShopDao bookShopDao;

	public void purchase(String username, String isbn) {
		// TODO Auto-generated method stub
		int price = bookShopDao.findBookPriceByIsbn(isbn);
		bookShopDao.updateBookStock(isbn);
		bookShopDao.updateUserAccount(username, price);
	}
}

并在application.xml中配置自动扫描的包:

	<!-- 配置自动扫描的包 -->
	<context:component-scan base-package="com.waston.spring.hibernate.*"></context:component-scan>

以及配置Spring的声明式事务:

	<!-- 配置spring的声明式事务 -->
	<!-- 配置事务管理器 -->
	<bean id = "transactionManager" class = "org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref = "sessionFactory"></property>
	</bean>
	<!-- 配置事务属性,需要事务管理器 -->
	<tx:advice id = "txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="get*" read-only="true"/>
			<tx:method name="*"/>
		</tx:attributes>
	</tx:advice>
	<!-- 配置事务切点,并把切点和事务属性关联起来 -->
	<aop:config>
		<aop:pointcut expression="execution(* com.waston.spring.hibernate.service.*.*(..))" 
		id="txPointcut"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
	</aop:config>

接着来测试一下:

package com.waston.hibernate.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.waston.spring.hibernate.service.BookShopService;

public class springHibernateTest {
	private ApplicationContext context = null;
	private BookShopService bookShopService = null;
	{
		context = new ClassPathXmlApplicationContext("application.xml");
		bookShopService = context.getBean(BookShopService.class);
	}

	public void testBookShopService() {
		bookShopService.purchase("aa", "1001");
	}
	
	public static void main(String args[]){
		springHibernateTest sTest = new springHibernateTest();
		sTest.testBookShopService();
	}
} 

运行结果:
关于Spring整合Hibernate实例
以上就是Spring中整合hibernate一个完整的实例。
---------------------------------------------分割线----------------------------------------------------
想到什么以后再来补充。