spring结合hibernate示例详解
单纯hibernate程序
1、首先是导入hibernate的jar包。
2、 建立用户和用户操作记录实体,log.java和user.java。代码如下所示。
log.java
import java.util.date; public class log { private int id; //日志的类别.日志一般起到一个不可否认性. //操作日志 安全日志 事件日志. private string type; private string detail; private date time; public int getid() { return id; } public void setid(int id) { this.id = id; } public string gettype() { return type; } public void settype(string type) { this.type = type; } public string getdetail() { return detail; } public void setdetail(string detail) { this.detail = detail; } public date gettime() { return time; } public void settime(date time) { this.time = time; } }
user.java
public class user { private int id; private string name; 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; } }
3、 并建立与之对应的实体配置文件,log.hbm.xml和use.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> <class name="com.bjpowernode.usermgr.domain.user" table="t_user"> <id name="id" > <generator class="native"/> </id> <property name="name" /> </class> </hibernate-mapping>
log.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> <class name="com.bjpowernode.usermgr.domain.log" table="t_log"> <id name="id" > <generator class="native"/> </id> <property name="type" /> <property name="detail" /> <property name="time" /> </class> </hibernate-mapping>
4、manager层代码如下所示。
logmanager.java接口
public interface logmanager { //添加日志.方法 public void addlog(log log); }
logmanagerimpl实现
public class logmanagerimpl implements logmanager { @override public void addlog(log log) { hibernateutils.getsessionfactory().getcurrentsession().save(log); } }
usermanager接口
public interface usermanager { public void adduser(user user); }
usermanagerimpl.java实现
public class usermanagerimpl implements usermanager { @override public void adduser(user user) { session session = null; try { //这个session中是放到threadlocal. session = hibernateutils.getsessionfactory().getcurrentsession(); session.begintransaction(); // 网用户表中添加一条同时网日志中添加一条. session.save(user); log log = new log(); log.settype("操作日志"); log.settime(new date()); log.setdetail("xxx"); logmanager logmanager = new logmanagerimpl(); //添加日志. logmanager.addlog(log); session.gettransaction().commit(); } catch (exception e) { e.printstacktrace(); session.gettransaction().rollback(); }finally{ hibernateutils.closesession(session); } } }
5、是通过sessionfactory来创建session,通过session来开启提交和关闭回滚事务,我们把session的开启关闭封装到一个工具类中。hibernateutils.java代码如下所示。
public class hibernateutils { private static sessionfactory factory; static { try { //读取hibernate.cfg.xml文件 configuration cfg = new configuration().configure(); //建立sessionfactory factory = cfg.buildsessionfactory(); }catch(exception e) { e.printstacktrace(); } } public static session getsession() { return factory.opensession(); } public static void closesession(session session) { if (session != null) { if (session.isopen()) { session.close(); } } } public static sessionfactory getsessionfactory() { return factory; } }
6、配置hibernate.cfg.xml文件,包括数据库名称,数据库关联的表,以及用户名密码等。代码如下所示。
<hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/spring_hibernate_1</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <property name="hibernate.dialect">org.hibernate.dialect.mysqldialect</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.hbm2ddl.auto">update</property> <property name="hibernate.current_session_context_class">thread</property> <!-- <property name="hibernate.current_session_context_class">jta</property> --> <mapping resource="com/bjpowernode/usermgr/domain/user.hbm.xml"/> <mapping resource="com/bjpowernode/usermgr/domain/log.hbm.xml"/> </session-factory> </hibernate-configuration>
7、 使用junit进行单元测试,代码如下所示。
import junit.framework.testcase; public class usermanagerimpltest extends testcase { public void testadduser() { usermanager usermanager = new usermanagerimpl(); user user = new user(); user.setname("张三"); usermanager.adduser(user); } }
在上述操作用,对事物的控制边界在业务逻辑层,因为在usermanagerimpl中我们调用adduser()这一方法的同时要把这一操作写入到日志中,也就是调用了addlog()方法,而对于类的方法,一方法一session,一session一事务,那么如果控制事务的呢?我们要执行开启adduser()事务同时再开启addlog()事务吗?在这里我们没有再用以前的opensession方法,选择用的hibernateutils.getsessionfactory().getcurrentsession();
同时在hibernate.cfg.xml中对getcurrentsession()进行配置如下, <propertyname="hibernate.current_session_context_class">thread</property>
表示在当前线程中,与当前线程绑定这样执行adduser()方法和addlog()方法使用的是同一个事务。
那opensession和getcurrentsession的区别呢?
1、 opensession必须关闭,currentsession在事务结束后自动关闭。
2、 opensession没有和当前线程绑定,currentsession和当前线程绑定。并且使用currentsession需要在我们的hibernate.cfg.xml文件中进行事务的配置,是使用jdbc事务还是jta事务。
hibernate和spring结合使用
我们从上述例子中发现,hibernate的事务是独立于hibernate对数据库的增删改查的,并且事务控制在我们的业务逻辑层,对于独立的东西,像是横切性问题,自然想到了aop,实际上springaop封装了对事务的管理,使用springaop我们不再负责去开启和关闭事务。
下面用springaop来和hibernate结合。
当然也要导入spring相关jar。
对于事务管理就是一个横切性问题,把事务管理模块化就是我们的aspect,然后再配置文件中进行配置,我们可以把事务单独放到一个配置文件中。
1、代码如下,applicationcontext-common.xml文件。
<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-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <!-- 配置sessionfactoyr --> <bean id="sessionfactory" class="org.springframework.orm.hibernate3.localsessionfactorybean"> <property name="configlocation"> <value>classpath:hibernate.cfg.xml</value> </property> </bean> <!-- 配置事务管理器 --> <bean id="transactionmanager" class="org.springframework.orm.hibernate3.hibernatetransactionmanager"> <property name="sessionfactory"> <ref bean="sessionfactory"/> </property> </bean> <!-- 哪些类哪些方法使用事务. --> <aop:config> <aop:pointcut id="allmanagermethod" expression="execution(* com.bjpowernode.usermgr.manager.*.*(..))"/> <aop:advisor pointcut-ref="allmanagermethod" advice-ref="txadvice"/> </aop:config> <tx:advice id="txadvice" transaction-manager="transactionmanager"> <tx:attributes> <tx:method name="add*" propagation="required"/> <tx:method name="del*" propagation="required"/> <tx:method name="modify*" propagation="required"/> <tx:method name="*" propagation="required" read-only="true"/> </tx:attributes> </tx:advice> </beans>
首先是配置的是sessionfactory,让spring拿到hibernate的sessionfactory,以便对hibernate事务控制,通过sessionfactory产生session再访问。这样就把把hibernate的sessionfactory注入到spring中了。通过<property>标签,告诉springhibernate的配置文件在哪里,以便spring可以读取hibernate的配置文件。
其次是配置事务管理器,把我们的sessionfactory注入给事务管理器,让事务管理器管理事务。
其次,到底是哪些类哪些方法,开始执行的时候执行事务,<aop:pointcutid="allmanagermethod"
其次,配置aop,expression="execution(*com.bjpowernode.usermgr.manager.*.*(..))",
到底是哪些类交给spring完成事务管理?我们应用在所有的manager包中的所有方法上,manager所有类所有方法全部参与事务的运行。那在什么地方触发开启事务?
再次,定义一个advice,配置事务的传播特性,例如adduser()中调用addlog()方法,是在同一个事务还是不在同一个事务。以add开头,del开头,modify开头以及其他,我们配置的事务传播特性为propagation="required",这样在一个方法中调用另一个方法他们公共一个线程。
2、让usermanagerimpl继承spring提供的对hibernatedao支持类。
hibernatedaosupport,这样继承之后我们就能拿到session,其实也就是hibernate中的session,只不过spring为我们封装了。我们可以这样拿到sesion:this.getsession().save(user);或者使用spring封装好的对象:
this.gethibernatetemplate().save(user);这样都封装到里面了,我们不管理事务的开启和关闭。
之前在我们的usermanagerimpl中使用了logmanagerimpl实例,这次我们可以使用spring的ioc容器,把他们之间的依赖关系注入到spring中,这样就看不到实例,面对接口编程,进行了解耦。
接口不变,usermanagerimpl.java代码如下所示。
public class usermanagerimpl extends hibernatedaosupport implements usermanager { private logmanager logmanager; public void setlogmanager(logmanager logmanager) { this.logmanager = logmanager; } @override public void adduser(user user)throws exception { //this.getsession().save(user); //或者用. this.gethibernatetemplate().save(user); log log = new log(); log.settype("操作日志"); log.settime(new date()); log.setdetail("xxx"); //logmanager logmanager = new logmanagerimpl(); //添加日志. logmanager.addlog(log); //运行期的异常,会回滚. 并且是他的子类也会回滚. //throw new runtimeexception(); //throw new exception(); } }
logmanagerimpl.java 代码如下所示。
public class logmanagerimpl extends hibernatedaosupport implements logmanager { @override public void addlog(log log) { //getsession().save(log); this.gethibernatetemplate().save(log); } }
删除我们自己建立的hibernateutils.java类,删除hibernate.cfg.xml文件中对getcurrentsession()的事务配置。
3、在配置文件中配置依赖关系。
applicationcontext-beans.xml代码如下所示。
<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-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <bean id="usermanager" class="com.bjpowernode.usermgr.manager.usermanagerimpl"> <property name="sessionfactory" ref="sessionfactory"/> <property name="logmanager" ref="logmanager"/> </bean> <bean id="logmanager" class="com.bjpowernode.usermgr.manager.logmanagerimpl"> <property name="sessionfactory" ref="sessionfactory"/> </bean> </beans>
在junit中测试程序代码如下所示。
public class usermanagerimpltest extends testcase { public void testadduser() { beanfactory factory = new classpathxmlapplicationcontext("applicationcontext-*.xml"); usermanager usermanager = (usermanager) factory.getbean("usermanager"); user user = new user(); user.setname("张三"); try { usermanager.adduser(user); } catch (exception e) { e.printstacktrace(); } } }
显示结果如下图所示。
这样就完成了spring和hibernate的结合,主要是利用springaop对hibernate的事务进行控制和在manager层之间的调用用spring ioc进行控制。
总结
以上所述是小编给大家介绍的spring结合hibernate示例详解,希望对大家有所帮助
推荐阅读
-
spring结合hibernate示例详解
-
spring结合struts的代码详解
-
Spring中事务用法示例及实现原理详解
-
Spring Boot中slf4j日志依赖关系示例详解
-
Spring Boot如何优化内嵌的Tomcat示例详解
-
Spring Security 单点登录简单示例详解
-
spring结合struts的代码详解
-
spring结合hibernate示例详解
-
用Spring集成的JOTM配置分布式事务,结合hibernate jpa 博客分类: mysqlhibernatespringsqlserveroracle
-
详解Spring Boot中整合Sharding-JDBC读写分离示例