您的位置:首页 > 编程语言 > Java开发

Struts2+Hibernate4+Spring4框架整合搭建Java项目原型

2016-09-08 10:52 573 查看

一、基本软件配置

1)MyEclipse 2014GA(JDK:1.7.0.u45)

2)apache-tomcat-7.0.64

3)mysql- 5.5.50

二、项目目的

整合使用Java三大框架(即Struts2、Spring4和Hibernate4),搭建项目架构原型。

三、SSH三大架构版本下载

Struts2.3.6:官网:http://struts.apache.org/

http://mirrors.cnnic.cn/apache/struts/binaries/struts-2.3.16.3-all.zip

Spring4.1.1:官网:http://spring.io/

http://repo.spring.io/libs-release-local/org/springframework/spring/4.1.1.RELEASE/spring-framework-4.1.1.RELEASE-dist.zip

Hibernate4.3.6:官网:http://hibernate.org/

http://softlayer-sng.dl.sourceforge.net/project/hibernate/hibernate4/4.3.6.Final/hibernate-release-4.3.6.Final.zip

四、项目目录



五 、创建项目

1、创建一个 webweb 项目 ,设置 如下 :





2、导入jar包

需导入的jar包详见下图,有多个jar包冲突不能同时到导入。除了导入到classpath中,由于jar包没放在\WEB-INF\lib目录中,在使用MyEclipse等开发工具将项目部署到Tomcat等服务器时,开发工具并不会自动复制所有jar包,需要我们手动复制这些jar到\WEB-INF\lib中。







3、安装Hibernate

项目虽导入hibernate的jar包,但不操作此步骤,无法添加反向工程。只需要安装hibernate4以上的版本。





已手动添加jar包,且版本不一样,此处不用再添加任何jar包



hibernate 数据库connection配置,如果还没配置driver可以 new一个。



添加反向工程



注意Hibernate主键生成策略,应根据自己模型设计选择主键生成策略。

1、自动增长identity

适用于MySQL、DB2、MS SQL Server,采用数据库生成的主键,用于为long、short、int类型生成唯一标识
使用SQL Server 和 MySQL 的自增字段,这个方法不能放到 Oracle 中,Oracle 不支持自增字段,要设定sequence(MySQL 和 SQL Server 中很常用)
数据库中的语法如下:
MySQL:create table t_user(id int auto_increment primary key, name varchar(20));
SQL Server:create table t_user(id int identity(1,1) primary key, name varchar(20));

<id name="id" column="id" type="long">
<generator class="identity" />
</id>

2、sequence

DB2、Oracle均支持的序列,用于为long、short或int生成唯一标识
数据库中的语法如下:
Oracle:create sequence seq_name increment by 1 start with 1;
需要主键值时可以调用seq_name.nextval或者seq_name.curval得到,数据库会帮助我们维护这个sequence序列,保证每次取到的值唯一,如:
insert into tbl_name(id, name) values(seq_name.nextval, ‘Jimliu’);

<id name="id" column="id" type="long">
<generator class="sequence">
<param name="sequence">seq_name</param>
</generator>
</id>

3、assigned

由应用程序负责生成主键标识符,往往使用在数据库中没有代理主键,使用的主键与业务相关的情况,如:

<id name="id" column="id" type="string">
<generator class="assigned" />
</id>

这种主键的生成方式不建议使用,在数据库表设计时就应该使用代理主键(surrogate key),不应使用自然主键(natural key具有业务含义),在没有指定<generator>标签时,默认就是assigned主键的生成方式
在插入数据的时候主键由用户自己添加,hibernate也不管

六、相关配置

1、JDBC配置

#######################  DB Connection Config  #######################

###----------------- DB Type -----------------
#the database of the application:mysql|sqlserver|oracle
databaseType=mysql
#databaseType=sqlserver
#databaseType=oracle

###----------------- MySQL5+ -----------------
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.1.1:3306/testdb?useUnicode=true&characterEncoding=utf-8
jdbc.username=test
jdbc.password=test
hibernate.dialect=org.hibernate.dialect.MySQLDialect

###----------------- SqlServer2005+ -----------------
#jdbc.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
#jdbc.url=jdbc:sqlserver://localhost:1433;DatabaseName=sampledb
#jdbc.username=sa
#jdbc.password=123456
#hibernate.dialect=org.hibernate.dialect.SQLServerDialect

###----------------- Oracle10g+ -----------------
#jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
#jdbc.url=jdbc:oracle:thin:@localhost:1521:orac10g
#jdbc.username=scott
#jdbc.password=scott123
#hibernate.dialect=org.hibernate.dialect.OracleDialect

