Struts2+Hibernate5+Spring4 集成+详解+BaseAction的提高 效率

最近在做一个CRM的项目,用的是SSH,所以想在这里和你们分享一下项目中的运用

先说说框架整合.最初的架构是最简单的Struts2+Spring5+Hibernate5,

数据库使用的是MySQL,现在贴出所有需要的

Pom jar包

4.0.0

com.zking.maven

ssh

0.0.1-SNAPSHOT

war

UTF-8

4.3.10.RELEASE

5.2.5.Final

2.5.16

5.1.40

4.0.0

0.9.5.2

2.0

1.2.17

1.8.10

1.2.47

javax.servlet

javax.servlet-api

${servlet.version}

provided

javax.servlet

jsp-api

${jsp-api.version}

provided

org.springframework

spring-core

${spring.version}

org.springframework

spring-web

${spring.version}

org.springframework

spring-orm

${spring.version}

org.apache.struts

struts2-core

${struts2.version}

org.apache.struts

struts2-json-plugin

${struts2.version}

org.apache.struts

struts2-spring-plugin

${struts2.version}

org.hibernate

hibernate-core

${hibernate.version}

org.javassist

javassist

junit

junit

4.12

test

com.mchange

c3p0

${c3p0.version}

mysql

mysql-connector-java

${mysql.version}

org.aspectj

aspectjweaver

${aspectj.version}

com.alibaba

fastjson

${fastjson.version}

net.sf.ehcache

ehcache

2.10.4

org.hibernate

hibernate-ehcache

${hibernate.version}

com.fasterxml.jackson.core

jackson-databind

2.9.4

javax.xml.bind

jaxb-api

2.1

com.sun.xml.bind

jaxb-impl

2.1.2

ssh

org.apache.maven.plugins

maven-compiler-plugin

3.7.0

1.8

1.8

UTF-8

好了 准备工作做完了

开始建立对应的Xml 文件了

各部分的配置及文件分别是

struts.xml;

Hibernate.cfg.xml,jdbc.properties

applicationContext.xml;

首页 我们要对spring 与 hibernate 进行整合 我们知道 spring 在SSH中 类似于黏合剂 它上接 hibernate 下接 struts2,对

hibernate首先整合 主要是方便做测试 以及调试 工作

hibernate.cfg.xml 的配置如下

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

2

org.hibernate.dialect.MySQL5InnoDBDialect

true

true

true

org.hibernate.cache.ehcache.EhCacheRegionFactory

true

100

30

jdbc:mysql://localhost:3306/mytest

com.mysql.jdbc.Driver

注意 在自己我们没有对hibernate 与MYSQL 进行完全的配置 ,以为还有数据库的密码与用户信息等,我们没有在这里进行配置,主要原因是

1.我们会为其配置一个数据源 文件 jdbc.properties 将对应属性 设置在这里面 方便 以后进行更改

2.其次是以为,spring5需要为其配置一个C3p0 数据源 所以 干脆 我们就这样做 会方便的多

你也可以 在hebernate 中 进行测试 后 再建立数据源

jdbc.properties

jdbc.jdbcUrl=jdbc:mysql://localhost:3306/mytest

jdbc.driverClass=com.mysql.jdbc.Driver

jdbc.user=root

jdbc.password=12345

jdbc.initialPoolSize=5

jdbc.maxPoolSize=10

OrdersEntity的映射文件 如下

package com.zking.module.custormer.entity;

import javax.persistence.*;

import java.sql.Timestamp;

@Entity

@Table(name = "orders", schema = "mytest", catalog = "")

