Spring集成Hibernate

1、Spring所需jar包。我是從Spring的官網上下載的Spring的全部jar包(有很多,我也不知道都是幹嘛的,全部添加)。除此之外Spring還需要添加這個




2.hibernate的jar包。


3.我的測試程序的目錄:


說明一下:model包下是實體類和對應的映射文件、dao和dao.imp分別是數據持久化的CRUD接口和方法、service和service.imp分別是業務邏輯層的接口和方法、最爲關鍵的是beans.xml,他是Spring的配置文件。現在沒有hibernate配置文件,統一由Spring的配置文件。beans.xml配置數據源,以及數據庫的一些配置屬性,Hibernate的事務管理也交由Spring來完成。我們只需要在beans.xml中完成事務管理的配置即可。

下面將代碼貼出:

model包下

package com.lql.model;

public class ContactPerson {

	
	private int id;
	private String name;
	private Group group;
	public Group getGroup() {
		return group;
	}
	public void setGroup(Group group) {
		this.group = group;
	}
	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;
	}
	
}
ContactPerson.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
	
	<!--ContactPerson 映射文件 -->
	
<hibernate-mapping 
	package="com.lql.model">

	<class name="ContactPerson" table="tb_person" lazy="true">
		<comment>Users may bid for or sell auction items.</comment>
		
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name" ></property>
		<many-to-one name="group" column="groupid"></many-to-one>
	</class>
	
</hibernate-mapping>

package com.lql.model;

import java.util.HashSet;
import java.util.Set;

public class Group {

	private int id;
	private String name;
	private Set<ContactPerson> persons;
	
	public void addPerson(ContactPerson person){
		if(persons == null){
			persons = new HashSet<ContactPerson>();
		}
		persons.add(person);
	}
	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 Set<ContactPerson> getPersons() {
		return persons;
	}
	public void setPersons(Set<ContactPerson> persons) {
		this.persons = persons;
	}
	
	
}

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

	<!-- Group映射文件 -->

<hibernate-mapping package="com.lql.model">

	<class name="Group" table="tb_group" lazy="true">
		<comment>Users may bid for or sell auction items.</comment>

		<id name="id">
			<generator class="native" />
		</id>
		<property name="name"></property>


		<!--
			多對一聯繫,集合名爲Group中persons key是在一的那張表裏加一個字段groupid 在雙向關聯的中如果在某一方的關聯配置中指定
			inverse=”true” ,那麼本方就不能維護兩者之間的關聯關係。關聯關係就由對方一方來維護。Inverse
			默認是false,雙方都可以維護關聯關係。維護關聯關係的意思是可以再本方的對象中保存對方的引用。
			extra:一種比較聰明的懶加載策略,即調用集合的size/contains等方法的時候,hibernate並不會去加載整個集合的數據,而是發出一條聰明的SQL語句,以便獲得需要的值,只有在真正需要用到這些集合元素對象數據的時候,纔去發出查詢語句加載所有對象的數據
		-->
		<set name="persons" order-by="id desc" lazy="extra" inverse="false">
			<key column="groupid"></key>
			<one-to-many class="com.lql.model.ContactPerson" />
		</set>

	</class>

</hibernate-mapping>

dao包:

package com.lql.dao;

import com.lql.model.Group;

public interface GroupDao {

	public void save(Group group);
	
	public Group queryByName(String name);
	
	public Group queryById(int id);
}
package com.lql.dao;

import com.lql.model.ContactPerson;

public interface PersonDao {

	public void save(ContactPerson person);
	public ContactPerson query(String name);
}

dao.imp包:

package com.lql.dao.imp;


import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.lql.dao.GroupDao;
import com.lql.model.Group;

public class GroupDaoImp implements GroupDao {

	//這裏將sessionFactory注入到GroupDaoImp類中,在beans.xml中配置注入即可
	private SessionFactory sessionFactory;
	
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	@Override
	public void save(Group group){
		// TODO Auto-generated method stub
		Session session = sessionFactory.getCurrentSession();
		session.save(group);
	}

	@Override
	public Group queryByName(String name) {
		// TODO Auto-generated method stub
		
		Session session = sessionFactory.getCurrentSession();
		String hql = "select g from Group g where g.name = ?";
		Query query = session.createQuery(hql);
		query.setParameter(0, name);
		Group group =(Group) query.uniqueResult();
		if(group == null){
			return null;
		}
		return group;
	}

