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也會將在這個事務中執行的操作都回滾。