public class OrdersEntity {

private int odrId;

private String odrCustomer;

private Timestamp odrDate;

private String odrAddr;

private String odrStatus;

@Id

@Column(name = "odr_id")

public int getOdrId() {

return odrId;

}

public void setOdrId(int odrId) {

this.odrId = odrId;

}

@Basic

@Column(name = "odr_customer")

public String getOdrCustomer() {

return odrCustomer;

}

public void setOdrCustomer(String odrCustomer) {

this.odrCustomer = odrCustomer;

}

@Basic

@Column(name = "odr_date")

public Timestamp getOdrDate() {

return odrDate;

}

public void setOdrDate(Timestamp odrDate) {

this.odrDate = odrDate;

}

@Basic

@Column(name = "odr_addr")

public String getOdrAddr() {

return odrAddr;

}

public void setOdrAddr(String odrAddr) {

this.odrAddr = odrAddr;

}

@Basic

@Column(name = "odr_status")

public String getOdrStatus() {

return odrStatus;

}

public void setOdrStatus(String odrStatus) {

this.odrStatus = odrStatus;

}

@Override

public boolean equals(Object o) {

if (this == o) return true;

if (o == null || getClass() != o.getClass()) return false;

OrdersEntity that = (OrdersEntity) o;

if (odrId != that.odrId) return false;

if (odrCustomer != null ? !odrCustomer.equals(that.odrCustomer) : that.odrCustomer != null) return false;

if (odrDate != null ? !odrDate.equals(that.odrDate) : that.odrDate != null) return false;

if (odrAddr != null ? !odrAddr.equals(that.odrAddr) : that.odrAddr != null) return false;

if (odrStatus != null ? !odrStatus.equals(that.odrStatus) : that.odrStatus != null) return false;

return true;

}

@Override

public int hashCode() {

int result = odrId;

result = 31 * result + (odrCustomer != null ? odrCustomer.hashCode() : 0);

result = 31 * result + (odrDate != null ? odrDate.hashCode() : 0);

result = 31 * result + (odrAddr != null ? odrAddr.hashCode() : 0);

result = 31 * result + (odrStatus != null ? odrStatus.hashCode() : 0);

return result;

}

@Override

public String toString() {

return "OrdersEntity{" +

"odrId=" + odrId +

", odrCustomer='" + odrCustomer + '\'' +

", odrDate=" + odrDate +

", odrAddr='" + odrAddr + '\'' +

", odrStatus='" + odrStatus + '\'' +

'}';

}

}

好了 hibernate 准备工作基本 完成

开始集成了

在spring的配置文件中配置 如下

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

id="txPointCut"/>

这里 我本来是采用注解式 开发的 这样 我们就不需要配置事物这些东西了

但是 注解式 开发 后期维护 起来 很麻烦

好处在于 我们的 依赖的注入 完全可以直接用 注解的方式

所以 我们2种 都用吧

各个优点我们都有了 这样的话 事物 我们就用 AOP 其他 不用管

spring会帮你处理

好了 到这一步时 我们得做测试了

来个Test 测试类

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-beans.xml"); SessionFactory dataSource = (SessionFactory) ctx.getBean("sessionFactory"); Session session = dataSource.getCurrentSession(); System.out.println(session);

这里主要测试 session 是否已经取到 我们操作 hibernate 就要用到 session 所以 它 必须 要取到的

SessionFactory 是从 spring applicationContext-beans.xml 取到的

这里从 SessionFactory 取session 有2种方式

getCurrentSession() 与 openSession() 主要在于 他们 处理事物的区别

getCurrentSession()可以帮你自动开启事物 而 后面那个就不可以了

进行到这里 spring 与 hibernate 配置工作就完成了

开始 进行 struts2 与 spring的整合了

接下来在web.xml中指定spring的配置文件.

web.xml内容如下:

contextConfigLocation

classpath:applicationContext-*.xml

pattern

yyyy-MM-dd hh:mm:ss

org.springframework.web.context.ContextLoaderListener

struts2

org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter

struts2

