標籤:dao 抽象類別 j2ee 解耦合
巴巴運動網-整合hibernate4+spring4(3)DAO層
1、項目圖解
2、首先我們引入相應的jar包
3、我們配置一下資料庫中相應的實體物件
ProductType.java
/** * 功能:這是產品類別的 * 檔案:ProductType.java * 時間:2015年5月12日10:16:21 * cutter_point */package com.cutter_point.bean.product; import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.SequenceGenerator; @Entity@SequenceGenerator(name="seq_1",sequenceName="seq_1",allocationSize=1,initialValue=1)public class ProductType{ /** 類型id **/ privateInteger typeid; privateString name; //類別名 privateString note; //備忘,用於百度搜尋 privateboolean visible = true; //是否可見 publicProductType() { } @Column(length=36,nullable=false) publicString getName() { returnname; } publicvoid setName(String name) { this.name= name; } @Column(length=200) publicString getNote() { returnnote; } publicvoid setNote(String note) { this.note= note; } @Column(nullable=false) publicboolean isVisible() { returnvisible; } publicvoid setVisible(boolean visible) { this.visible= visible; } @Id @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="seq_1") //自增長 publicInteger getTypeid() { returntypeid; } publicvoid setTypeid(Integer typeid) { this.typeid= typeid; }}
這裡的xml檔案我們也不必去配置了
4、我們配置一下spring的設定檔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/beanshttp://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd"> <!-- 掃描帶有spring特殊機制的類,這是把這些包下面所有的類都添加到spring中進行管理 --> <context:component-scan base-package="com.cutter_point" /> <!-- 屬性遍曆器 --> <!-- <context:property-placeholderlocation="classpath:jdbc.properties" /> --> <!-- 串連資料庫屬性配置,destroy-method="close"就是說在這個bean被摧毀的情況下可以調用這個bean預設的close方法--> <bean id="myDataSource" class="org.apache.commons.dbcp2.BasicDataSource"destroy-method="close"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/> <property name="url"value="jdbc:oracle:thin:@localhost:1522:orcl"/> <property name="username"value="xf1205020116"/> <property name="password"value="xf1205020116"/> <!-- 串連池啟動時的初始值 --> <property name="initialSize" value="1"/> <!-- 串連池的最大值 dbcp2裡面似乎沒有--> <!-- <property name="maxActive"value="500"/> --> <!-- 最大空閑值.當經過一個高峰時間後,串連池可以慢慢將已經用不到的串連慢慢釋放一部分,一直減少到maxIdle為止 --> <property name="maxIdle" value="2"/> <!-- 最小空閑值.當閒置串連數少於閥值時,串連池就會預申請去一些串連,以免洪峰來時來不及申請 --> <property name="minIdle" value="1"/> </bean> <!-- hibernate二級緩衝的配置 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <!-- configuration elided for brevity --> <property name="dataSource" ref="myDataSource" /> <!-- <propertyname="mappingResources"> <list> 對應檔 <value>com/cutter_point/bean/product/ProductType.hbm.xml</value> </list> </property>--> <property name="hibernateProperties"> <!-- 用來配置hibernate的屬性配置 --> <value> hibernate.dialect=org.hibernate.dialect.OracleDialect hibernate.hbm2ddl.auto=update <!--其他取值 create、create-drop、update、validate none--> hibernate.show_sql=true hibernate.format_sql=true <!-- 開啟二級緩衝功能 --> hibernate.cache.use_second_level_cache= true hibernate.cache.use_query_cache= false hibernate.cache.region.factory_class= org.hibernate.cache.ehcache.EhCacheRegionFactory <!-- hibernate3的二級緩衝配置 --> <!-- <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>--> </value> </property> <property name="packagesToScan" value="com.cutter_point.bean" /> </bean> <!-- 交易管理員,吧上面配置的bean注入到這個裡面 --> <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- 我們採用註解的方式來使用這個事務,首先我們開啟事務 --> <tx:annotation-driven transaction-manager="txManager" /> </beans>
注意我們的spring設定檔裡面也不必再寫對應的xml檔案在哪了
5、建立底層的DAO層的介面實現增刪蓋查實現底層DAO介面
/** * 功能:這是對資料庫進行增刪改查的介面類 * 檔案:DAO.java * 時間:2015年5月14日18:51:24 * cutter_point */package com.cutter_point.service.base; publicinterfaceDAO{ /** * 儲存一個實體類 * @param entity 實體類 */ publicvoid save(Object entity); /** * 根據id號刪除資料 * @param entityClass 類別 * @param entityid 實體類id號 */ public <T> void delete(Class<T>entityClass, Object entityid); /** * 根據數組id刪除一堆資料 * @param entityClass 類別 * @param entityids id號的數組 */ public <T> void delete(Class<T>entityClass, Object[] entityids); /** * 更具實體類修改相應的資料 * @param entity 實體類 */ publicvoid update(Object entity); /** * 根據類別和id來尋找不同的類別下的實體 * @param entityClass 類別 * @param entityId 實體id * @return返回一個實體類 */ public <T> Tfind(Class<T> entityClass, Object entityId);}
我們吧一些公用方法實現,使用一個抽象類別來實現
/** * 功能:這是對資料庫進行增刪改查的抽象類別,實現一些方法 * 檔案:DaoSupport.java * 時間:2015年5月14日19:03:52 * cutter_point */package com.cutter_point.service.base; import java.io.Serializable; import javax.annotation.Resource; import org.hibernate.Session;import org.hibernate.SessionFactory;importorg.springframework.transaction.annotation.Propagation;importorg.springframework.transaction.annotation.Transactional; @Transactional //吧這個類裡面的方法提交給spring管理,方法都開上事務public abstract class DaoSupport implementsDAO{ //通過spring取得sessionFactory @Resource publicSessionFactory sessionFactory; @Override publicvoid save(Object entity) { Sessionsession = sessionFactory.getCurrentSession(); session.persist(entity); } /** * 開啟事務 */ @Override public<T> void delete(Class<T> entityClass, Object entityid) { this.delete(entityClass,new Object[]{entityid}); } /** * 關閉事務 */ @Override public<T> void delete(Class<T> entityClass, Object[] entityids) { Sessionsession = sessionFactory.getCurrentSession(); for(Objectid : entityids) { //迴圈刪除相應的id號 session.delete(session.get(entityClass,(Serializable) id)); } } @Override publicvoid update(Object entity) { Sessionsession = sessionFactory.getCurrentSession(); session.merge(entity); } /** * 這個方法不需要開啟事務,而且不會更改資料庫的資料 */ @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED) @Override public<T> T find(Class<T> entityClass, Object entityId) { Sessionsession = sessionFactory.getCurrentSession(); return(T) session.get(entityClass, (Serializable) entityId); } }
6、使用依賴注入
首先實現一個業務介面
ProductService.java
packagecom.cutter_point.service.product; importcom.cutter_point.bean.product.ProductType;importcom.cutter_point.service.base.DAO; public interfaceProductTypeService extends DAO{ //這裡面定義ProductTypeService專有的方法}
實現介面ProductServiceBean.java
/** * 功能:這是產品類別的服務類 * 檔案:ProductService.java * 時間:2015年5月13日15:36:06 * cutter_point */packagecom.cutter_point.service.product.impl; import org.hibernate.Query;import org.hibernate.Session;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional; import com.cutter_point.service.base.DaoSupport;importcom.cutter_point.service.product.ProductTypeService; @Service //相當於在spring裡面定義一個bean,這是註解的方式<context:component-scanbase-package="com.cutter_point" />@Transactional //在方法執行的時候開啟事務public class ProductTypeServiceBean extendsDaoSupport implements ProductTypeService{ /** * 當我們刪除的時候,會吧相應的對象進行假刪除,也就是把相應的對象設定為不可見 */ @Override public<T> void delete(Class<T> entityClass, Object[] entityids) { //取得和資料庫的串連 Sessions = sessionFactory.getCurrentSession(); //我們首先判斷這個傳進來的id不是空的 if(entityids!= null && entityids.length > 0) { StringBuildersb = new StringBuilder(); for(inti = 0; i < entityids.length; ++i) { sb.append("?").append(","); } //在這個語句添加到最後的時候會多餘一個, sb.deleteCharAt(sb.length()-1); //刪除最後一個就是,號 Queryquery = s.createSQLQuery("update producttype p set p.visible = ? wherep.typeid in("+sb.toString()+")").setParameter(0, false); for(inti = 0; i < entityids.length; ++i) { query.setParameter(i+ 1, entityids[i]); } query.executeUpdate(); } }}
這裡使用一個函數覆蓋的方式吧底層的delete方法給覆蓋了,我們不直接刪除資料,而是把資料的一個是否可見的欄位屬性設定為不可見
7、接下來我們測試一下hibernate+spring的註解是否配置成功
/** * 功能:這是產品類別的單元測試 * 檔案:ProductTest.java * 時間:2015年5月12日10:27:24 * cutter_point */package junit.test; import javax.sql.DataSource; import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import org.junit.Assert;import org.junit.BeforeClass;import org.junit.Test;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext; importcom.cutter_point.bean.product.ProductType;importcom.cutter_point.service.product.ProductTypeService; public class ProductTest{ //測試spring是否可以運作 privatestatic ApplicationContext cxt; privatestatic ProductTypeService pts; @BeforeClass publicstatic void setUpBeforeClass() throws Exception { try { cxt= new ClassPathXmlApplicationContext("config/spring/beans.xml"); pts= (ProductTypeService) cxt.getBean("productTypeServiceBean"); } catch(Exception e) { e.printStackTrace(); } } @Test publicvoid test() { ProductTypept = new ProductType(); //new一個對象 pt.setTypeid(78); //設定id號碼 Configurationcfg = new Configuration(); //得到Configuration @SuppressWarnings("deprecation") SessionFactorysf =cfg.configure("/config/hibernate/hibernate.cfg.xml").buildSessionFactory(); //取得session工廠 Sessionsession = sf.openSession(); session.beginTransaction(); session.save(pt); session.getTransaction().commit(); session.close(); sf.close(); } @Test publicvoid testSpring() { //測試spring是否可以運作 ApplicationContextcxt = new ClassPathXmlApplicationContext("config/spring/beans.xml"); DataSourcedatasource = (DataSource)cxt.getBean("myDataSource"); //取出一個對象 System.out.println(datasource); //判斷是不是為空白, } @Test publicvoid testSH() { //測試spring是否可以運作 ApplicationContextcxt = new ClassPathXmlApplicationContext("config/spring/beans.xml"); ProductTypeServiceproductService = (ProductTypeService)cxt.getBean("productTypeService"); //取出一個對象 ProductTypept = new ProductType(); pt.setName("cutter_point"); pt.setNote("非常好"); productService.save(pt); } @Test publicvoid testSave() { ProductTypetype = new ProductType(); type.setName("跑步用品"); type.setNote("中國好跑步2"); pts.save(type); } @Test publicvoid testFind() { ProductTypept = pts.find(ProductType.class, 5); Assert.assertNotNull(pt); System.out.println(pt); } @Test publicvoid testUpdate() { ProductTypept = pts.find(ProductType.class, 5); pt.setName("cutter_point666"); pt.setNote("出彩中國人"); pts.update(pt); } @Test publicvoid testDelete() { pts.delete(ProductType.class,3); }}
6、總結
這次就是實現一個公用的底層介面和抽象類別,底層DAO介面可以給我們的業務介面繼承,用業務介面繼承底層介面,那麼每個業務介面都會有相應的增刪改查的功能,然後我們在相應的業務方法實現裡面繼承我們的DaoSupport和實現我們繼承了DAO的業務介面,這樣我們的業務方法裡面實現相應的介面的時候只要實現自己專屬的相應的方法就可以了,而相應公有的增刪改查功能,同時在底層介面實現,這樣就可以更加的實現代碼的降耦合度,為了以後的維護更加方便。
【j2ee spring】29、巴巴運動網-整合hibernate4+spring4(4)DAO層