###----------------- JNDI -----------------
#jndi.name=myjndi123

###----------------- Hibernate -----------------
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.hbm2ddl.auto=update
hibernate.jdbc.fetch_size=100
hibernate.jdbc.batch_size=20

hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=true
hibernate.memcached.cacheTimeSeconds=10800
#Hibernate4
hibernate.cache.region.factory_class=org.hibernate.cache.EhCacheRegionFactory
#Hibernate3
#hibernate.cache.region.factory_class=org.hibernate.cache.EhCacheProvider

###----------------- C3P0 -----------------
c3p0.maxPoolSize=50
c3p0.minPoolSize=1
c3p0.initialPoolSize=1
c3p0.maxIdleTime=20

###----------------- DBCP -----------------
dbcp.maxActive=50
dbcp.maxIdle=50
dbcp.minIdle=1
dbcp.maxWait=10000
dbcp.initialSize=1


2、hibernate.cfg.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>

<!-- 基本配置:JDBC方式 -->
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="hibernate.connection.url">
jdbc:mysql://192.168.1.1:3306/testdb?useUnicode=true&characterEncoding=utf-8
</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">
abcd.1234
</property>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>

<!-- 扩展配置 -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.jdbc.fetch_size">100</property>
<property name="hibernate.jdbc.batch_size">30</property>

<!-- 配置二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">
true
</property>
<property name="hibernate.cache.use_query_cache">true</property>
<!-- Hibernate4,这里和Hibernate3不一样,要特别注意!!! -->
<property name="hibernate.cache.region.factory_class">
org.hibernate.cache.EhCacheRegionFactory
</property>
<!-- Hibernate3 -->
<!-- <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> -->

<!-- 配置C3P0 -->
<property name="hibernate.connection.provider_class">
org.hibernate.connection.C3P0ConnectionProvider
</property>
<property name="hibernate.c3p0.max_size">10</property>
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_statements">3</property>
<property name="hibernate.c3p0.timeout">30</property>
<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.idle_test_periodt">10</property>

<!-- 领域对象:映射文件方式 -->
<property name="myeclipse.connection.profile">testdb</property>
<property name="connection.url">jdbc:mysql://192.168.1.1:3306/testdb</property>
<property name="connection.username">test</property>
<property name="connection.password">test</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

<!-- 领域对象:Annotation注解方式
<mapping class="实体类全限定名" />
-->

</session-factory>
</hibernate-configuration>


3、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:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> 
<!-- 说明:下面有的Bean配置提供了多种方案,请根据需要采用某一种(别忘了注释掉其他同类方案) -->

<!-- 自动扫描Spring注解配置 -->
<context:component-scan base-package="cases" />

<!-- 自动加载属性配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties" />

<!-- 配置数据源:方法一,使用C3P0方式(推荐) -->
<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}" />

<!-- 配置数据源:方法二,使用DBCP方式(不推荐) -->
<!--
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}" />
-->

<!-- 配置数据源:方法三,使用JNDI方式 -->
<!--
<jee:jndi-lookup id="dataSource" jndi-name="${jndi.name}" />
-->

<!-- 配置Hibernate的数据源代理工厂:方法一,使用p属性通配符,按文件名搜索匹配的映射文件 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
p:dataSource-ref="dataSource" p:mappingLocations="classpath*:/cases/**/*.hbm.xml">
<property name="hibernateProperties">
<props>
<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.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</prop>
</props>
</property>
</bean>
<!-- 配置Hibernate的数据源代理工厂:方法二,使用list集合,按文件名搜索匹配的映射文件 -->
<!--
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
p:dataSource-ref="dataSource">
<property name="mappingLocations">
<list>
<value>classpath*:/com/**/*.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<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.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</prop>
</props>
</property>
</bean>
-->
<!-- 配置Hibernate的数据源代理工厂:方法三,使用p属性通配符,按目录搜索映射文件 -->
<!--
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
p:dataSource-ref="dataSource" p:mappingDirectoryLocations="classpath*:/com/**/domain">
<property name="hibernateProperties">
<props>
<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.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</prop>
</props>
</property>
</bean>
-->
<!-- 配置Hibernate的数据源代理工厂:方法四,使用hibernate.cfg.xml -->
<!--
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
p:dataSource-ref="dataSource" p:configLocation="classpath:hibernate.cfg.xml">
</bean>
-->

<!-- 配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />

<!-- 配置声明式事务:方法一,在Service实现类或者public实现方法上使用注解@Transactional,则此类或方法就会启用事务机制 -->
<tx:annotation-driven transaction-manager="transactionManager" />

