Spring4整合Hibernate5详细步骤
spring与hiberante整合
通过hibernate的学习,我们知道,hibernate主要在hibernate.cfg.xml配置文件中
接下来我们看一下hibernate的一个配置文件
hibernate配置文件
hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?> <!doctype hibernate-configuration public "-//hibernate/hibernate configuration dtd 3.0//en" "http://hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- 指定连接数据库所用的驱动 --> <property name="connection.driver_class">com.mysql.jdbc.driver</property> <!-- 指定连接数据库的url,其中hibernate是本应用连接的数据库名 --> <property name="connection.url">jdbc:mysql://localhost/hibernate_test</property> <!-- 指定连接数据库的用户名 --> <property name="connection.username">root</property> <!-- 指定连接数据库的密码 --> <property name="connection.password">cheng</property> <!-- 指定连接池里最大连接数 --> <property name="hibernate.c3p0.max_size">20</property> <!-- 指定连接池里最小连接数 --> <property name="hibernate.c3p0.min_size">1</property> <!-- 指定连接池里连接的超时时长 --> <property name="hibernate.c3p0.timeout">5000</property> <!-- 指定连接池里最大缓存多少个statement对象 --> <property name="hibernate.c3p0.max_statements">100</property> <property name="hibernate.c3p0.idle_test_period">3000</property> <property name="hibernate.c3p0.acquire_increment">2</property> <property name="hibernate.c3p0.validate">true</property> <!-- 指定数据库方言 --> <property name="dialect">org.hibernate.dialect.mysql5innodbdialect</property> <!-- 根据需要自动创建数据表 --> <property name="hbm2ddl.auto">update</property><!--①--> <!-- 显示hibernate持久化操作所生成的sql --> <property name="show_sql">true</property> <!-- 将sql脚本进行格式化后再输出 --> <property name="hibernate.format_sql">true</property> <!-- 避免这个错误信息disabling contextual lob creation as createclob() method threw error :java.lang.reflect.invocationtargetexception --> <property name="hibernate.temp.use_jdbc_metadata_defaults">false</property> <!-- 罗列所有持久化类的类名 --> <mapping class="com.wechat.entity.po.user"/> <mapping class="com.wechat.entity.po.person"/> </session-factory> </hibernate-configuration>
配置文件的作用
hibernate.cfg.xml文件的主要作用就是配置了一个session-factory
- 在session-factory中主要通过property配置一些数据库的连接信息,我们知道,spring通常会将这种数据库连接用datasource来表示,这样一来,hibernate.cfg.xml文件中的所有跟数据库连接的都可以干掉了,直接用spring的datasource,而datasource也可以用c3p0、dbcp等。
- 在session-factory中通过property除了配置一些数据库的连接信息之外,还有一些hibernate的配置,比如方言、自动创建表机制、格式化sql等,这些信息也需要配置起来。
- 还有最关键的一个持久化类所在路径的配置
当不采用spring整合的时候,我们使用hibernate时主要是用hibernate从sessionfactory中去的session,然后用session来操作持久化对象,而sessionfactory来自于配置文件。像下面这样:
standardserviceregistry registry = null; sessionfactory sessionfactory = null; session session = null; transaction transaction = null; simpledateformat sdf = new simpledateformat("yyyy-mm-dd hh:mm:ss"); @before public void init() { registry = new standardserviceregistrybuilder() .configure() // configures settings from hibernate.cfg.xml .build(); sessionfactory = new metadatasources( registry ).buildmetadata().buildsessionfactory(); session = sessionfactory.opensession(); //开始事务 transaction = session.gettransaction(); transaction.begin(); } @test public void testsaveuser() { user user = new user(); user.setusername("张学友"); user.setpassword("jacky"); user.setregistdate(sdf.format(new date())); file file = new file("d:"+file.separator+"ubuntu.png"); string filename = file.getname(); string prefix=filename.substring(filename.lastindexof(".")+1); system.out.println(prefix); inputstream input = null; try { input = new fileinputstream(file); } catch (filenotfoundexception e) { e.printstacktrace(); } blob image = null; try { image = hibernate.getlobcreator(session).createblob(input,input.available()); } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } user.setuserpic(image); session.save(user); } @after public void destroy(){ transaction.commit(); session.close(); sessionfactory.close(); standardserviceregistrybuilder.destroy( registry ); }
spring对hibernate的整合就是将上述三点通过spring配置起来,而hibernate最关键的sessionfactroy就是spring的一个bean
这些理解了整合就简单了,
sessionfactorybean
spring的sessionfactroy像下面这样配置:
<!-- 加载配置文件 --> <context:property-placeholder location="classpath:jdbc.properties" file-encoding="utf-8" ignore-unresolvable="true" /> <bean id="sessionfactory" class="org.springframework.orm.hibernate5.localsessionfactorybean"> <property name="datasource" ref="datasource" /> <property name="packagestoscan"> <list> <!-- 可以加多个包 --> <value>com.wechat.entity.po</value> </list> </property> <property name="hibernateproperties"> <props> <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> <prop key="hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> <prop key="hibernate.format_sql">${hibernate.format_sql}</prop> <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop> </props> </property> </bean>
通过bean的配置可以看出该bean就是hibernate的sessionfactroy
因为它指向了org.springframework.orm.hibernate5.localsessionfactorybean
在这个bean中主要配置了上面说的三点:
- 数据源datasource
- hibernate的配置,包括方言,输出sql等
- 持久化类的位置,通过包进行扫描
下面给出数据源datasource的配置
datasource
<!-- 配置数据源 --> <bean id="datasource" class="com.mchange.v2.c3p0.combopooleddatasource" destroy-method="close" p:driverclass="${jdbc.driverclassname}" p:jdbcurl="${jdbc.url}" p:user="${jdbc.username}" p:password="${jdbc.password}" p:testconnectiononcheckout="${jdbc.c3p0.testconnectiononcheckout}" p:testconnectiononcheckin="${jdbc.c3p0.testconnectiononcheckin}" p:idleconnectiontestperiod="${jdbc.c3p0.idleconnectiontestperiod}" p:initialpoolsize="${jdbc.c3p0.initialpoolsize}" p:minpoolsize="${jdbc.c3p0.minpoolsize}" p:maxpoolsize="${jdbc.c3p0.maxpoolsize}" p:maxidletime="${jdbc.c3p0.maxidletime}" />
还有数据库的连接信息
jdbc.properties
#----------------------------------------------------- # 数据库配置 #----------------------------------------------------- #服务器地址 host=127.0.0.1 jdbc.driverclassname=com.mysql.jdbc.driver jdbc.url=jdbc:mysql://${host}:3306/hibernate_test jdbc.username=root jdbc.password=cheng #----------------------------------------------------- # 适用于c3p0的配置 #----------------------------------------------------- #----------------------------------------------------- # c3p0反空闲设置,防止8小时失效问题28800 #----------------------------------------------------- #idleconnectiontestperiod要小于mysql的wait_timeout jdbc.c3p0.testconnectiononcheckout=false jdbc.c3p0.testconnectiononcheckin=true jdbc.c3p0.idleconnectiontestperiod=3600 #----------------------------------------------------- # c3p0连接池配置 #----------------------------------------------------- #initialpoolsize, minpoolsize, maxpoolsize define the number of connections that will be pooled. #please ensure that minpoolsize <= maxpoolsize. #unreasonable values of initialpoolsize will be ignored, and minpoolsize will be used instead. jdbc.c3p0.initialpoolsize=10 jdbc.c3p0.minpoolsize=10 jdbc.c3p0.maxpoolsize=100 #maxidletime defines how many seconds a connection should be permitted to go unused before being culled from the pool. jdbc.c3p0.maxidletime=3600 #----------------------------------------------------- # hibernate连接池配置 #----------------------------------------------------- hibernate.connection.driverclass=com.mysql.jdbc.driver hibernate.connection.url=jdbc:mysql://${host}:3306/${dbname} hibernate.dialect=org.hibernate.dialect.mysql5dialect hibernate.show_sql=true hibernate.format_sql=true hibernate.hbm2ddl.auto=update
配置完这些还有spring强大的事务管理
<!-- 配置hibernate事务管理器 --> <bean id="transactionmanager" class="org.springframework.orm.hibernate5.hibernatetransactionmanager"> <property name="sessionfactory" ref="sessionfactory" /> </bean> <!-- 配置事务异常封装 --> <bean id="persistenceexceptiontranslationpostprocessor" class="org.springframework.dao.annotation.persistenceexceptiontranslationpostprocessor" /> <!-- 基于数据源的事务管理器 --> <!-- <bean id="transactionmanager" class="org.springframework.jdbc.datasource.datasourcetransactionmanager" p:datasource-ref="datasource" /> --> <!-- 配合<tx:advice>和<aop:advisor>完成了事务切面的定义 --> <!-- 使用强大的切点表达式是语言轻松定义目标方法 --> <aop:config proxy-target-class="true"> <!-- 通过aop定义事务增强切面 --> <aop:pointcut expression=" execution(* com.wechat.service..*(..))" id="servicemethod" /> <!-- 引用事务增强 --> <aop:advisor advice-ref="txadvice" pointcut-ref="servicemethod" /> </aop:config> <!-- 事务增强 --> <tx:advice id="txadvice" transaction-manager="transactionmanager"> <!-- 事务属性定义 --> <tx:attributes> <tx:method name="*" /> </tx:attributes> </tx:advice>
好了,这些配置好之后就可以使用在spring中配置的sessionfactroy了
userdao
package com.wechat.dao; import java.util.list; import com.wechat.entity.po.user; public interface userdao { // 得到所有用户 public list<user> getalluser(); // 检测用户名是否存在 public boolean isexists(string username); }
实现类
package com.wechat.dao.impl; import java.util.arraylist; import java.util.list; 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.wechat.dao.userdao; import com.wechat.entity.po.user; @repository public class userdaoimpl implements userdao { //注入sessionfactory @autowired private sessionfactory sessionfactory; @suppresswarnings("unchecked") @override public list<user> getalluser() { list<user> userlist = new arraylist<user>(); string hsql="from user"; session session = sessionfactory.getcurrentsession(); query query = session.createquery(hsql); userlist = query.list(); return userlist; } @override public boolean isexists(string username) { query query = sessionfactory.opensession() .createquery("from user u where u.username = :username").setparameter("username", username); system.out.println(query.list().size()); return query.list().size()>0?true:false; } }
userservice
package com.wechat.service.user; import java.util.list; import com.wechat.entity.po.user; public interface userservice { public list<user> getalluser(); public boolean isexists(string username); }
实现类
package com.wechat.service.user.impl; import java.util.list; import org.springframework.beans.factory.annotation.autowired; import org.springframework.cache.annotation.cacheable; import org.springframework.stereotype.service; import com.wechat.dao.userdao; import com.wechat.entity.po.user; import com.wechat.service.user.userservice; @service public class userserviceimpl implements userservice { @autowired private userdao userdao; @override public list<user> getalluser() { return userdao.getalluser(); } @override @cacheable(cachenames="isexists", key="#username") public boolean isexists(string username) { return userdao.isexists(username); } }
因为事务管理是配置在service层,所以用service来测试
测试
package com.wechat.dao; import java.util.list; import org.junit.test; import org.junit.runner.runwith; import org.springframework.beans.factory.annotation.autowired; import org.springframework.test.context.contextconfiguration; import org.springframework.test.context.junit4.springjunit4classrunner; import com.wechat.entity.po.user; import com.wechat.service.user.userservice; @runwith(springjunit4classrunner.class) @contextconfiguration(locations = { "classpath:spring/spring-core.xml" }) public class userservicetest { @autowired private userservice userservice; @test public void test() { list<user> userlist = userservice.getalluser(); for(user user:userlist){ system.out.println(user.getusername()); } } }
输入结果
hibernate: select user0_.userid as userid1_2_, user0_.password as password2_2_, user0_.registdate as registda3_2_, user0_.userpic as userpic4_2_, user0_.username as username5_2_ from user_info user0_ 程高伟 张学友
数据库表
好了spring整合hibernate就写到这里。
项目地址:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 详解在spring boot中消息推送系统设计与实现
下一篇: java利用数组随机抽取幸运观众
推荐阅读
-
Spring4整合Hibernate5详细步骤
-
使用maven整合Spring+SpringMVC+Mybatis框架详细步骤(图文)
-
springmvc整合freemarker配置的详细步骤
-
Spring Boot整合elasticsearch的详细步骤
-
springmvc整合freemarker配置的详细步骤
-
Apache+MySQL+php+phpMyAdmin整合详细步骤
-
java Spring整合Freemarker的详细步骤
-
java Spring整合Freemarker的详细步骤
-
java Spring整合Freemarker的详细步骤
-
Spring Boot整合elasticsearch的详细步骤