/*

配置 struts2 的核心处理器 已经 hibernate 的监听

现在Hibernate已经纳入Spring的管理了.看看下面的业务代码,Service层的bean也已经被Spring管理了.

OrdersServiceImpl.java如下

package com.zking.module.custormer.service.impl;

import com.zking.module.custormer.dao.OrdersDao;

import com.zking.module.custormer.entity.OrdersEntity;

import com.zking.module.custormer.service.OrdersService;

import org.springframework.stereotype.Repository;

import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.util.List;

@Service("ordersService")

public class OrdersServiceImpl implements OrdersService {

@Resource

private OrdersDao ordersDao;

@Override

public List getAll() {

return ordersDao.getAll();

}

}

@Service: 该注解添加到业务层,表示这个类由spring管理.

@Resource是 取到 spring 的 依赖 它在dao层 我们已经注入了

OrdersAction.java如下

package com.zking.module.custormer.action;

import com.alibaba.fastjson.JSONObject;

import com.zking.base.action.BaseAction;

import com.zking.module.custormer.entity.CstLinkmanEntity;

import com.zking.module.custormer.entity.OrdersEntity;

import com.zking.module.custormer.service.OrdersService;

import com.zking.module.custormer.util.ResponseUtil;

import org.apache.struts2.ServletActionContext;

import org.springframework.stereotype.Controller;

import javax.annotation.Resource;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.util.List;

@Controller

public class Orders extends BaseAction {

@Resource

private OrdersService ordersService;

// 查询

public void list() throws Exception {

HttpServletRequest req = ServletActionContext.getRequest();

List list = ordersService.getAll();

System.out.println(list.size());

JSONObject result = new JSONObject();

result.put("total", list.size());

result.put("rows", list);

System.out.println(result.toJSONString());

HttpServletResponse response = ServletActionContext.getResponse();

try {

ResponseUtil.write(response,result);

} catch (Exception e) {

e.printStackTrace();

}

// return SUCCESS;

}

}

注意 我们在自己继承了 一个自己写的类BaseAction 他的作用是提高开发效率

为什么呢?

BaseAction.java 如下

package com.zking.base.action;

import java.lang.reflect.ParameterizedType;

import java.lang.reflect.Type;

import java.util.Map;

import javax.servlet.ServletContext;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.interceptor.ServletRequestAware;

import org.apache.struts2.interceptor.ServletResponseAware;

import org.apache.struts2.util.ServletContextAware;

import org.dom4j.rule.Mode;

import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionSupport;

import com.opensymphony.xwork2.ModelDriven;

@Controller

public class BaseAction extends ActionSupport implements ModelDriven,ServletRequestAware,ServletResponseAware,ServletContextAware{

public static final String SUCCESS="success";

public static final String FAILED="failed";

public static final String LIST="list";

public static final String EDIT="edit";

public static final String DETAIL="detail";

protected Object result;

protected String message;

public Object getResult() {

return result;

}

public String getMessage() {

return message;

}

protected T model;

@Override

public T getModel() {

ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass();

System.out.println(type);

Class clazz = (Class)type.getActualTypeArguments()[0];

System.out.println(clazz);

try {

if(model==null) {

model = (T)clazz.newInstance();

}

} catch (Exception e) {

throw new RuntimeException(e);

}

return model;

}

protected ServletContext application;

@Override

public void setServletContext(ServletContext context) {

this.application = context;

}

protected HttpServletResponse response;

@Override

public void setServletResponse(HttpServletResponse response) {

response.setCharacterEncoding("UTF-8");

response.setHeader("content-type", "text/html;charset=UTF-8");

this.response = response;

}

protected HttpServletRequest request;

@Override

public void setServletRequest(HttpServletRequest request) {

this.request = request;

}

}

我们可以在所以Action 都继承他 他里面包含了

ActionSupport , ModelDriven,ServletRequestAware,ServletResponseAware,ServletContextA

还定义了常量,重要的是getModel()这个方法 ,因为实现了

ModelDriven 所以 我们 需要 实例我们的 实体类 前台 传参就不是 类名.属性名了 直接是属性名 就 可以了

而getModel()就可以获取到 在这里我们将它设置为泛型 所以 在Action 里面 继承就可以直接插入他的类型

此外 还 包括 request , response 等 获取 ,这样必要的 东西在Action 里面 都包有 ,效率就提高了

好了 该配置 struts.xml 了 内容如下:

regex:.* /WEB-INF/jsp/roleAction/list.jsp role_list /WEB-INF/jsp/roleAction/saveUI.jsp

到这里就完全完成了 在这里做个测试 看 JSP跳 Action 是否成功 如果不成功检查配置 是否有问题

其实 SSH的整合 还是算 比较容易的 主要是要根据步骤去做 好处当然是在于方便调试 啊 不要 一气呵成

的就配置完 不然 哪里报错 都不知道 还有 在企业中 注解式 开发 还是有比较多的人使用 以为他相对于配置版

开发效率 大大提高 并且 比较容易 所以 还不会注解版的同学 都 了解 一下 其实 用的 标签 也就 几个 在不同

层 的 注解而已 ,此外 我们应用了BaseAction 其实 开发中 你也 可以往dao层 继续 加入BaseDao 因为dao层

与数据库打交道 所以增删改查是必须的 里面 泛型的使用 之后,Dao其他的类 继承后 就不需要写增删改查了

就会提高很过的效率

《镇魔曲》结婚系统
【世预赛】卫冕冠军阿根廷提前五轮出线,成第四支出线球队