<!-- 配置声明式事务:方法二,使用tx/aop命名空间的配置(其实还有方法三,由于快要过时不推荐使用了,这里就不给出方法三的配置了) -->
<!--
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="edit*" propagation="REQUIRED" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="new*" propagation="REQUIRED" />
<tx:method name="set*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="change*" propagation="REQUIRED" />
<tx:method name="get*" propagation="REQUIRED" read-only="true" />
<tx:method name="find*" propagation="REQUIRED" read-only="true" />
<tx:method name="load*" propagation="REQUIRED" read-only="true" />
<tx:method name="search*" propagation="REQUIRED" read-only="true" />
<tx:method name="*" propagation="REQUIRED" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="mypointcut" expression="execution(* com.**.service..*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="mypointcut" />
</aop:config>
-->

<!-- 下面三个Bean的配置可有可无,但配置后用处更大,通常用于BaseDao类、其他Dao类或特殊工具类中 -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate"
p:sessionFactory-ref="sessionFactory" />

<bean id="hibernateDaoSupport" class="org.springframework.orm.hibernate4.support.HibernateDaoSupport"
p:hibernateTemplate-ref="hibernateTemplate" abstract="true"/>

<bean id="sessionFactoryUtils" class="org.springframework.orm.hibernate4.SessionFactoryUtils" abstract="true"/>

</beans>


4、Struts.xml增加一些配置

<!-- 指定Web应用的默认编码,相当于调用request的setCharacterEncoding方法 -->
<constant name="struts.i18n.encoding" value="UTF-8" />
<!-- 设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭 -->
<constant name="struts.serve.static.browserCache" value="false" />
<!-- 当Struts2的配置文件修改后,系统是否自动重新加载配置文件,默认值为false(生产环境下使用),开发阶段最好打开 -->
<constant name="struts.configuration.xml.reload" value="true" />
<!-- 开发模式下使用,这样可以打印出更详细的日志信息 -->
<constant name="struts.devMode" value="true" />
<!-- 默认的视图主题 -->
<constant name="struts.ui.theme" value="simple" />
<!-- 把Action对象交给Spring创建和管理 -->
<constant name="struts.objectFactory" value="spring" />
<!-- Struts2处理的请求后缀,默认值是action -->
<constant name="struts.action.extension" value="do" />


七、通用基础数据库操作类(网上可以找到)

1.BaseDAO.java

package cases.dao;

import java.io.Serializable;
import java.util.List;

/**
* 基础数据库操作类
*
* @author arthurmok
*
*/
public interface BaseDAO<T> {

/**
* 保存一个对象
*
* @param o
* @return
*/
public Serializable save(T o);

/**
* 删除一个对象
*
* @param o
*/
public void delete(T o);

/**
* 更新一个对象
*
* @param o
*/
public void update(T o);

/**
* 保存或更新对象
*
* @param o
*/
public void saveOrUpdate(T o);

/**
* 查询
*
* @param hql
* @return
*/
public List<T> find(String hql);

/**
* 查询集合
*
* @param hql
* @param param
* @return
*/
public List<T> find(String hql, Object[] param);

/**
* 查询集合
*
* @param hql
* @param param
* @return
*/
public List<T> find(String hql, List<Object> param);

/**
* 查询集合(带分页)
*
* @param hql
* @param param
* @param page
*            查询第几页
* @param rows
*            每页显示几条记录
* @return
*/
public List<T> find(String hql, Object[] param, Integer page, Integer rows);

/**
* 查询集合(带分页)
*
* @param hql
* @param param
* @param page
* @param rows
* @return
*/
public List<T> find(String hql, List<Object> param, Integer page,
Integer rows);

/**
* 获得一个对象
*
* @param c
*            对象类型
* @param id
* @return Object
*/
public T get(Class<T> c, Serializable id);

/**
* 获得一个对象
*
* @param hql
* @param param
* @return Object
*/
public T get(String hql, Object[] param);

/**
* 获得一个对象
*
* @param hql
* @param param
* @return
*/
public T get(String hql, List<Object> param);

/**
* select count(*) from 类
*
* @param hql
* @return
*/
public Long count(String hql);

/**
* select count(*) from 类
*
* @param hql
* @param param
* @return
*/
public Long count(String hql, Object[] param);

/**
* select count(*) from 类
*
* @param hql
* @param param
* @return
*/
public Long count(String hql, List<Object> param);

/**
* 执行HQL语句
*
* @param hql
* @return 响应数目
*/
public Integer executeHql(String hql);

/**
* 执行HQL语句
*
* @param hql
* @param param
* @return 响应数目
*/
public Integer executeHql(String hql, Object[] param);

/**
* 执行HQL语句
*
* @param hql
* @param param
* @return
*/
public Integer executeHql(String hql, List<Object> param);

}


