jackwang1 的 Struts2+spring2.5+jpa(hibernate)+proxool
Struts2+spring2.5+jpa(hibernate)这种组合大家在网上看的很多了,不过他们大多数的数据源用的是dbcp,或是cp30,也找了一些用proxool做数据源的,不过配置完似乎总有问题
例如 如果把数据源配置在applicationContext.xml里,则应用在启动的时候会报“Attempt to refer to a unregistered pool by its alias” 这是因为struts2与spring进行整合时,web.xml中的spring加载必须使listener来加载,如果使用ContextLoderServlet,则会出空指向异常,报的是Struts2的objectFactory中的某处,因为绝大多数WEB容器的加载顺序是:Listener,Filter,Servlet,所以将会现struts2在spring前加载,它就找不到spring的管理容器,产生异常,解决办法使用ContextLoderListener来加载spring,好,这样一来又有问题了(proxool在web.xml中的配置采用servlet加载,比Listener启动的晚),spring出异常了,它又会找不到我们在applicationContext.xml所提供的数据源的别名,即:proxool.DbPool,无法管理数据库连接池了。于是只好放弃这种做法,某位大人说自己写Listener,这个也是个不错的解决方法,其实我是不建议修改人家源码的,因为这样不通用!经过多次测试终于找到了如下的一种配置方案:
1 准备:Struts2+spring2.5+jpa(hibernate)+proxool的必要jar包你得有吧,对了,我连接的是oracle数据库
2 开发工具:myeclipse6.5
3 新建工程,作必要的准备工作,copy jar包,我只把主要的配置文件列出来:
1)web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java./xml/ns/javaee"
xmlns:xsi="http://www./2001/XMLSchema-instance"
xsi:schemaLocation="http://java./xml/ns/javaee
http://java./xml/ns/javaee/web-app_2_5.xsd">
<!-- Include this if you are using Hibernate
<filter>
<filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
<filter-class>
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
-->
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
2)在web.xml同级目录建立applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www./schema/beans"
xmlns:xsi="http://www./2001/XMLSchema-instance"
xmlns:jee="http://www./schema/jee"
xmlns:tx="http://www./schema/tx"
xmlns:context="http://www./schema/context"
xsi:schemaLocation="http://www./schema/beanshttp://www./schema/beans/spring-beans-2.5.xsd http://www./schema/txhttp://www./schema/tx/spring-tx-2.5.xsd http://www./schema/jeehttp://www./schema/jee/spring-jee-2.5.xsd http://www./schema/contexthttp://www./schema/context/spring-context-2.5.xsd"
default-lazy-init="true">
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<!-- 连接池 -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"></property>
<property name="persistenceUnitName" value="punit"></property> <!--value 与persistence.xml中的 unitname相同-->
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:component-scan base-package="spring" />
</beans>
3)在src文件夹建立META-INF,在该文件夹建persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java./xml/ns/persistence"
xmlns:xsi="http://www./2001/XMLSchema-instance"
xsi:schemaLocation="http://java./xml/ns/persistencehttp://java./xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="punit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.ejb.cfgfile" value="hibernate.cfg.xml"/>
</properties>
</persistence-unit>
</persistence>
4)在src文件夹建立hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate./hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.ProxoolConnectionProvider</property>
<property name="hibernate.proxool.pool_alias">test</property>
<property name="hibernate.proxool.xml">proxool.xml</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">false</property>
<!-- Drop and re-create the database schema on startup - create-drop-->
<property name="hbm2ddl.auto">update</property>
<mapping class="entity.Person"/>
</session-factory>
</hibernate-configuration>
5)在src文件建立proxool.xml
<?xml version="1.0" encoding="UTF-8"?>
<something-else-entirely>
<proxool>
<alias>test</alias>
<!--proxool只能管理由自己产生的连接-->
<driver-url>
jdbc:oracle:thin:@127.0.0.1:1521:orcl
</driver-url>
<driver-class>
oracle.jdbc.OracleDriver
</driver-class>
<driver-properties>
<property name="user" value="book" />
<property name="password" value="book" />
</driver-properties>
<!-- proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁-->
<house-keeping-sleep-time>90000</house-keeping-sleep-time>
<!-- 指因未有空闲连接可以分配而在队列中等候的最大请求数,超过这个请求数的用户连接就不会被接受-->
<maximum-new-connections>20</maximum-new-connections>
<!-- 最少保持的空闲连接数-->
<prototype-count>5</prototype-count>
<!-- 允许最大连接数,超过了这个连接,再有请求时,就排在队列中等候,最大的等待请求数由maximum-new-connections决定-->
<maximum-connection-count>100</maximum-connection-count>
<!-- 最小连接数-->
<minimum-connection-count>10</minimum-connection-count>
</proxool>
</something-else-entirely>
至此 所有的配置文件建立完成,测试程序
package spring;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import entity.Person;
@Transactional
@Component
public class LoginServiceImpl implements LoginService {
@PersistenceContext
private EntityManager em;
// public void setEntityManager(EntityManager em) {
// this.em = em;
// }
@SuppressWarnings("unchecked")
public boolean checkuser(String name, String password) {
Query query = em
.createQuery("select o from Person o where o.name=?1 and o.password=?2");
query.setParameter(1, name);
query.setParameter(2, password);
List<Person> ls = query.getResultList();
if (ls.size() > 0)
return true;
else
return false;
}
}
有兴趣的话 自己测试下吧