巴巴运动网-整合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的业务接口,这样我们的业务方法里面实现相应的接口的时候只要实现自己独有的相应的方法就可以了,而相应公有的增删改查功能,同时在底层接口实现,这样就可以更加的实现代码的降耦合度,为了以后的维护更加方便。