目录
第一节 web 整合 servlet + spring
第一步:创建项目导入jar包
- 创建一个web项目,使用web.xml配置文件
- 导入jar包,注意要导入spring-web-3.2.0.RELEASE.jar(web整合包),其余jar包用前一天的即可,大部分用不到
第二步:创建Service与Servlet
- 创建一个简单的service用于测试
- 实现类
- 创建一个servlet
package com.it.web.servlet;
import com.it.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取参数
String username = request.getParameter("username");
//调用service
//service创建,由spring创建,从spring容器获取user
UserService userService = null;
/*开发中,项目只需要加载一次spring配置文件即可*/
/*ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(context.hashCode());
userService = (UserService) context.getBean("userService");
userService.add(username);*/
//获取applicationContext对象
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
System.out.println(context.hashCode());
userService = (UserService) context.getBean("userService");
userService.add(username);
//响应(在页面上显示)
response.getWriter().write("register success");
}
}
第三步:写spring配置文件applicationContext.xml
- 拷贝前一天的spring配置文件beans3.xml改名成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: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 class="com.it.service.impl.UserServiceImpl" id="userService"></bean>
</beans>
第四步:试运行
- 发现问题:每次刷新都要加载一次spring配置文件(hashCode值不同,对象不同),(如果加载过多)这样是很费时费性能的
- 开发中,只需加载一次spring配置文件
第五步:在web.xml中配置spring监听器
- 光这样配置是不行的,默认获取的是【/WEB-INF/applicationContext.xml路径下的文件】,而我们常将spring配置文件放在src目录下
- 查看ContextLoaderListener的父类ContextLoader发现
- 配置如下
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--配置spring配置文件的加载路径在类路径(src)下-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--配置spring监听器,目的是加载配置文件,生成bean-->
<listener>
<!--默认获取的是【/WEB-INF/applicationContext.xml路径下的文件】-->
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
第六步:在Servlet中通过工具类获取Spring的配置
- 通过WebApplicationContextUtils来获取
第二节 web 整合 struts + hibernate + spring(SSH整合)
整合版本
struts-2.3.33-all
spring-framework-3.0.2.RELEASE
hibernate-distribution-3.6.10.Final-dist
第一步:创建web项目 web-ssh
第二步:整合jar包
1. 导入struts的jar包
2. 导入spring的jar包
- 核心:4+1 , beans、core、context、expression , commons-logging【日志】
- AOP:aop联盟(aopalliance)、spring aop 、aspect规范(aspect.weaver)、spring aspect
- db:jdbc、tx【事务】
- 测试:test
- web开发:spring web
- 驱动:mysql
- 连接池:c3p0
- 整合hibernate:spring orm
3. 导入Hibernate的jar包
4. 整合log4j
slf4j-log4j12-1.7.2.jar是桥接左右2个jar包作用(桥梁互通)
5. 二级缓存(整合ehcache)
6. 整合包
- spring整合hibernate: spring orm【上面已导入】
- struts 整合spring:struts2-spring-plugin-2.3.33.3.jar
7. 删除重复jar包
- 删除其中一个
第三步:spring整合hibernate的单元测试
1. 写一个po类与映射文件
- User.java
package com.it.model;
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
public User() {
}
public User(String username, String password, Integer age) {
this.username = username;
this.password = password;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", age=" + age +
'}';
}
}
- User.hbm.xml
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.it.model">
<!-- name:模型的全名称-->
<class name="User" table="t_user">
<!-- name:模型属性名 -->
<id name="id">
<!-- generator:id的生成策略
native:如果是mysql数据库,id会自动增长
-->
<generator class="native"></generator>
</id>
<!-- 如果模型的属性和数据库的列名一样,就不用写column -->
<property name="username" length="32"></property>
<property name="password" length="32"></property>
<property name="age"></property>
</class>
</hibernate-mapping>
2. dao实现类
package com.it.dao.impl;
import com.it.dao.UserDao;
import com.it.model.User;
import org.springframework.orm.hibernate3.HibernateTemplate;
/**
* @ClassName UserServiceImpl
* @Author shuyy
* @Date 2020/9/17
**/
public class UserDaoImpl implements UserDao {
private HibernateTemplate hibernateTemplate;//提供set方法,由spring注入
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
@Override
public void add(User user) {
hibernateTemplate.save(user);
}
}
3. service实现类
package com.it.service.impl;
import com.it.dao.UserDao;
import com.it.model.User;
import com.it.service.UserService;
/**
* @ClassName UserServiceImpl
* @Author shuyy
* @Date 2020/9/17
**/
public class UserServiceImpl implements UserService {
private UserDao userDao;//提供set,由spring注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void register(User user) {
userDao.add(user);
}
}
4. hibernate.cfg.xml
- 如果使用update报错,就先使用create,再改成update
<!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>
<!-- 1.配置数据库连接的4个参数 -->
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///web-ssh</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!-- 2.是否显示sql语句 -->
<property name="show_sql">true</property>
<!-- 3.是否格式化sql语句 -->
<property name="format_sql">true</property>
<!-- 4.是否自动提交事务:针对insert有效,针对delete无效 -->
<!--注释,现在使用spring来管理-->
<!--<property name="hibernate.connection.autocommit">true</property>-->
<!-- 5.开启与当前线程绑定session的功能
ThreadLocal<Connection>
ThreadLocal<ActionContext>
ThreadLocal<Session>
-->
<!--<property name="hibernate.current_session_context_class">thread</property>-->
<!-- 6.hibernate.hbm2ddl.auto
ddl数据库定义语言
配置映射文件与数据库表的关系
update:如果数据库有没表,自动帮你创表【常用】
如果hbm与数据表不一样,会更新【例如在User实体类中添加一个字段,程序执行,数据库会自动帮你更新表结构】
create:每次启动hibernate都帮你创建表【所以插入数据后再执行程序,会覆盖刷新】
create-drop,每次启动hibernate都帮你创建表,执行完后删除表【要你何用,用完就删,可以测试时使用,哈哈】
validate:检验hbm文件,如果与数据库的字段不一致,就抛出异常【还好】
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 7.hibernate.dialect:数据库方言
每个数据库都有自己的方言,MySQL有MySQL的方式,oracle有oracle的方式
因为一个意思有不同的表达方式,就如同不同地方有不同的方言
MySQL与oracle的分页语句不同:
mysql:分页使用limit
oracle:分页使用rownum
可以查看MySQLDialect和OracleDialect的getLimitString
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!--<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>-->
<!--配置c3p0-->
<!--
#hibernate.connection.provider_class org.hibernate.connection.C3P0ConnectionProvider
//c3p0提供者
#hibernate.c3p0.max_size 2 //最大连接数,同时最多得到的connection数
#hibernate.c3p0.min_size 2 //最小连接数
#hibernate.c3p0.timeout 5000 //连接超时时间5000毫秒(5秒)
#hibernate.c3p0.max_statements 100 //最多可以创建Statements对象的个数,就是可以执行SQL语句的对象的个数
#hibernate.c3p0.idle_test_period 3000 //检查连接池中所有空闲连接的间隔时间,单位为秒
#hibernate.c3p0.acquire_increment 2 //连接池中连接耗尽了一次性增加2个
#hibernate.c3p0.validate false //每次都验证连接是否可用,
-->
<!--<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.max_size">2</property>
<property name="hibernate.c3p0.min_size">2</property>
<property name="hibernate.c3p0.timeout">5000</property>
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<property name="hibernate.c3p0.acquire_increment">2</property>
<property name="hibernate.c3p0.validate">false</property>
-->
<!--
配置事务的隔离级别
1:读未提交
2:读已提交
4:可重复读
8:串行
-->
<!--<property name="hibernate.connection.isolation">4</property>-->
<!--配置开启二级缓存-->
<!--<property name="hibernate.cache.use_second_level_cache">true</property>-->
<!--配置二级缓存的实现-->
<!--<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>-->
<!--开启查询缓存-->
<!--<property name="hibernate.cache.use_query_cache">true</property>-->
<!-- 8.配置JavaBean与表的映射文件 -->
<mapping resource="com/it/model/User.hbm.xml" />
<!--配置类和集合缓存
注意:类缓存的配置在mapping下,由dtd约束
-->
<!--一般不会给客户配置只读缓存,这里只是测试一下二级缓存-->
<!--<class-cache class="com.it.hibernate.domain.Customer" usage="read-only"></class-cache>
<class-cache class="com.it.hibernate.domain.Order" usage="read-only"></class-cache>-->
<!--配置集合缓存-->
<!--<collection-cache collection="com.it.hibernate.domain.Customer.orders" usage="read-only"></collection-cache>-->
</session-factory>
</hibernate-configuration>
5. 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: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">
<!--配置sessionFactory-->
<bean class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" id="sessionFactory">
<!--配置hibernate的配置文件路径-->
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
</bean>
<!--配置hibernate的模板-->
<bean class="org.springframework.orm.hibernate3.HibernateTemplate" id="hibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!--配置dao-->
<bean class="com.it.dao.impl.UserDaoImpl" id="userDao">
<property name="hibernateTemplate" ref="hibernateTemplate"></property>
</bean>
<!--配置Service-->
<bean class="com.it.service.impl.UserServiceImpl" id="userService">
<property name="userDao" ref="userDao"></property>
</bean>
<!--配置事务-->
<!--1.配置事务管理器-->
<bean class="org.springframework.orm.hibernate3.HibernateTransactionManager" id="txManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!--2.配置通知-->
<tx:advice transaction-manager="txManager" id="txAdvice">
<tx:attributes>
<tx:method name="register"/>
</tx:attributes>
</tx:advice>
<!--3.把通知关联切入点-->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.it.service..*.*(..))"></aop:advisor>
</aop:config>
</beans>
6. 单元测试
package com.it.test;
import com.it.model.User;
import com.it.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @ClassName Demo01
* @Author shuyy
* @Date 2020/9/17
**/
@RunWith(SpringJUnit4ClassRunner.class)//整合junit
@ContextConfiguration(locations = "classpath:applicationContext.xml")//加载配置文件
public class Demo01 {
@Autowired//自动注入
private UserService userService;
@Test
public void test1(){
//保存一个用户
User user = new User("shu", "123", 18);
userService.register(user);
}
}
7. 简化:去除hibernate.cfg.xml文件
- 修改applicationContext.xml,将hibernate的配置放进来
<?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: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">
<!--数据源datasource-->
<bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///web-ssh"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!--配置sessionFactory-->
<bean class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" id="sessionFactory">
<!--1.配置数据源-->
<property name="dataSource" ref="dataSource"></property>
<!--2.hibernate的其它配置-->
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
</props>
</property>
<!--3.hibernate映射文件路径-->
<property name="mappingLocations" value="classpath:com/it/model/*.hbm.xml"></property>
</bean>
<!--配置hibernate的模板-->
<bean class="org.springframework.orm.hibernate3.HibernateTemplate" id="hibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!--配置dao-->
<bean class="com.it.dao.impl.UserDaoImpl" id="userDao">
<property name="hibernateTemplate" ref="hibernateTemplate"></property>
</bean>
<!--配置Service-->
<bean class="com.it.service.impl.UserServiceImpl" id="userService">
<property name="userDao" ref="userDao"></property>
</bean>
<!--配置事务-->
<!--1.配置hibernate事务管理器-->
<bean class="org.springframework.orm.hibernate3.HibernateTransactionManager" id="txManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!--2.配置通知-->
<tx:advice transaction-manager="txManager" id="txAdvice">
<tx:attributes>
<tx:method name="register"/>
</tx:attributes>
</tx:advice>
<!--3.把通知关联切入点-->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.it.service..*.*(..))"></aop:advisor>
</aop:config>
</beans>
由于版本和报错等问题,这里使用的环境是Spring4.2+jdk1.8+mysql8+hibernate3.6+tomcat8.5.29,使用Spring3.2+jdk1.7+mysql5也可以,主要是spring版本与jdk版本的匹配问题
第四步:spring整合struts
1. web.xml编写
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--1.web项目启动的时候就会加载spring的配置文件-->
<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>
<!--2.配置struts的拦截器-->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<!--配置struts拦截路径-->
<filter-mapping>
<filter-name>struts2</filter-name>
<!--拦截所有/*请求-->
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
2. struts.xml编写
- 从官方jar包中提供的项目中拷贝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>
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<action name="user_*" class="com.it.web.action.UserAction" method="{1}">
<result name="success">/success.jsp</result>
</action>
</package>
</struts>
- 并提供一个success.jsp页面
3. UserAction编写
package com.it.web.action;
import com.it.model.User;
import com.it.service.UserService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
/**
* @ClassName RegisteAction
* @Author shuyy
* @Date 2020/9/17
**/
public class UserAction extends ActionSupport implements ModelDriven {
private User user = new User();
private UserService userService;
//这里提供set方法,但是不需要在spring中配置注入
//因为struts核心core中有默认配置文件配置了如果属性名id一致会自动注入
public void setUserService(UserService userService) {
this.userService = userService;
}
public String register(){
//获取请求参数
System.out.println(user);
//调用service
userService.register(user);
//返回结果
return SUCCESS;
}
@Override
public Object getModel() {
return user;
}
}
4. 运行Tomcat
- http://localhost:8080/web_ssh_war_exploded/user_register?username=shu12&password=123&age=20
- 数据成功插入,整合完成