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也会将在这个事务中执行的操作都回滚。