1、整合思路
a. SSM介绍
springmvc+ spring + mybatis=ssm
mybatis 持久层的CURD
spring 业务层 IOC、DI(解耦) 和AOP(事务问题), ssm 综合练习中:aop解决日志问题
springMVC 表现层 MVC的操作
b. 整合使用的技术
1). Spring 5.0.2
2). mybatis 3.4.5
3). SpringMVC 5.0.2
4). log4J2 2.9.1
5). bootstrap 3.3.5
6). jquery 1.9.1
......
c. 业务介绍
我们需要完成一张账户表的增删改查操作
2、引入依赖和依赖分析
a. Spring相关的
1). spring-context : Spring容器
2). spring-tx : Spring事务
3). spring-jdbc : SpringJDBC
4). spring-test : Spring单元测试
5). spring-webmvc : SpringMVC
b. mybatis相关的
1). mybatis : mybatis核心
2). mybatis-spring :mybatis与spring整合
3) 切面相关的
aspectjweaver : AOP切面
4) 数据源相关(选择使用):
c3p0
commons-dbcp
spring自带的数据源
5) 单元测试相关的:
junit : 单元测试,与spring-test放在一起做单元测试
6) ServletAPI相关的
jsp-api : jsp页面使用request等对象
servlet-api : java文件使用request等对象
7) 日志相关的:
log4j-core : log4j2核心包
log4j-api : log4j2的功能包
log4j-web : web项目相关日志功能
slf4j-api : 另外一种日志包,
slf4j:Simple Logging Facade for Java为java做简单的日志记录此处和log4j一起
log4j-slf4j-impl : slf4j的log4j实现类,也就是说slf4j的日志记录功能由log4j实现
log4j-jcl : 程序运行的时候检测用了哪种日志实现类现在叫Apache Common Logging
8) 数据库相关的
mysql-connector-java : mysql的数据库驱动包
ojdbc.jar : oracle的驱动jar包
9) 页面表达式
JSTL : JSTL标签库必须jar包 基础功能
standard : JSTL标签库的必须jar包 进阶功能
10) 文件上传
commons-fileupload : 上传插件
commons-io : IO操作包
3、表和实体类的创建
1. 表
2. 实体类
public class Account {
private Integer id;
private String name;
private Float money;
}
4、Dao层的编写
a、引入依赖
org.mybatis
mybatis
3.4.5
mysql
mysql-connector-java
5.1.36
c3p0
c3p0
0.9.1.2
commons-dbcp
commons-dbcp
1.4
org.springframework
spring-jdbc
5.0.2.RELEASE
junit
junit
4.12
b、接口编写
package com.itheima.dao;
import com.itheima.domain.Account;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
/**
* @author 黑马程序员
* @Company http://www.ithiema.com
* @Version 1.0
*/
public interface AccountDao {
/**
* 查询所有
* @return
*/
@Select("select * from account")
public List findAll();
/**
* 根据id查询
* @param id
* @return
*/
@Select("select * from account where id = #{id}")
public Account findById(Integer id);
/**
* 保存账户
* @param account
*/
@Insert("insert into account values(null ,#{name},#{money})")
public void save(Account account);
/**
* 更新账户
* @param account
*/
@Update("update account set name = #{name},money=#{money} where id = #{id}")
public void update(Account account);
/**
* 删除一个账户
* @param id
*/
@Delete("delete from account where id = #{id}")
public void del(Integer id);
}
c、配置文件
d、测试
package com.itheima;
import com.itheima.dao.AccountDao;
import com.itheima.domain.Account;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;
/**
* @author 黑马程序员
* @Company http://www.ithiema.com
* @Version 1.0
*/
public class TestDao {
@Test
public void test(){
// 配置文件的输入流对象
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("SqlMapConfig.xml");
// session工厂对象
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获取一个SqlSession对象
SqlSession sqlSession = sessionFactory.openSession();
// 获取动态代理对象
AccountDao accountDao = sqlSession.getMapper(AccountDao.class);
// 执行方法
List accountList = accountDao.findAll();
// 遍历结果
for (Account account : accountList) {
System.out.println(account.getName());
}
// 释放资源
sqlSession.close();
}
}
e. spring 与mybatis整合操作
1)添加依赖
org.mybatis
mybatis-spring
1.3.1
org.springframework
spring-context
5.0.2.RELEASE
2) 删除了SqlMapConfig.xml
3) 添加一个applicationContext.xml文件
4) 测试
@Test
public void testMybatisWithSpring(){
//创建spring容器
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取容器中的对象
AccountDao accountDao = ac.getBean(AccountDao.class);
//执行方法
List accountList = accountDao.findAll();
//遍历结果
for (Account account : accountList) {
System.out.println(account.getName());
}
}
5、Service层编写
a、引入依赖
org.springframework
spring-context
5.0.2.RELEASE
org.springframework
spring-tx
5.0.2.RELEASE
org.aspectj
aspectjweaver
1.8.9
org.springframework
spring-test
5.0.2.RELEASE
b、接口编写
package com.itheima.service;
import com.itheima.domain.Account;
import java.util.List;
/**
* @author 黑马程序员
* @Company http://www.ithiema.com
* @Version 1.0
*/
public interface AccountService {
/**
* 查询所有
* @return
*/
public List findAll();
/**
* 根据id查询
* @param id
* @return
*/
public Account findById(Integer id);
/**
* 保存账户
* @param account
*/
public void save(Account account);
/**
* 更新账户
* @param account
*/
public void update(Account account);
/**
* 删除一个账户
* @param id
*/
public void del(Integer id);
}
c、实现类编写
package com.itheima.service.impl;
import com.itheima.dao.AccountDao;
import com.itheima.domain.Account;
import com.itheima.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author 黑马程序员
* @Company http://www.ithiema.com
* @Version 1.0
*/
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
AccountDao accountDao;
@Override
public List findAll() {
return accountDao.findAll();
}
@Override
public Account findById(Integer id) {
return accountDao.findById(id);
}
@Override
public void save(Account account) {
accountDao.save(account);
}
@Override
public void update(Account account) {
accountDao.update(account);
}
@Override
public void del(Integer id) {
accountDao.del(id);
}
}
d、配置文件,在applicationContext.xml中添加
e、测试
package com.itheima;
import com.itheima.domain.Account;
import com.itheima.service.AccountService;
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;
import java.util.List;
/**
* @author 黑马程序员
* @Company http://www.ithiema.com
* @Version 1.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestService {
@Autowired
AccountService accountService;
@Test
public void test(){
List accountList = accountService.findAll();
for (Account account : accountList) {
System.out.println(account.getName());
}
}
}
6、dao和service最终配置文件
7、web层编写
a、引入依赖
org.springframework
spring-webmvc
5.0.2.RELEASE
javax.servlet
servlet-api
2.5
provided
javax.servlet
jsp-api
2.0
provided
b、配置文件:springmvc.xml
c. 控制类的创建
package com.itheima.controller;
import com.itheima.domain.Account;
import com.itheima.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
/**
* @author 黑马程序员
* @Company http://www.ithiema.com
* @Version 1.0
*/
@Controller
@RequestMapping("/account")
public class AccountController {
@Autowired
AccountService accountService;
/**
* 查询全部
* @return
*/
@RequestMapping("/findAll")
public ModelAndView findAll(){
//查询数据
List accountList = accountService.findAll();
System.out.println(accountList);
ModelAndView modelAndView = new ModelAndView();
//添加数据
modelAndView.addObject("accountList",accountList);
//指定页面
modelAndView.setViewName("show");
return modelAndView;
}
/**
* 保存操作
* 执行service中的save方法
* 最后查询数据库中所有的的内容,在页面展示
*
*/
@RequestMapping("/save")
public String save(Account account){
//执行保存操作
accountService.save(account);
//执行查询所有
return "redirect:findAll";
}
@RequestMapping("/del")
public String del(Integer id){
//执行删除操作
accountService.del(id);
//执行查询所有
return "redirect:findAll";
}
/**
* 更新页面数据回显
* @return
*/
@RequestMapping("/updateUI")
public ModelAndView updateUI(Integer id){
//根据id查询一个账户
Account account = accountService.findById(id);
//创建模型视图对象
ModelAndView modelAndView = new ModelAndView();
//添加数据
modelAndView.addObject("account", account);
//指定页面
modelAndView.setViewName("update");
return modelAndView;
}
/**
* 更新账户
* @param account
* @return
*/
@RequestMapping("/update")
public String update(Account account){
//更新操作
accountService.update(account);
//执行查询所有
return "redirect:findAll";
}
}
8、编写web.xml
Archetype Created Web Application
contextConfigLocation
classpath:applicationContext.xml
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
CharacterEncodingFilter
/*
org.springframework.web.context.ContextLoaderListener
DispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring-mvc.xml
DispatcherServlet
/
9、编写页面
bootstrap 文档网站:https://www.w3cschool.cn/bootstrap/
a, 查询页面编写
1. show.jsp
<%--
Created by IntelliJ IDEA.
User: sun
Date: 2018/11/22
Time: 16:15
To change this template use File | Settings | File Templates.
--%>
<%@ page isELIgnored="false" contentType="text/html;charset=UTF-8" language="java" %>
<%--引入c 标签--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
Title
边框表格布局
编号
账户名
余额
<%--foreach循环
items: 要循环的集合对象
var:循环中的每一个对象
--%>
${account.id}
${account.name}
${account.money}
2. 引入bootstrap资源
3. jstl标签的依赖
jstl
jstl
1.2
taglibs
standard
1.1.2
b ,添加账户
<%--
Created by IntelliJ IDEA.
User: sun
Date: 2018/11/22
Time: 16:53
To change this template use File | Settings | File Templates.
--%>
<%@ page isELIgnored="false" contentType="text/html;charset=UTF-8" language="java" %>
Title
c, 删除操作
删除
d, 更新操作
<%--
Created by IntelliJ IDEA.
User: sun
Date: 2018/11/22
Time: 16:53
To change this template use File | Settings | File Templates.
--%>
<%@ page isELIgnored="false" contentType="text/html;charset=UTF-8" language="java" %>
Title
1、拦截器的作用
a. 拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
b. 拦截器链(Interceptor Chain)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
c. 拦截器,过滤器,监听器的区别
过滤器:是servlet的一部分,任何web项目都可以使用
配置 /* 后会过滤所有的资源(请求)
拦截器:是springMVC的一部分,只能在springMVC中使用
配置了/* 只会拦截请求,不会拦截静态资源
监听器:Web监听器是Servlet规范中的一种特殊类,用于监听ServletContext、HttpSession和 ServletRequest等域对象的创建与销毁事件,当Web应用启动时启动,当Web应用销毁时销毁。用于监听域对象的属性发生修改的事件,可以在事件发生前、发生后做一些必要的处理
d. 底层采用的是aop的思想
2、拦截器的代码
a. 引入依赖
org.springframework
spring-context
5.0.2.RELEASE
org.springframework
spring-webmvc
5.0.2.RELEASE
javax.servlet
servlet-api
2.5
provided
javax.servlet
jsp-api
2.0
provided
b.spring-mvc.xml
c. 创建拦截器类
package com.itheima.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 创建自己的拦截器类,需要实现接口HandlerInterceptor
* @author 黑马程序员
* @Company http://www.ithiema.com
* @Version 1.0
*/
public class MyInterceptor1 implements HandlerInterceptor{
/**
* 执行顺序:在控制器方法执行前执行
* 作用:拦截所有的请求,判断是否可以进行下一步执行
* 举例:如果判断你是否登录成功了,如果登录成功,则放行,返回值配置为true
* 如果登录失败,则拦截,返回值配置为false
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器1:preHandle执行了");
return true;
}
/**
* 执行的顺序: preHandel放行操作,可以执行
* 控制器方法返回值之前执行
* 作用:可以对返回的数据验证
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("拦截器1:postHandle执行了");
}
/**
* 执行顺序:preHandler必须放行, 执行完postHandle,之后执行
* 作用:释放资源
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("拦截器1:afterCompletion执行了");
}
}
3、多个拦截器测试
a. preHandler: 按照拦截器的配置顺序正序执行, 如果返回的都是true,则执行控制器的方法
b. postHandler: 所有的preHandler执行完之后,返回的都是true, 按照拦截器配置顺序倒序执行
c. afterCompletion: 所有postHandler执行完之后,
d. 配置多个拦截器
4、在ssm中使用拦截器示例
a, 登录页面
<%--
Created by IntelliJ IDEA.
User: sun
Date: 2018/11/22
Time: 16:53
To change this template use File | Settings | File Templates.
--%>
<%@ page isELIgnored="false" contentType="text/html;charset=UTF-8" language="java" %>
Title
b, spring-mvc.xml 添加拦截器配置
c, 创建拦截器类
package com.itheima.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author 黑马程序员
* @Company http://www.ithiema.com
* @Version 1.0
*/
public class LoginInterceptor implements HandlerInterceptor{
/**
* 登录验证
* 如果session有登录信息,放行
* 如果session没有登录信息,拦截
* 判断是否是登录请求,如果登录请求,直接放行
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//获取请求路径
String requestURI = request.getRequestURI();
//判断是否是登录请求
if(requestURI.contains("login")){
// 如果是登录请求,直接放行
return true;
}
//从session中获取登录信息
Object username = request.getSession().getAttribute("username");
if(username != null){
//session中有登录信息,放行
return true;
}else{
//session没有登录信息,跳转到登录页面
response.sendRedirect("/login.jsp");
return false;
}
}
}