	@Override
	public Group queryById(int id) {
		// TODO Auto-generated method stub
		Session session = sessionFactory.getCurrentSession();
		Group group =(Group) session.get(Group.class, 1);
		return group;
	}

}
package com.lql.dao.imp;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.lql.dao.PersonDao;
import com.lql.model.ContactPerson;

public class PersonDaoImp implements PersonDao {

	private SessionFactory sessionFactory;
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	@Override
	public void save(ContactPerson person) {
		// TODO Auto-generated method stub
		Session session = sessionFactory.getCurrentSession();
		session.save(person);
	}
	
	public ContactPerson query(String name){
		Session session = sessionFactory.getCurrentSession();
		String hql = "select cp from ContactPerson cp where cp.name = ?";
		Query query = session.createQuery(hql);
		query.setParameter(0, name);
		ContactPerson person =(ContactPerson)query.uniqueResult();
		return person;
	}

}


service包下:

package com.lql.service;

import com.lql.model.Group;

public interface GroupService {

	public void addGroup(Group group);
	public Group queryGroupById(int id);
}

package com.lql.service;

import com.lql.model.ContactPerson;

public interface PersonService {

	public void addPerson(ContactPerson person);
	public ContactPerson queryPerson(String name);
}

service.imp包:

package com.lql.service.imp;

import com.lql.dao.GroupDao;
import com.lql.dao.PersonDao;
import com.lql.model.ContactPerson;
import com.lql.model.Group;
import com.lql.service.PersonService;

public class PersonServiceImp implements PersonService{

	/**
	 * 同樣將GroupDao和PersonDao實現類,GroupDaoImp和PersonDaoImp
	 * 注入這個類中,採用Set方法的方式注入
	 */
	private GroupDao groupDao;
	private PersonDao personDao;
	
	
	public void setGroupDao(GroupDao groupDao) {
		this.groupDao = groupDao;
	}


	public void setPersonDao(PersonDao personDao) {
		this.personDao = personDao;
	}


	@Override
	public void addPerson(ContactPerson person) {
		// TODO Auto-generated method stub
		String groupName = person.getGroup().getName();
		Group group = groupDao.queryByName(groupName);
		
		if(group == null){
			group = person.getGroup();
			groupDao.save(group);
		}
		personDao.save(person);
		person.setGroup(group);
	}


	@Override
	public ContactPerson queryPerson(String name) {
		
		ContactPerson person = personDao.query(name);
		
		return person;
	}

}

package com.lql.service.imp;

import com.lql.dao.GroupDao;
import com.lql.model.Group;
import com.lql.service.GroupService;

public class GroupServiceImp implements GroupService {

	private GroupDao groupDao;
	
	public void setGroupDao(GroupDao groupDao) {
		this.groupDao = groupDao;
	}

	@Override
	public void addGroup(Group group) {
		// TODO Auto-generated method stub
		groupDao.save(group);
	}

	@Override
	public Group queryGroupById(int id) {
		// TODO Auto-generated method stub
		Group group = groupDao.queryById(id);
		return group;
	}

}

最後也是最爲關鍵的部分,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:context="http://www.springframework.org/schema/context"
	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/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
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">



	<!-- Spring配置文件中配置數據源 -->
	<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost/spring" />
		<property name="username" value="root" />
		<property name="password" value="123456" />
	</bean>

	<!-- 配置數據源後配置SessionFactory property配置hibernate配置文件中的一些配置項-->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource" ref="myDataSource" />
		<property name="hibernateProperties">
			<value>
				hibernate.dialect=org.hibernate.dialect.MySQLDialect
				hibernate.hbm2ddl.auto=update
				hibernate.show_sql=true
			</value>
		</property>
		<!-- Hibernate映射文件 -->
		<property name="mappingResources">
			<list>
				<value>com/lql/model/ContactPerson.hbm.xml</value>
				<value>com/lql/model/Group.hbm.xml</value>
			</list>
		</property>
	</bean>

	<!-- 配置Hibernate事務管理器 
	Spring集成Hibernate時,通常將Hibernate中的事務管理交給Spring來統一進行。
	Dao只需進行自己的CRUD操作,不必關心事務管理的問題。
	-->
	<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	
	<!-- 配置哪些方法的調用需要增加事務管理器 -->
	<aop:config>
		<aop:pointcut id="allServiceMethods" expression="execution(* com.lql.service.*.*(..))" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="allServiceMethods" />
	</aop:config>
	
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<!-- 對於增加,刪除,修改的方法,都需要事務管理 -->
			<tx:method name="add*" propagation="REQUIRED" />
			<tx:method name="query*" propagation="REQUIRED" read-only="true"/>
		</tx:attributes>
	</tx:advice>

	
	<!--將Dao的實現注入到Service中-->
	<bean id="personService" class="com.lql.service.imp.PersonServiceImp">
		<property name="personDao" ref="personDao"></property>
		<property name="groupDao" ref="groupDao"></property>
	</bean>

	<bean id="groupService" class="com.lql.service.imp.GroupServiceImp">
		<property name="groupDao" ref="groupDao"></property>
	</bean>
