SSH 三大框架整合
Spring整合web项目
在Servlet当中直接加载配置文件,获取对象
存在问题
- 每次请求都会创建一个Spring的工厂,这样浪费服务器资源,应该一个项目只有一个Spring的工厂。
- 在服务器启动的时候,创建一个Spring的工厂。
- 创建完工厂,将这个工厂类保存到ServletContext中。
- 每次使用的时候都从ServletContext中获取。
解决方案
使用spring核心监听器ContextLoaderListener
引入jar包 spring-web.jar
配置监听器:
<!-- Spring的核心监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 加载Spring的配置文件的路径的,默认加载的/WEB-INF/applicationContext.xml -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
直接在Action当中获取工厂
@WebServlet("/MyServlet")
public class MyServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.service(req, resp);
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
// 获取工厂 程序启动时,保存到ServletContext中
ServletContext servletContext = this.getServletContext();
WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
// 获取对象
UserService userService = (UserService)applicationContext.getBean("userService");
userService.save();
}
}
public class UserService {
public void save(){
System.out.println("-save-");
}
}
applicationContext.xml 中配置:
<bean id="userService" class="com.study.ssh.demo2.UserService"/>
SSH整合
案例(将页面信息存储到数据库中)
准备数据库
DROP TABLE IF EXISTS `account`;
CREATE TABLE `account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`money` double DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
web层接收请求——struts
dao层——hibernate
(1)引入Jar包
链接: 微云链接
(2)引入配置文件
-
struts
- 创建配置文件
- 添加核心过滤器
-
hibernate
- 创建配置文件
-
spring
- 添加核心配置文件
- 在web.xml当中添加spring核心监听器
(3)创建包结构
action、dao、domain(pojo)、service、util
(4)创建相关类
- 创建domain,建立关系映射
- 创建CustomerAaction,配置Struts
- JSP当中input标签添加name跳转到action
- 创建Customer业务层,把业务层交给spring管理
(5)搭建 struts 环境
页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/account_save.action">
name:<input type="text">
money:<input type="text">
<input type="submit" value="提交">
</form>
</body>
</html>
创建 action 类
import com.opensymphony.xwork2.ActionSupport;
public class AccountAction extends ActionSupport {
public String save(){
System.out.println("AccountAction——save");
return null;
}
}
struts 核心配置文件(struts.xml)接收action
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<package name="struts" namespace="/" extends="struts-default">
<action name="account_*" class="com.ssh.action.AccountAction" method="{1}"/>
</package>
</struts>
如果页面点击提交时,控制台能够成功显示"AccountAction——save",说明struts 环境配置成功。
(6)action接收页面参数
创建模型(domain包下)
import lombok.Getter;
import lombok.Setter;
@Getter @Setter
public class Account {
private String name;
private Double money;
@Override
public String toString() {
return "Account{" +
"name='" + name + '\'' +
", money=" + money +
'}';
}
}
web层(action)接收参数(采用模型驱动)
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.ssh.domain.Account;
public class AccountAction extends ActionSupport implements ModelDriven<Account> {
private Account account = new Account();
@Override
public Account getModel() {
return account;
}
public String save(){
System.out.println("AccountAction——save");
System.out.println(account);
return null;
}
}
jsp页面提供name属性且值和对象属性一致
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/account_save.action">
name:<input type="text" name="name">
money:<input type="text" name="money">
<input type="submit" value="提交">
</form>
</body>
</html>
页面点击提交时,控制台能够成功显示对象的信息且参数正确,接收页面参数成功。
(7)创建业务层(面向接口)
接口
import com.ssh.domain.Account;
public interface AccountService {
public void save(Account account);
}
实现类
import com.ssh.domain.Account;
public class AccountServiceImpl implements AccountService{
@Override
public void save(Account account) {
System.out.println("已经来到业务类:"+account);
}
}
web层(action)调用业务层(service)
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.ssh.domain.Account;
import com.ssh.service.AccountService;
import com.ssh.service.AccountServiceImpl;
public class AccountAction extends ActionSupport implements ModelDriven<Account> {
private Account account = new Account();
@Override
public Account getModel() {
return account;
}
public String save(){
/*System.out.println("AccountAction——save");
System.out.println(account);*/
// 调用业务层
AccountService accountService = new AccountServiceImpl();
accountService.save(account);
return null;
}
}
(8)引入spring框架
spring核心配置文件(applicationContext.xml)配置:将业务层交给spring管理。
<?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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- service bean -->
<bean id="accountService" class="com.ssh.service.AccountServiceImpl"/>
</beans>
web层(action)通过spring调用业务层(service)
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.ssh.domain.Account;
import com.ssh.service.AccountService;
import com.ssh.service.AccountServiceImpl;
import org.apache.struts2.ServletActionContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletContext;
public class AccountAction extends ActionSupport implements ModelDriven<Account> {
private Account account = new Account();
@Override
public Account getModel() {
return account;
}
public String save(){
/*System.out.println("AccountAction——save");
System.out.println(account);*/
// 调用业务层
/*AccountService accountService = new AccountServiceImpl();
accountService.save(account);*/
// 通过spring调用业务层
ServletContext servletContext = ServletActionContext.getServletContext();
/*获取工厂*/
WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
/*获取对象*/
AccountService accountService = (AccountService)applicationContext.getBean("accountService");
accountService.save(account);
return null;
}
}
(9)自动注入spring对象
需要导入 struts2-spring-plugin-2.5.16.jar
web层(action)通过自动注入spring对象调用业务层(service)
- 需要提供属性和set方法
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.ssh.domain.Account;
import com.ssh.service.AccountService;
import com.ssh.service.AccountServiceImpl;
import org.apache.struts2.ServletActionContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletContext;
public class AccountAction extends ActionSupport implements ModelDriven<Account> {
private Account account = new Account();
@Override
public Account getModel() {
return account;
}
// 自动注入
private AccountService accountService;
public void setAccountService(AccountService accountService) {
this.accountService = accountService;
}
public String save(){
/*System.out.println("AccountAction——save");
System.out.println(account);*/
// 调用业务层
/*AccountService accountService = new AccountServiceImpl();
accountService.save(account);*/
// 通过spring调用业务层
/*ServletContext servletContext = ServletActionContext.getServletContext();
*//*获取工厂*//*
WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
*//*获取对象*//*
AccountService accountService = (AccountService)applicationContext.getBean("accountService");
accountService.save(account);*/
accountService.save(account);
return null;
}
}
(10)action交给spring管理
优点
- 方便统一管理
- 可以对action通过AOP做增强
struts.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<package name="struts" namespace="/" extends="struts-default">
<!--class 值是spring中的id-->
<action name="account_*" class="accountAction" method="{1}"/>
</package>
</struts>
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress ALL -->
<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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--action bean -->
<!--注意:
1.scope="prototype" 必须是多例。
2.action中的service以前是交给struts管理的时候,它是自动注入的。现在交给spring管理,需要自己手动注入。
-->
<bean id="accountAction" class="com.ssh.action.AccountAction" scope="prototype">
<property name="accountService" ref="accountService"/>
</bean>
<!-- service bean -->
<bean id="accountService" class="com.ssh.service.AccountServiceImpl"/>
</beans>
AccountAction:
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.ssh.domain.Account;
import com.ssh.service.AccountService;
public class AccountAction extends ActionSupport implements ModelDriven<Account> {
private Account account = new Account();
@Override
public Account getModel() {
return account;
}
// 自动注入
private AccountService accountService;
public void setAccountService(AccountService accountService) {
this.accountService = accountService;
}
public String save(){
accountService.save(account);
return null;
}
}
(11)引入Hibernate
在service层中,需要调用dao来访问数据库。
新建dao层接口和实现类:
import com.ssh.domain.Account;
public interface AccountDao {
public void save(Account account);
}
import com.ssh.domain.Account;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class AccountDaoImpl extends HibernateDaoSupport implements AccountDao {
@Override
public void save(Account account) {
System.out.println("AccountDaoImpl——保存到数据库中 dao");
this.getHibernateTemplate().save(account);
}
}
表的映射文件
<?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>
<class name="com.ssh.domain.Account" table="account">
<!--建立类属性哪一个是主键 还要跟数据库当中主键进行对应 -->
<id name="id" column="id">
<generator class="native" />
</id>
<!--建立类中的普通属性与数据库当中字段进行关联 -->
<property name="name" column="name" />
<property name="money" column="money" />
</class>
</hibernate-mapping>
spring 核心配置文件 applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress ALL -->
<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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 导入hibernate相关配置 -->
<import resource="hibernateApplication.xml"/>
<!--action bean -->
<!--注意:
1.scope="prototype" 必须是多例。
2.action中的service以前是交给struts管理的时候,它是自动注入的。现在交给spring管理,需要自己手动注入。
-->
<bean id="accountAction" class="com.ssh.action.AccountAction" scope="prototype">
<property name="accountService" ref="accountService"/>
</bean>
<!-- service bean -->
<bean id="accountService" class="com.ssh.service.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<!--dao bean-->
<bean id="accountDao" class="com.ssh.dao.AccountDaoImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>
<?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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置hibernate -->
<!--引入属性文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driverClass}" />
<!--属性文件当中的名称不能和name名称一样-->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- Spring整合Hibernate -->
<!-- 引入Hibernate的配置的信息 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!-- 注入连接池 -->
<property name="dataSource" ref="dataSource"/>
<!-- 配置Hibernate的相关属性 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<!-- 设置映射文件 -->
<property name="mappingResources">
<list>
<value>com/ssh/domain/Account.hbm.xml</value>
</list>
</property>
</bean>
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!--开启注解 增强-->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
数据库链接配置 jdbc.properties
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3307/ssh
jdbc.username=root
jdbc.password=123456
HibernateTemplate的使用
接口
import com.ssh.domain.Account;
import java.util.List;
public interface AccountDao {
public void save(Account account);
public void update(Account account);
public void delete(Account account);
public Account getById(Integer id);
public List<Account> getAll();
}
实现类
import com.ssh.domain.Account;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Transactional
public class AccountDaoImpl extends HibernateDaoSupport implements AccountDao {
@Override
public void save(Account account) {
System.out.println("AccountDaoImpl——保存到数据库中 dao");
this.getHibernateTemplate().save(account);
}
@Override
public void update(Account account) {
this.getHibernateTemplate().update(account);
}
@Override
public void delete(Account account) {
this.getHibernateTemplate().delete(account);
}
@Override
public Account getById(Integer id) {
Account account = this.getHibernateTemplate().get(Account.class, id);
return account;
}
@Override
public List<Account> getAll() {
DetachedCriteria criteria = DetachedCriteria.forClass(Account.class);
List<Account> list = (List<Account>)this.getHibernateTemplate().findByCriteria(criteria);
return list;
}
}
测试
import com.ssh.domain.Account;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AccountDaoTest {
@Resource(name="accountDao")
private AccountDao accountDao;
@Test
public void save(){
Account account = new Account();
account.setName("zs");
account.setMoney(500d);
accountDao.save(account);
}
@Test
public void get(){
Account account = accountDao.getById(1);
System.out.println(account);
}
@Test
public void update(){
Account account = accountDao.getById(1);
account.setMoney(600d);
accountDao.update(account);
}
@Test
public void getAll(){
List<Account> list = accountDao.getAll();
for (Account account : list) {
System.out.println(account);
}
}
@Test
public void delete(){
Account account = accountDao.getById(3);
accountDao.delete(account);
}
}