您好,登錄后才能下訂單哦!
使用Spring4如何實(shí)現(xiàn)對(duì)Hibernate5進(jìn)行整合?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
Spring與Hiberante整合
通過hibernate的學(xué)習(xí),我們知道,hibernate主要在hibernate.cfg.xml配置文件中
接下來我們看一下hibernate的一個(gè)配置文件
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> <!-- 指定連接數(shù)據(jù)庫所用的驅(qū)動(dòng) --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <!-- 指定連接數(shù)據(jù)庫的url,其中hibernate是本應(yīng)用連接的數(shù)據(jù)庫名 --> <property name="connection.url">jdbc:mysql://localhost/hibernate_test</property> <!-- 指定連接數(shù)據(jù)庫的用戶名 --> <property name="connection.username">root</property> <!-- 指定連接數(shù)據(jù)庫的密碼 --> <property name="connection.password">cheng</property> <!-- 指定連接池里最大連接數(shù) --> <property name="hibernate.c3p0.max_size">20</property> <!-- 指定連接池里最小連接數(shù) --> <property name="hibernate.c3p0.min_size">1</property> <!-- 指定連接池里連接的超時(shí)時(shí)長(zhǎng) --> <property name="hibernate.c3p0.timeout">5000</property> <!-- 指定連接池里最大緩存多少個(gè)Statement對(duì)象 --> <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> <!-- 指定數(shù)據(jù)庫方言 --> <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> <!-- 根據(jù)需要自動(dòng)創(chuàng)建數(shù)據(jù)表 --> <property name="hbm2ddl.auto">update</property><!--①--> <!-- 顯示Hibernate持久化操作所生成的SQL --> <property name="show_sql">true</property> <!-- 將SQL腳本進(jìn)行格式化后再輸出 --> <property name="hibernate.format_sql">true</property> <!-- 避免這個(gè)錯(cuò)誤信息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文件的主要作用就是配置了一個(gè)session-factory
當(dāng)不采用spring整合的時(shí)候,我們使用hibernate時(shí)主要是用hibernate從sessionFactory中去的session,然后用session來操作持久化對(duì)象,而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(); //開始事務(wù) transaction = session.getTransaction(); transaction.begin(); } @Test public void testSaveUser() { User user = new User(); user.setUsername("張學(xué)友"); 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對(duì)hibernate的整合就是將上述三點(diǎn)通過spring配置起來,而hibernate最關(guān)鍵的sessionFactroy就是spring的一個(gè)bean
這些理解了整合就簡(jiǎn)單了,
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> <!-- 可以加多個(gè)包 --> <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
因?yàn)樗赶蛄薿rg.springframework.orm.hibernate5.LocalSessionFactoryBean
在這個(gè)bean中主要配置了上面說的三點(diǎn):
下面給出數(shù)據(jù)源dataSource的配置
dataSource
<!-- 配置數(shù)據(jù)源 --> <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}" />
還有數(shù)據(jù)庫的連接信息
jdbc.properties
#----------------------------------------------------- # 數(shù)據(jù)庫配置 #----------------------------------------------------- #服務(wù)器地址 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反空閑設(shè)置,防止8小時(shí)失效問題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強(qiáng)大的事務(wù)管理
<!-- 配置Hibernate事務(wù)管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- 配置事務(wù)異常封裝 --> <bean id="persistenceExceptionTranslationPostProcessor" class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" /> <!-- 基于數(shù)據(jù)源的事務(wù)管理器 --> <!-- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource" /> --> <!-- 配合<tx:advice>和<aop:advisor>完成了事務(wù)切面的定義 --> <!-- 使用強(qiáng)大的切點(diǎn)表達(dá)式是語言輕松定義目標(biāo)方法 --> <aop:config proxy-target-class="true"> <!-- 通過aop定義事務(wù)增強(qiáng)切面 --> <aop:pointcut expression=" execution(* com.wechat.service..*(..))" id="serviceMethod" /> <!-- 引用事務(wù)增強(qiáng) --> <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" /> </aop:config> <!-- 事務(wù)增強(qiáng) --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 事務(wù)屬性定義 --> <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(); // 檢測(cè)用戶名是否存在 public boolean isExists(String username); }
實(shí)現(xiàn)類
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); }
實(shí)現(xiàn)類
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); } }
因?yàn)槭聞?wù)管理是配置在service層,所以用service來測(cè)試
測(cè)試
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()); } } }
輸入結(jié)果
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_ 程高偉 張學(xué)友
數(shù)據(jù)庫表
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。