<span style="white-space:pre"></span><pre name="code" class="html"><!-- 將SessionFactory注入Dao的實現中 -->
<bean id="personDao" class="com.lql.dao.imp.PersonDaoImp"><property name="sessionFactory" ref="sessionFactory"></property></bean><bean id="groupDao" class="com.lql.dao.imp.GroupDaoImp"><property name="sessionFactory" ref="sessionFactory"></property></bean></beans>


測試代碼也粘上:

package com.lql.test;

import junit.framework.TestCase;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.lql.dao.GroupDao;
import com.lql.model.ContactPerson;
import com.lql.model.Group;
import com.lql.service.GroupService;
import com.lql.service.PersonService;

public class Test1 extends TestCase {

	/**
	 * 插入一條Group
	 */
	public void test1(){
		BeanFactory beanFactory = new ClassPathXmlApplicationContext("beans.xml");
		GroupService groupService =(GroupService) beanFactory.getBean("groupService");
		Group group = new Group();
		group.setName("同學");
		groupService.addGroup(group);	
	}
	
	/**
	 * 插入一個聯繫人
	 */
	public void test2(){
		BeanFactory beanFactory = new ClassPathXmlApplicationContext("beans.xml");
		PersonService personService =(PersonService) beanFactory.getBean("personService");
		Group group = new Group();
		group.setName("同學");
		ContactPerson person = new ContactPerson();
		person.setGroup(group);
		person.setName("小明");
		personService.addPerson(person);
	}
	
	/**
	 * 根據Id查詢分組
	 */
	public void test3(){
		BeanFactory beanFactory = new ClassPathXmlApplicationContext("beans.xml");
		GroupService groupService =(GroupService) beanFactory.getBean("groupService");
		Group group = groupService.queryGroupById(1);
		System.out.println(group.getName());
	}
	
	/**
	 * 根據姓名查詢聯繫人
	 */
	public void test4(){
		
		BeanFactory beanFactory = new ClassPathXmlApplicationContext("beans.xml");
		PersonService personService =(PersonService) beanFactory.getBean("personService");
		ContactPerson person = personService.queryPerson("小明");
		System.out.println(person.getName());
		
	}
}

所有代碼都已貼出。
從代碼中我們沒有看到Hibernate的事務管理的代碼,比如:session.beginTransaction(),.getTransaction().commot();等,這是因爲我們在beans.xml中配置了聲明式事務管理器。並指定了在哪些類的哪些方法上加入Spring的事務管理機制。

就是這部分代碼:

<!-- 配置Hibernate事務管理器 
<span style="white-space:pre">	</span>Spring集成Hibernate時,通常將Hibernate中的事務管理交給Spring來統一進行。
<span style="white-space:pre">	</span>Dao只需進行自己的CRUD操作,不必關心事務管理的問題。
<span style="white-space:pre">	</span>-->
<span style="white-space:pre">	</span><bean id="transactionManager"
<span style="white-space:pre">		</span>class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<span style="white-space:pre">		</span><property name="sessionFactory" ref="sessionFactory" />
<span style="white-space:pre">	</span></bean>
<!-- 配置哪些方法的調用需要增加事務管理器 -->
	<aop:config>
		<aop:pointcut id="allServiceMethods" expression="execution(* com.lql.service.*.*(..))" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="allServiceMethods" />
	</aop:config>
	
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<!-- 對於增加,刪除,修改的方法,都需要事務管理 -->
			<tx:method name="add*" propagation="REQUIRED" />
			<tx:method name="query*" propagation="REQUIRED" read-only="true"/>
		</tx:attributes>
	</tx:advice>

經過上述配置:事務管理都會統一在com.lql.servce.下的類中的名字爲add*,query*的方法中進行。

比如PersonService的這個方法addPerson(ContactPerson person);方法,在執行這個方法之前,Spring會自動開啓一個事務,並在這個方法所有操作執行完成後將事務提交。不論這個方法中包含多少個CRUD,都只開啓一次事務,關閉一次事務。如果在執行過程中出現異常,Spring也會將在這個事務中執行的操作都回滾。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章