整合SSH框架(1)
Spring4+hibernate4+Struts2的整合,整合完成后我会把这个项目上传上去,但是我的建议是最好还是自己在自己的电脑上自己整合一下,我不保证一定没问题
1、首先建立一个web项目
然后我们建立一个spring的配置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/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/cutter_point?useUnicode=true&characterEncoding=UTF-8" /> <property name="username" value="root" /> <property name="password" value="xiaofeng2015" /> </bean> --> <!-- 推荐配置 --> <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <!-- results in a setDriverClassName(String) call --> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/cutter_point"/> <property name="username" value="root"/> <property name="password" value="xiaofeng2015"/> <property name="minIdle"></property> </bean> </beans>
引入相应的包,这里具体情况,具体引入,最后我会把我的所有的包截图出来,暂时我是集成了spring4和hibernate4的
我暂时是引入了这么多的包,也许有多余,Struts还没开始,但是我这里是可以运行的。
2、接下来是Hibernate的二级缓存的配置
首先配置这个的时候,我们要了解一下配置数据源的几种方式,数据源的配置方式有3种
1,使用org.springframework.jdbc.datasource.DriverManagerDataSource
说明:DriverManagerDataSource建立连接是只要有连接就新建一个connection,根本没有连接池的作用。
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"><value>${jdbc.driverClassName}</value></property> <property name="url"><value>${jdbc.url}</value></property> <property name="username"><value>${jdbc.username}</value></property> <property name="password"><value>${jdbc.password}</value></property> </bean>
2.使用org.apache.commons.dbcp.BasicDataSource
说明:这是一种推荐说明的数据源配置方式,它真正使用了连接池技术
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName"> <value>oracle.jdbc.driver.OracleDriver</value> </property> <property name="url"> <value>jdbc:oracle:thin:@localhost:1521:orcl</value> </property> <property name="username"> <value>test</value> </property> <property name="password"> <value>test</value> </property> <property name="maxActive"> <value>255</value> </property> <property name="maxIdle"> <value>2</value> </property> <property name="maxWait"> <value>120000</value> </property> </bean>
3.使用org.springframework.jndi.JndiObjectFactoryBean
说明:JndiObjectFactoryBean
能够通过JNDI获取DataSource
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"><value>java:comp/env/jdbc/roseindiaDB_local</value></property> </bean>
总结:3种方式中的第一种没有使用连接池,故少在项目中用到,
第三种方式需要在web server中配置数据源,不方便于部署,本人推荐使用每二种方式进行数据源的配置。
配置一个数据源
Spring在第三方依赖包中包含了两个数据源的实现类包,其一是Apache的DBCP,其二是 C3P0。
可以在Spring配置文件中利用这两者中任何一个配置数据源。
DBCP数据源
DBCP类包位于<spring_home></spring_home>/lib/jakarta-commons/commons-dbcp.jar,
DBCP是一个依赖 Jakarta commons-pool对象池机制的数据库连接池,
所以在类路径下还必须包括<spring_home></spring_home>/lib/jakarta-commons/commons-pool.jar。
下面是使用DBCP配置MySql数据源的配置片断:
xml 代码
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3309/sampledb" /> <property name="username" value="root" /> <property name="password" value="1234" /> </bean>
BasicDataSource提供了close()方法关闭数据源,所以必须设定destroy-method=”close”属性,
以便Spring容器关闭时,数据源能够正常关闭。除以上必须的数据源属性外,还有一些常用的属性:
defaultAutoCommit:设置从数据源中返回的连接是否采用自动提交机制,默认值为 true;
defaultReadOnly:设置数据源是否仅能执行只读操作, 默认值为 false;
maxActive:最大连接数据库连接数,设置为0时,表示没有限制;
maxIdle:最大等待连接中的数量,设置为0时,表示没有限制;
maxWait:最大等待秒数,单位为毫秒, 超过时间会报出错误信息;
validationQuery:用于验证连接是否成功的查询SQL语句,SQL语句必须至少要返回一行数据,
如你可以简单地设置为:“select count(*) from user”;
removeAbandoned:是否自我中断,默认是 false ;
removeAbandonedTimeout:几秒后数据连接会自动断开,在removeAbandoned为true,提供该值;
logAbandoned:是否记录中断事件, 默认为 false;
C3P0数据源
C3P0是一个开放源代码的JDBC数据源实现项目,它在lib目录中与Hibernate一起发布,
实现了JDBC3和JDBC2扩展规范说明的 Connection 和Statement 池。
C3P0类包位于<spring_home></spring_home>/lib/c3p0/c3p0-0.9.0.4.jar。下面是使用C3P0配置一个 Oracle数据源:
xml 代码
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value=" oracle.jdbc.driver.OracleDriver "/> <property name="jdbcUrl" value=" jdbc:oracle:thin:@localhost:1521:ora9i "/> <property name="user" value="admin"/> <property name="password" value="1234"/> </bean>
其他更多内容参考:
http://blog.csdn.net/z69183787/article/details/22786215
好的,我的数据源配置采用的是dbcp,然后hibernate的sessionFactory的配置是:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <!-- configuration elided for brevity --> <property name="dataSource" ref="myDataSource" /> <property name="mappingResources"> <list> <!-- 映射文件 --> <value>cn/cutter_point/bean/Person.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <!-- 用来配置hibernate的属性配置 --> <value> hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.hbm2ddl.auto=update <!--其他取值 create、create-drop、update、validate none --> hibernate.show_sql=true hibernate.format_sql=true </value> </property> </bean>
这里有个问题,那就是,我把<property
name="dataSource"ref="myDataSource"
/>
中的dataSource改为myDataSource就会出错
然后配置事务管理器,针对hibernate
<!-- 配置事务管理器,针对hibernate --> <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean>
我们在类里面对相应的方法进行相应的事务管理的时候使用注解的方式
<!-- 采用注解的方式管理事务 --> <tx:annotation-driven transaction-manager="txManager"/>
最后,我们的applicationContext.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:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <context:annotation-config /> <!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/cutter_point?useUnicode=true&characterEncoding=UTF-8" /> <property name="username" value="root" /> <property name="password" value="xiaofeng2015" /> </bean> --> <!-- 推荐配置 --> <bean id="myDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"> <!-- results in a setDriverClassName(String) call --> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/cutter_point"/> <property name="username" value="root"/> <property name="password" value="xiaofeng2015"/> <!-- 连接池启动时的初始值 --> <property name="initialSize" value="1"/> <!-- 连接池的最大值 dbcp2里面似乎没有--> <!-- <property name="maxActive" value="500"/> --> <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 --> <property name="maxIdle" value="2"/> <!-- 最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 --> <property name="minIdle" value="1"/> </bean> <!-- <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> 扫描实体类 <property name="packagesToScan" value="com.tzl"/> hibernate 配置 <property name="hibernateProperties"> <value> hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.show_sql=true hibernate.format_sql=true hibernate.hbm2ddl.auto=none 其他取值 create、create-drop、update、validate hibernate.current_session_context_class=thread hibernate.temp.use_jdbc_metadata_defaults=false </value> </property> </bean> --> <!-- hibernate二级缓存的配置 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <!-- configuration elided for brevity --> <property name="dataSource" ref="myDataSource" /> <property name="mappingResources"> <list> <!-- 映射文件 --> <value>cn/cutter_point/bean/Person.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <!-- 用来配置hibernate的属性配置 --> <value> hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.hbm2ddl.auto=update <!--其他取值 create、create-drop、update、validate none --> hibernate.show_sql=true hibernate.format_sql=true </value> </property> </bean> <!-- 配置事务管理器,针对hibernate --> <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- 采用注解的方式管理事务 --> <tx:annotation-driven transaction-manager="txManager"/> <bean id="personServiceBean" class="cn.cutter_point.service.impl.PersonServiceBean" /> </beans>
3、设置数据库里面相应的映射文件
Bean文件
/** * 功能:实现SSH的整合hibernate4+spring4+struts2,这个是一个实体bean * 时间:2015年3月28日19:02:47 * author:cutter_point * 文件:Person.java */ package cn.cutter_point.bean; public class Person { private Integer id; private String name; public Person() { } public Person(String name) { this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
映射文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.cutter_point.bean"> <!-- <class name="Version"> <id name="id"> <generator class="org.hibernate.id.TableHiLoGenerator"> <param name="table">uid_table</param> <param name="column">next_hi_value_column</param> </generator> </id> <property name="description"/> </class> --> <class name="Person" table="person"> <id name="id"> <generator class="native" /> </id> <property name="name" length="20" not-null="true" /> </class> </hibernate-mapping>
4、我们创建一个服务接口类
package cn.cutter_point.service; import java.util.List; import cn.cutter_point.bean.Person; public interface PersonService { //这个业务bean实现几个方法,保存,更新,删除,获取,获取全部 public abstract void save(Person persnon); public abstract void update(Person person); public abstract void delete(Integer personid); public abstract Person getPerson(Integer personid); public abstract List<Person> getPersons(); }
实现接口
/** * 功能:实现SSH的整合hibernate4+spring4+struts2,这个是一个实体bean * 时间:2015年3月28日21:13:10 * author:cutter_point * 文件:Person.java */ package cn.cutter_point.service.impl; import java.util.List; import javax.annotation.Resource; import org.hibernate.SessionFactory; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import cn.cutter_point.bean.Person; import cn.cutter_point.service.PersonService; @Transactional public class PersonServiceBean implements PersonService { @Resource //这个就是依赖注入 private SessionFactory sessionFactory; //这个业务bean实现几个方法,保存,更新,删除,获取,获取全部 @Override public void save(Person person) { sessionFactory.getCurrentSession().persist(person); } @Override public void update(Person person) { sessionFactory.getCurrentSession().merge(person); } @Override public void delete(Integer personid) { sessionFactory.getCurrentSession().delete(sessionFactory.getCurrentSession().get(Person.class, personid)); } @Override @Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true) public Person getPerson(Integer personid) { return (Person) sessionFactory.getCurrentSession().get(Person.class, personid); } @SuppressWarnings("unchecked") //取消警告 @Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true) @Override public List<Person> getPersons() { return sessionFactory.getCurrentSession().createQuery("from Person").list(); } }
5、单元测试
package junit.test; import static org.junit.Assert.*; import java.util.List; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.cutter_point.bean.Person; import cn.cutter_point.service.PersonService; public class PersonServiceTest { private static PersonService personService; @BeforeClass public static void setUpBeforeClass() throws Exception { try { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); personService = (PersonService) applicationContext.getBean("personServiceBean"); } catch (Exception e) { e.printStackTrace(); } } @Test public void testSave() { // fail("Not yet implemented"); personService.save(new Person("cutter_point")); } @Test public void testUpdate() { // fail("Not yet implemented"); Person person = personService.getPerson(2); //.... person.setName("小丽"); personService.update(person); } @Test public void testDelete() { // fail("Not yet implemented"); personService.delete(9); } @Test public void testGetPerson() { Person person = personService.getPerson(2); System.out.println(person.getName()); // try // { // System.out.println("请关闭数据库"); // Thread.sleep(1000*15); // } // catch (InterruptedException e) // { // e.printStackTrace(); // } // System.out.println("第二次开始获取"); // person = personService.getPerson(2); // System.out.println(person.getName()); } @Test public void testGetPersons() { List<Person> persons = personService.getPersons(); for(Person person : persons) { System.out.println(person.getName()); } } }
数据库还是使用前面文章中使用的数据库MySQL,表还是那个表
运行整个单元测试
ok,到这里spring4+hibernate4的集成已经完成了!!!