2
. BaseDAOImpl.java


package cases.dao;

import java.io.Serializable;
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 org.springframework.stereotype.Service;

import cases.dao.BaseDAO;

@Repository("baseDAO")
@SuppressWarnings("all")

public class BaseDAOImpl<T> implements BaseDAO<T> {

private SessionFactory sessionFactory;

public SessionFactory getSessionFactory() {
return sessionFactory;
}

@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}

private Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}

public Serializable save(T o) {
return this.getCurrentSession().save(o);
}

public void delete(T o) {
this.getCurrentSession().delete(o);
}

public void update(T o) {
this.getCurrentSession().update(o);
}

public void saveOrUpdate(T o) {
this.getCurrentSession().saveOrUpdate(o);
}

public List<T> find(String hql) {
return this.getCurrentSession().createQuery(hql).list();
}

public List<T> find(String hql, Object[] param) {
Query q = this.getCurrentSession().createQuery(hql);
if (param != null && param.length > 0) {
for (int i = 0; i < param.length; i++) {
q.setParameter(i, param[i]);
}
}
return q.list();
}

public List<T> find(String hql, List<Object> param) {
Query q = this.getCurrentSession().createQuery(hql);
if (param != null && param.size() > 0) {
for (int i = 0; i < param.size(); i++) {
q.setParameter(i, param.get(i));
}
}
return q.list();
}

public List<T> find(String hql, Object[] param, Integer page, Integer rows) {
if (page == null || page < 1) {
page = 1;
}
if (rows == null || rows < 1) {
rows = 10;
}
Query q = this.getCurrentSession().createQuery(hql);
if (param != null && param.length > 0) {
for (int i = 0; i < param.length; i++) {
q.setParameter(i, param[i]);
}
}
return q.setFirstResult((page - 1) * rows).setMaxResults(rows).list();
}

public List<T> find(String hql, List<Object> param, Integer page,
Integer rows) {
if (page == null || page < 1) {
page = 1;
}
if (rows == null || rows < 1) {
rows = 10;
}
Query q = this.getCurrentSession().createQuery(hql);
if (param != null && param.size() > 0) {
for (int i = 0; i < param.size(); i++) {
q.setParameter(i, param.get(i));
}
}
return q.setFirstResult((page - 1) * rows).setMaxResults(rows).list();
}

public T get(Class<T> c, Serializable id) {
return (T) this.getCurrentSession().get(c, id);
}

public T get(String hql, Object[] param) {
List<T> l = this.find(hql, param);
if (l != null && l.size() > 0) {
return l.get(0);
} else {
return null;
}
}

public T get(String hql, List<Object> param) {
List<T> l = this.find(hql, param);
if (l != null && l.size() > 0) {
return l.get(0);
} else {
return null;
}
}

public Long count(String hql) {
return (Long) this.getCurrentSession().createQuery(hql).uniqueResult();
}

public Long count(String hql, Object[] param) {
Query q = this.getCurrentSession().createQuery(hql);
if (param != null && param.length > 0) {
for (int i = 0; i < param.length; i++) {
q.setParameter(i, param[i]);
}
}
return (Long) q.uniqueResult();
}

public Long count(String hql, List<Object> param) {
Query q = this.getCurrentSession().createQuery(hql);
if (param != null && param.size() > 0) {
for (int i = 0; i < param.size(); i++) {
q.setParameter(i, param.get(i));
}
}
return (Long) q.uniqueResult();
}

public Integer executeHql(String hql) {
return this.getCurrentSession().createQuery(hql).executeUpdate();
}

public Integer executeHql(String hql, Object[] param) {
Query q = this.getCurrentSession().createQuery(hql);
if (param != null && param.length > 0) {
for (int i = 0; i < param.length; i++) {
q.setParameter(i, param[i]);
}
}
return q.executeUpdate();
}

public Integer executeHql(String hql, List<Object> param) {
Query q = this.getCurrentSession().createQuery(hql);
if (param != null && param.size() > 0) {
for (int i = 0; i < param.size(); i++) {
q.setParameter(i, param.get(i));
}
}
return q.executeUpdate();
}

}


至此,项目原型搭建完成,可在此架构上做业务开发了。

由于自己项目业务逻辑不一样,代码不便贴出,可参考下面文章用户登录实现的例子。
http://blog.csdn.net/ycb1689/article/details/22928519
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: