此次通过如下案例让大家理解SSH框架
案例步骤解析:
- 创建entity包,创建Person类和Car类
- 配置applicationContext.xml文件
- 在struts.xml文件中,配置实体类 在WebRoot目录中,创建regiest.jsp页面,并设计表单
- 在WebRoot目录中,创建list.jsp页面,接收Action返回参数
- 运行程序,在浏览器上输入http://localhost:8080/myCar_ssh/regiest.jsp查看运行结果
一. 创建entity包
1.编写实体类 Person
package com.car.entity;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "v_person")
public class Person implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "p_id")
private Integer pid;
@Column(name = "p_name")
private String pname;
@Column(name = "p_age")
private String page;
@Column(name = "p_sex")
private String psex;
@Column(name = "p_grade")
private String pgrade;
@Column(name = "p_no")
private String pno;
@Column(name = "p_driving")
private String pdriving;
@OneToMany(mappedBy = "person", targetEntity = Car.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Set<Car> cars = new HashSet<Car>();
public Integer getPid() {
return pid;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public String getPage() {
return page;
}
public void setPage(String page) {
this.page = page;
}
public String getPsex() {
return psex;
}
public void setPsex(String psex) {
this.psex = psex;
}
public String getPgrade() {
return pgrade;
}
public void setPgrade(String pgrade) {
this.pgrade = pgrade;
}
public String getPno() {
return pno;
}
public void setPno(String pno) {
this.pno = pno;
}
public String getPdriving() {
return pdriving;
}
public void setPdriving(String pdriving) {
this.pdriving = pdriving;
}
public Set<Car> getCars() {
return cars;
}
public void setCars(Set<Car> cars) {
this.cars = cars;
}
}
2.编写实体类 Car
package com.car.entity;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "v_car")
public class Car implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "c_id")
private Integer cid;
@Column(name = "c_category")
private String ccategory;
@Column(name = "c_number")
private String cnumber;
@Column(name = "c_age")
private String cage;
@ManyToOne(targetEntity = Person.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "p_id")
private Person person;
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public String getCcategory() {
return ccategory;
}
public void setCcategory(String ccategory) {
this.ccategory = ccategory;
}
public String getCnumber() {
return cnumber;
}
public void setCnumber(String cnumber) {
this.cnumber = cnumber;
}
public String getCage() {
return cage;
}
public void setCage(String cage) {
this.cage = cage;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
二. 创建action包
1.编写实体类 PersonAction
package com.car.action;
import java.util.List;
import org.apache.struts2.ServletActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import com.car.entity.Car;
import com.car.entity.Person;
import com.car.service.CarService;
import com.car.service.PersonService;
@Controller("personAction")//用于标注控制层组件
@Scope("prototype")//原型模式
public class PersonAction {
@Autowired
private PersonService personService;
private CarService carService;
private Person person;
private Car car;
private String msg;
public String insertPerson() {
personService.savePerson(person);
msg = "添加成功!";
return "success";
}
public String findPerson() {
// 此list集合要么放在全局变量,要么放在request
List<Person> list = personService.queryPerson();
ServletActionContext.getRequest().setAttribute("list", list);
return "list";
}
public PersonService getPersonService() {
return personService;
}
public CarService getCarService() {
return carService;
}
public void setCarService(CarService carService) {
this.carService = carService;
}
public void setPersonService(PersonService personService) {
this.personService = personService;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
}
2.编写实体类 CarAction
package com.car.action;
import java.util.List;
import org.apache.struts2.ServletActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import com.car.entity.Car;
import com.car.entity.Person;
import com.car.service.CarService;
@Controller("carAction")//用于标注控制层组件
@Scope("prototype")//原型模式
public class CarAction {
@Autowired
private CarService carService;
private Person person;
private Car car;
private String msg;
public String insertCar() {
car.setPerson(person);
carService.saveCar(car);
msg = "添加成功!";
return "success";
}
public String findCar() {
// 此list集合要么放在全局变量,要么放在request
List<Car> list = carService.queryCar();
ServletActionContext.getRequest().setAttribute("list", list);
return "list";
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
}
三. 创建DAO层
1.编写接口 CarDao和PersonDao
package com.car.dao;
import java.util.List;
import com.car.entity.Person;
public interface PersonDao {
public void savePerson(Person person);
public List<Person> queryPerson();
}
package com.car.dao;
import java.util.List;
import com.car.entity.Car;
public interface CarDao {
public void saveCar(Car car);
public List<Car> queryCar();
}
2.编写 DaoImpl
package com.car.dao.impl;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.car.dao.PersonDao;
import com.car.entity.Person;
@Repository("personDao")
public class PersonDaoImpl implements PersonDao {
@Autowired
private SessionFactory sf;
@Override
public void savePerson(Person person) {
// TODO Auto-generated method stub
Session s = sf.getCurrentSession();
s.save(person);
}
@Override
public List<Person> queryPerson() {
Session s = sf.getCurrentSession();
List<Person> list = s.createQuery("from Person").list();
return list;
}
public SessionFactory getSf() {
return sf;
}
public void setSf(SessionFactory sf) {
this.sf = sf;
}
}
package com.car.dao.impl;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.car.dao.CarDao;
import com.car.entity.Car;
@Repository("carDao")
public class CarDaoImpl implements CarDao {
@Autowired
private SessionFactory sf;
@Override
public void saveCar(Car car) {
// TODO Auto-generated method stub
Session s = sf.getCurrentSession();
s.save(car);
}
@Override
public List<Car> queryCar() {
Session s = sf.getCurrentSession();
List<Car> list = s.createQuery("from Car").list();
return list;
}
public SessionFactory getSf() {
return sf;
}
public void setSf(SessionFactory sf) {
this.sf = sf;
}
}
四. 创建Service层
1.编写接口 PersonService 和CarService
package com.car.service;
import java.util.List;
import com.car.entity.Person;
public interface PersonService {
public void savePerson(Person person);
public List<Person> queryPerson();
}
package com.car.service;
import java.util.List;
import com.car.entity.Car;
public interface CarService {
public void saveCar(Car car);
public List<Car> queryCar();
}
2.编写 ServiceImpl
package com.car.service.impl;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.car.dao.PersonDao;
import com.car.entity.Person;
import com.car.service.PersonService;
@Service("personService")
public class PersonServiceImpl implements PersonService {
@Autowired
private PersonDao personDaoimpl;
@Override
public void savePerson(Person person) {
personDaoimpl.savePerson(person);
}
@Override
public List<Person> queryPerson() {
return personDaoimpl.queryPerson();
}
}
package com.car.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.car.dao.CarDao;
import com.car.entity.Car;
import com.car.service.CarService;
@Service("carService")
public class CarServiceImpl implements CarService {
@Autowired
private CarDao carDaoimpl;
@Override
public void saveCar(Car car) {
carDaoimpl.saveCar(car);
}
@Override
public List<Car> queryCar() {
return carDaoimpl.queryCar();
}
public CarDao getCarDaoimpl() {
return carDaoimpl;
}
public void setCarDaoimpl(CarDao carDaoimpl) {
this.carDaoimpl = carDaoimpl;
}
}
五. 配置web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>myCar_ssh</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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>
</web-app>
六. 配置db.properties文件(连接数据库)
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/meitao
username=root
password=123456
七. 配置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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" 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-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.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
">
<!-- 自动扫描com.zr包下的spring注解 -->
<context:component-scan base-package="com.car"></context:component-scan>
<!-- aop切面编程使用自动代理。与aop的注解一起使用 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 加载,classpath表示去classes目录下查找 -->
<bean id="DBconfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:db.properties"></property>
</bean>
<!-- 把Druid的数据源对象交由spring管理 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="username" value="${username}" />
<property name="password" value="${password}" />
<property name="driverClassName" value="${driver}" />
<property name="url" value="${url}" />
<!-- 初始化连接池中的连接数,默认为10 -->
<property name="initialSize" value="10" />
<!--连接池中保留的最大连接数。默认值: 100 -->
<property name="maxActive" value="100" />
<!-- 连接池中保留的最小连接数,默认为:10 -->
<property name="minIdle" value="10" />
<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。默认值: 0 -->
<property name="maxWait" value="60"></property>
</bean>
<!-- SessionFactory交由spring管理 -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<!-- 为SessionFactory注入数据源 -->
<property name="dataSource" ref="dataSource"></property>
<!-- hibernate独有的属性配置 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.autocommit">true</prop>
<!-- 正向工程 -->
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<!-- 自动扫描com.zr.entity包下的所有hibernate注解实体或映射文件 -->
<property name="packagesToScan" value="com.car.entity"></property>
</bean>
<!-- 声明式事务,1.配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 2.配置事务范围 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="update*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="del*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="edit*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="query*" propagation="SUPPORTS" read-only="true" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 3.配置切入点,关联切入点与事务通知。 -->
<aop:config>
<aop:pointcut id="productServiceMethods" expression="execution(* com.car.service..*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods" />
</aop:config>
</beans>
八. 配置struts.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 把struts2的action类交由spring管理 -->
<constant name="struts.objectFactory" value="spring"></constant>
<!-- 当修改struts2的配置文件,自动重新加载 -->
<constant name="struts.configuration.xml.reload" value="true"></constant>
<!-- action标签的class 的值不再是类名,而是spring管理的bean的id -->
<package name="car" namespace="/" extends="struts-default">
<action name="car_*" method="{1}" class="carAction">
<result name="success" type="redirectAction">
<param name="actionName">car_findCar</param>
</result>
<result name="list">list.jsp</result>
</action>
</package>
</struts>
九. 编写JSP文件
1.创建regiest.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>驾驶员等级</title>
</head>
<body>
<div align="center">
<form action="car_insertCar.action" method="post">
驾驶员姓名:<input type="text" name="person.pname" /><br>
驾照等级:<select name="person.pgrade">
<option value="A1" selected="selected">A1</option>
<option value="A2">A2</option>
<option value="A3">A3</option>
<option value="B1">B1</option>
<option value="B2">B2</option>
<option value="C1">C1</option>
<option value="C3">C3</option>
<option value="C4">C4</option>
</select> <br>
驾照编号:<input type="text" name="person.pno" /><br>
驾龄:<input type="text" name="person.pdriving" /><br>
汽车类型:<input type="text" name="car.ccategory" /><br>
<input type="submit" name="注册" />
</form>
</div>
</body>
</html>
2.创建list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>驾驶员信息</title>
</head>
<body>
<h1>驾驶员信息表</h1>
<c:forEach items="${list}" var="car">
<hr color="blue" />
驾驶员姓名:${car.person.pname}------驾照等级:${car.person.pgrade}------驾照编号:${car.person.pno}
------驾龄:${car.person.pdriving}------汽车类型:${car.ccategory} <br>
</c:forEach>
</body>
</html>
十. 知识点汇总
1.@Autowir与@Resource注解的区别:
@Autowire 默认按照类型装配,默认情况下它要求依赖对象必须存在如果允许为null,可以设置它required属性为false,
如果我们想使用按照名称装配,可以结合@Qualifier注解一起使用;
@Resource默认按照名称装配,当找不到与名称匹配的bean才会按照类型装配,可以通过name属性指定,如果没有指定name属性,
当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,
即默认取属性名作为bean名称寻找依赖对象.
注意:如果没有指定name属性,并且按照默认的名称仍然找不到依赖的对象时候,会回退到按照类型装配,但一旦指定了name属性,
就只能按照名称装配了
2.Spring中的@scope注解
默认是单例模式,即scope="singleton"。另外scope还有prototype、request、session、global session作用域。scope="prototype"多例
@scope默认是单例模式(singleton)
如果需要设置的话@scope("prototype")
(1)singleton单例模式,
全局有且仅有一个实例
(2)prototype原型模式,
每次获取Bean的时候会有一个新的实例
spring容器在进行输出prototype的bean对象时,会每次都重新生成一个新的对象给请求方,
虽然这种类型的对象的实例化以及属性设置等工作都是由容器负责的,
但是只要准备完毕,并且对象实例返回给请求方之后,容器就不在拥有当前对象的引用,
请求方需要自己负责当前对象后继生命周期的管理工作,包括该对象的销毁。
也就是说,容器每次返回请求方该对象的一个新的实例之后,就由这个对象“自生自灭”,
最典型的体现就是spring与struts2进行整合时,要把action的scope改为prototype。
如同分苹果,将苹果的bean的scope属性声明为prototype,在每个人领取苹果的时候,
我们都是发一个新的苹果给他,发完之后,别人爱怎么吃就怎么吃,爱什么时候吃什么时候吃,
但是注意吃完要把苹果核扔到垃圾箱!对于那些不能共享使用的对象类型,应该将其定义的scope设为prototype。
(3)request
request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效,配置实例:
request、session、global session使用的时候首先要在初始化web的web.xml中做如下配置:
如果你使用的是Servlet 2.4及以上的web容器,那么你仅需要在web应用的XML声明文件web.xml中增加下述ContextListener即可:
<web-app>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
</web-app>
(4)session
session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效
(5)global session
global session作用域类似于标准的HTTP Session作用域,它仅在基于portlet的web应用中才有意义。
Portlet是基于Java的Web组件,由Portlet容器管理,并由容器处理请求,生产动态内容。
Portlet容器提供它们需求的运行时环境并运行Portlet。
它包含Portlets并控制它们的生命周期。
容器提供Portlet参数的持久存储机制,它接受来自Portal的request,并在其持有的Portlet上执行request。
容器不负责Portlet产生内容的聚合,Portal自己处理内容聚合。
Portals使用Portlets作为可插拔用户接口组件,提供信息系统的表示层
Portlet规范定义了全局Session的概念,它被所有构成某个 portlet web应用的各种不同的portlet所共享。
在global session作用域中定义的bean被限定于全局portlet Session的生命周期范围内。
如果在web中使用global session作用域来标识bean,那么web会自动当成session类型来使用。