MyBatis,Spring,SpringMvc,单元测试框架,日志框架Log4J

思维导图源文件获取,用xmind 8 打开github


MyBatis框架

概述

  • MyBatis是一个持久层框架/ORM框架,会对结果集(查询)映射,对JDBC简单的封装
    • insert
    • update
    • delete
    • selectOne
    • selectList
  • 持久化
    • 狭义:将数据永久的保存到数据库/磁盘等媒介
    • 广义:针对于数据的操作都称之持久化操作
    • 实体Bean == 持久化类
  • 需要的jar包
    • mybatis-3.4.6.jar
    • mysql-connector-java-5.1.45-bin.jar

CRUD操作

  • 针对于CUD操作,MyBatis需要手动提交事务

  • MyBatis的API调用过程

  • package com.hs.util;

  • /**

    • 知识点:
    • final修饰类:不能被继承
    • 修饰方法:不能被重写
    • 修饰变量:常量不可用变,但如果是对象,对象里的值可以变
  • */

  • import org.apache.ibatis.io.Resources;

  • import org.apache.ibatis.session.SqlSession;

  • import org.apache.ibatis.session.SqlSessionFactory;

  • import org.apache.ibatis.session.SqlSessionFactoryBuilder;

  • import java.io.IOException;

  • import java.io.InputStream;

  • public class MyBatisUtils {

  • private MyBatisUtils() { } //不允许实例化

  • private static final String PATH = “mybatis-config.xml”;

  • private static InputStream inputStream;

  • private static SqlSessionFactory sqlSessionFactory;

  • static { //1.静态代码块,只是加载一次

  • try {

  • //输入流 读文件

  • //1.读取核心配置文件

  • inputStream = Resources.getResourceAsStream(PATH);

  • //2.创建SqlSession工厂(SqlSessionFactory)相当于Connection

  • sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

  • } catch (IOException e) {

  • e.printStackTrace();

  • throw new RuntimeException(“加载核心配置文件失败”);

  • }

  • }

  • /**

  • *3.获取SqlSession 相当于 执行SQL语句对象PreparedStament预处理对象

    • SqlSession完成所有的持久化操作CRUD
  • */

  • public static SqlSession getSqlsession() {

  • return sqlSessionFactory.openSession();

  • }

  • /**

  • *6.关闭资源

  • */

  • public static void closeSqlSession(SqlSession sqlSession) {

  • if (sqlSession != null) {

  • sqlSession.close();

  • }

  • }

  • }

    • 1.读取核心配置文件 classpath(src)/mybatis-config.xml

      • 加载数据库信息属性文件jdbc.properties,${key}获取值

      • 自定义设置类型的别名

      • 配置数据库的环境

      • 加载映射文件

    • 2.创建SqlSession工厂 == SqlSessionFactory

    • 3.获取SqlSession

      • 连接数据库
      • 完成针对于数据的CRUD操作
    • 4.执行定制的SQL语句

      • 传统方式
        • 命名空间namespace持久化类的全路径
        • .
        • 映射文件的ID
      • 接口代理模式——推荐
        • 命名空间namespace固定必须为接口的全路径
        • 映射文件中的ID需要跟接口中的方法名保持一致
        • 查询操作:根据你的接口的返回值
          • selectOne
          • selectList
    • 5.事务的提交

      • Spring框架中有事务的管理
    • 6.关闭资源

  • 提取公共的字段代码

    • 无别名

    • role_id,role_name,role_key,status

    • 有别名

    • <math> <semantics> <mrow> <mrow> <mi> a </mi> <mi> l </mi> <mi> i </mi> <mi> a </mi> <mi> s </mi> </mrow> <mi mathvariant="normal"> . </mi> <mi> r </mi> <mi> o </mi> <mi> l </mi> <msub> <mi> e </mi> <mi> i </mi> </msub> <mi> d </mi> <mo separator="true"> , </mo> </mrow> <annotation encoding="application&#47;x&#45;tex"> {alias}.role_id, </annotation> </semantics> </math>alias.roleid,{alias}.role_name, <math> <semantics> <mrow> <mrow> <mi> a </mi> <mi> l </mi> <mi> i </mi> <mi> a </mi> <mi> s </mi> </mrow> <mi mathvariant="normal"> . </mi> <mi> r </mi> <mi> o </mi> <mi> l </mi> <msub> <mi> e </mi> <mi> k </mi> </msub> <mi> e </mi> <mi> y </mi> <mo separator="true"> , </mo> </mrow> <annotation encoding="application&#47;x&#45;tex"> {alias}.role_key, </annotation> </semantics> </math>alias.rolekey,{alias}.status

    • 概要: 如何用

  • 查询操作

    • 结果集的处理方式

      • resultType
      • resultMap
    • 结果集可以处理成什么方式?

      • 返回Map类型

        • resultType="map"或者resultType=“java.util.Map”
        • resultMap属性去找resultMap标签
          • 默认情况是自动映射
          • 可以设置别名
      • 返回List类型–>依旧使用Map处理结果

        • 只是在调用方法的时候使用selectList即可
      • 返回对象

        • 可以使用别名方式,保证查询的字段名称和类中的属性名称一致即可使用resultType完成对象的映射

        • 重点resultMap属性

          • 一对一和多对一的关联标签association

            • select方式

            • 结果集映射方式

            • resultMap id=“JoinResultMapper” type=“User” extends=“BaseResultMapper”>

动态的SQL语句

  • 在映射文件中获取数据的方式

    • #()
      • #()默认是预处理模式
    • $()
      • $()默认是直接拼接到SQL语句当中,并且需要提供KEY值,推荐在排序使用
  • if标签

    • test属性 test=“类中属性或者Map中的KEY或者使用@Param指定KEY”
  • where标签

    • 如果有内容,在内容的最前面加入where关键字,并且去掉内容最前面的and或者or

    • and user_name like concat(’%’,#{name},’%’)

    • and sex = #{sex}

  • set标签

    • 如果有内容,在内容的最前面加入set关键字,并且去掉内容最后面的逗号

    • user_name = #{user_name},

    • sex = #{sex},

    • money = #{money},

  • trim标签

    • 主要的目的是完成对动态添加SQL的拼写— 一般可以用来完成set和where功能

    • <trim prefix=“当发现有内容的时候,你在内容的最前面想加入什么内容”

    • prefixOverrides=“当发现有内容的时候,你在内容的最前面想抹掉什么内容”

    • suffix=“当发现有内容的时候,你在内容的最后面面想加入什么内容”

    • suffixOverrides=“当发现有内容的时候,你在内容的最后面想抹掉什么内容”>

  • foreach标签

    • 如果你传递的数据的形参为一个数据,并且数据类型是数组或者List
      • collection属性只能取array || list
    • 如果你传递的是Map或者对象(都有一个存储集合的属性或者KEY)
      • collection=“集合对应的Map中的KEY或者类中的属性”

传递多个参数

/**

  • 传递多个参数
  • 1.当你的形参传递>1个的时候,parameterType不写,让其自动处理
  • 2.#{值},默认为arg0,arg1…或param1,param2,,,
  • 若在dao注解了@xxx(相当于指明了key值),即也可以写xxx,默认的也可以写,相当于3个值

*/

User getUser(@Param(“account”) String account, @Param(“password”) String password);

接口代理模式和传统模式

  • 接口代理模式

  • 只需要写接口,在测试类中调用,接口编程: 什么是接口? 简单理解:接口就是定义规范

  • 接口返回类型跟你设置的resultMap或者resultType对应上即可,但是会根据你返回的类型完成selectone或者selectList操作

  • 接口里方法如何写:sql语句返回的结果集类型 sql语句的id(要传的值);

  • eg:List getSkillLike02(String name);

  • List为SQL语句返回的结果集类型,getSkillLike02为映射文件中SQL语句的id,String name是传给映射文件的值

  • 映射文件命名空间为接口的全路径

  • 可以根据接口的返回类型自动判断使用selectOne还是selectList

  • eg:返回的是一个对象的为one,返回的是list的就是List,如果是List,也是List

  • 传统模式

  • 需要写接口,接口实现类,测试类,

  • 映射文件命名空间为持久化类的全路径

单元测试框架

概述

  • 单元(方法)就是对类中方法的测试
  • 命名规则
    • 类名 UserDaoTest
    • 方法 testLoadMethod

需要的jar包

  • hamcrest-core-1.3.jar
  • junit-4.12.jar

如何使用

  • @Before

  • @Before //再每个单元测试运行之前都要进行这个方法

  • public void init() {

  • this.arithmeticService = new ArithmeticServiceImpl(); //想用哪个功能就实例化哪个

  • }

  • @Test

  • @Test //测试这个方法

  • public void test01() {}

日志框架Log4J

概述

  • 在MyBatis中显示出SQL语句,信息等,放在classpath路径下log4j.properties

需要的jar包

  • log4j-1.2.17.jar

如何使用

Global logging configuration

log4j.rootLogger=ERROR, stdout

MyBatis logging configuration…

如果要显示SQL语句,那么这个位置需要配置为命名空间

log4j.logger.com.shxt.model.Skill=TRACE

Console output…

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

SpringMVC框架

概述

  • 核心配置文件DispatcherServlet的规则

    • 默认情况下:WEB-INF/[servlet-name]-servlet.xml

    • springmvc

    • org.springframework.web.servlet.DispatcherServlet

    • 2

    • springmvc

需要的jar包

  • spring-aop-4.3.6.RELEASE.jar

spring-beans-4.3.6.RELEASE.jar

spring-context-4.3.6.RELEASE.jar

spring-context-support-4.3.6.RELEASE.jar

spring-core-4.3.6.RELEASE.jar

spring-expression-4.3.6.RELEASE.jar

spring-web-4.3.6.RELEASE.jar

spring-webmvc-4.3.6.RELEASE.jar

commons-logging-1.2.jar

控制器专题

  • 控制传递的参数

  • @RequestMapping(path = “/param02”,params = {“hs!=tomcat”,“method=add”})

  • 形参

    • 默认会对形参中的类进行自动的实例化操作
  • 页面跳转方式

    • 默认请求转发,能访问WEB-INF下
    • 重定向,不能访问WEB-INF下
    • 概要: 指明前缀,请求转发"forward:/hs011.jsp",重定向redirect:/xxx
  • 返回类型

    • ModelAndView

      • JSP的请求转发的视图解析器

jackson-core-2.8.1.jar

jackson-databind-2.8.1.jar

  • 访问路径

    • 路径的设置

      • /sys/user
      • /sys/*或者/sys/**—不推荐使用
      • /sys/user/{hs}占位符路径
        • 使用占位符,一般只是传递主键和简单的字符串,完成REST风格的路径,优先级比通配符高,hs接收传过的值
    • 请求方式的说明

      • HTML页面中有且只有GET/POST请求

      • 通过设置过滤器完成了8种请求方式

静态资源(图片、js、css)排除方案,不经过DispatcherServlet

处理方式一 推荐方式–>

<mvc:default-servlet-handler default-servlet-name=“default”/>

客户端传递数据转换成服务端对应的数据类型

  • @RequestParam注解

  • public ModelAndView test02(@RequestParam(value = “user_name”, required = false) String name,

  • @RequestParam(name = “user_id”, required = false, defaultValue = “1111”) Integer id) {

  • System.out.println(“姓名” + name);

  • System.out.println(“ID” + id);

  • return null;

  • }

    • name="" | value=""对应传递数据的名称
    • required="true"默认值
    • defaultValue=“设置默认值”
  • 简写方式 推荐:传递的name和形参中的名称保持一致即可

  • 数组

    • 超链接获取数组

    • 传递数组

    • @GetMapping("/client04")

    • public ModelAndView test01(@RequestParam(name = “role_id”) Integer[] roles) {

    • System.out.println(Arrays.asList(roles));

    • return null;

    • }

    • 复选框传递数组

    • 篮球

    • 足球

    • 看书

    • 简写方式

    • @GetMapping("/client05")

    • public ModelAndView test02(String[] hobby) {

    • if (hobby != null) {

    • System.out.println(Arrays.asList(hobby));

    • } else {

    • System.out.println(“您没有爱好!”);

    • }

    • return null;

    • }

    • 文本框传递数据

    • 简写方式

    • @GetMapping("/client06")

    • public ModelAndView test03(String[] hobby) {

    • System.out.println(Arrays.asList(hobby));

    • return null;

    • }

    • 多选列表传递数组

    • 音乐
    • 看书
    • 足球
    • 简写方式

    • @GetMapping("/client07")

    • public ModelAndView test04(String[] hobby) {

    • if (hobby != null) {

    • System.out.println(Arrays.asList(hobby));

    • } else {

    • System.out.println(“您没有爱好!!”);

    • }

    • return null;

    • }

  • 对象

    • 简单对象,只是需要你传递的名称跟类中的属性名保持一致即可

    • @GetMapping("/client08")

    • public ModelAndView test01(User user, String user_name, String sex) {

    • System.out.println(user);

    • System.out.println("-----依然可以使用简单方式----");

    • System.out.println(user_name);

    • System.out.println(sex);

    • return null;

    • }

    • 多个对象如果属性不相同,那么SpringMvc框架会帮我们自动完成转换

    • @GetMapping("/client09")

    • public ModelAndView test02(User user, Role role) {

    • System.out.println(user);

    • System.out.println("-----角色----");

    • System.out.println(role);

    • return null;

    • }

    • 关联对象,一个对象里有另外一个对象

    • public class User {

    • private Role role;

      • 后台处理

        • @GetMapping("/client10")

        • public ModelAndView test03(User user, Role role) {

        • //设置关联关系

        • user.setRole(role);

        • System.out.println(user);

        • return null;

        • }

      • 前台处理

      • 多个对象进行关联方式二:前台处理

      • 姓名:

      • 性别:

      • 角色名称:<%–name=类中.属性–%>

      • 提交数据

      • @GetMapping("/client11")

      • public ModelAndView test04(User user) {

      • System.out.println(user);

      • return null;

      • }

    • 多个对象如果出现同属性问题,需要借助第三方类来区分数据的归属情况

    • 不同对象同属性传递借助第三方类

    • 用户

    • 姓名:

    • 性别:

    • 角色信息:

    • 学生

    • 姓名:

    • 性别:

    • 提交数据

    • @GetMapping("/client12")

    • public ModelAndView test05(HsModel hsModel) {

    • System.out.println(hsModel.getStudent());

    • System.out.println(hsModel.getUser());

    • return null;

    • }

      • 第三方类含这些类

        • public class HsModel {

        • private User user;

        • private Student student;

  • Map

  • 姓名:<input type=“text” name=“query[‘user_name’]”<%–属性[‘需要设置的key值’]–%>>

  • 性别:

  • 提交数据

  • @GetMapping("/client13")

  • public ModelAndView test01(HsModel hsModel) {

  • System.out.println(hsModel.getQuery());

  • return null;

  • }

    • 需要借助第三方类的支持

    • public class HsModel {

    • private Map<String,Object> query;

    • 一般做分页查询的时候使用 query[“设置Map中的KEY”]

  • List

  • 姓名: <%–设置第1条数据的user_name–%>

  • 性别:<%–设置第1条数据的sex–%>


  • 姓名: <%–设置第2条数据的user_name–%>

  • 性别:


  • 姓名: <%–设置第6条数据的user_name,同时也设置了这个list长度是6–%>

  • 性别:

  • 提交数据

  • @Controller

  • public class ListTypeDemoController {

  • @GetMapping("/client14")

  • public ModelAndView test01(HsModel hsModel) {

  • System.out.println(hsModel.getStudentList());

  • return null;

  • }

  • }

    • 需要借助第三方类的支持

    • public class HsModel {

    • private List studentList;

    • 一般做批量添加

  • 占位符传递数据

  • 占位符传递数据

    • 普通接收数据

    • @GetMapping("/client15/{id}/{name}")

    • public ModelAndView test01(

    • @PathVariable(“id”) int user_id,/占位符的名字和形参不一样,在PathVariable中需要写占位符的名字/

    • @PathVariable String name,/一样则可以省略/

    • String sex /@RequestParam的简写方式/

    • ) {

    • System.out.println(user_id);

    • System.out.println(name);

    • System.out.println(sex);

    • return null;

    • }

    • Map接收数据

    • @GetMapping("/client16/{id}/{name}")

    • public ModelAndView test01(

    • @PathVariable Map<String,Object> map,/占位符的名字作为key值/

    • String sex /@RequestParam的简写方式/

    • ) {

    • System.out.println(map);

    • System.out.println(sex);

    • return null;

    • }

  • JSON数据

    • 服务端使用@RequestBody接收数据

    • JSON数据—Java对象互转

      • Map

      • @Test

      • public void test01() throws IOException {

      • Map<String,Object> map = new HashMap<>();

      • map.put(“user_name”,“悟空”);

      • map.put(“age”, 500);

      • map.put(“hobby”,/静态初始化数据/ new String[]{“music”,“book”});

      • System.out.println(“转换之前的Map:”+map);

      • //1.java对象转JSON格式的字符串

      • ObjectMapper objectMapper = new ObjectMapper();

      • String jsonString = objectMapper.writeValueAsString(map);

      • System.out.println(“java对象转JSON格式的字符串:”+jsonString);

      • //2.JSON字符串转换为java对象

      • Map<String, Object> hsMap = objectMapper.readValue(jsonString, Map.class);

      • System.out.println(“JSON字符串转换为java对象:”+hsMap);

      • }

      • 集合

      • @Test

      • public void test03() throws Exception {

      • List userList = new ArrayList<>();

      • User user = new User();

      • user.setUser_id(100);

      • user.setUser_name(“八戒”);

      • user.setSex(“男”);

      • Role role = new Role();

      • role.setRole_name(“超级管理员”);

      • user.setRole(role);

      • userList.add(user);

      • user = new User();

      • user.setUser_id(100);

      • user.setUser_name(“悟空”);

      • user.setSex(“男”);

      • role = new Role();

      • role.setRole_name(“管理员”);

      • user.setRole(role);

      • userList.add(user);

      • System.out.println(“转换之前的List:”+userList);

      • //1.java对象转json字符串

      • ObjectMapper objectMapper = new ObjectMapper();

      • String jsonString = objectMapper.writeValueAsString(userList);

      • System.out.println(“java对象转json字符串:”+jsonString);

      • //2.json字符串转java对象

      • System.out.println(“组成的List<map>:”+objectMapper.readValue(jsonString, List.class)); //组成的是List</map>

      • JavaType t = objectMapper.getTypeFactory().constructParametricType(List.class, User.class);

      • List tempList = objectMapper.readValue(jsonString, t);

      • System.out.println(“json字符串转java对象:”+tempList);

      • }

      • 自定义对象

      • @Test

      • public void test02() throws Exception {

      • User user = new User();

      • user.setUser_id(100);

      • user.setUser_name(“八戒”);

      • user.setSex(“男”);

      • Role role = new Role();

      • role.setRole_name(“超级管理员”);

      • //建立联系

      • user.setRole(role);

      • System.out.println(“转换之前的User:”+user);

      • //1.java对象转json字符串

      • ObjectMapper objectMapper = new ObjectMapper();

      • String jsonString = objectMapper.writeValueAsString(user);

      • System.out.println(“java对象转json字符串:”+jsonString);

      • //2.json字符串转java对象

      • User hsUser = objectMapper.readValue(jsonString, User.class);

      • System.out.println(“json字符串转java对象:”+hsUser);

      • }

    • JavaScript对象—JSON格式字符互转

  • 文件上传

    • 配置上传文件的解析器,如果发现你是二进制流的方式传递数据,那么会使用该解析器处理数据
  • 数据类型的转换

    • 日期类型的转换@@DateTimeFormat

    • /**

      • 接收日期类型的客户端传递数据,简写方式
      • 没有写注解,就写 2018/8/14 15:31:20
      • 写了注解就按照他的格式来,如果没有写时间,你输入了时间也不会认
      • 如果一个类中也有这样的属性,同时接收这个时间,注解里也要写格式
      • @return
    • */

    • @GetMapping("/client01")

    • public ModelAndView test01(

    • @DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”) Date mydate,

    • User user) {

    • System.out.println(mydate);

    • System.out.println(user);

    • return null;

    • }

    • @InitBinder

    • @InitBinder

    • public void init01(WebDataBinder binder) {

    • //监控要转换(String)的数据类型

    • binder.registerCustomEditor(String.class, /匿名对象/new PropertyEditorSupport() {

    • //重写了setAsText方法

    • @Override

    • public void setAsText(String text) throws IllegalArgumentException {

    • System.out.println(“之前接收的值----” + text);

    • //对数据重新处理赋值,赋值给形参user_name

    • this.setValue(“对数据处理之后的值----” + text + “悟空”);

    • }

    • });

    • //监控Integer类型

    • binder.registerCustomEditor(Integer.class, new PropertyEditorSupport() {

    • @Override

    • public void setAsText(String text) throws IllegalArgumentException {

    • System.out.println(text);

    • this.setValue(“999”);

    • }

    • });

    • }

客户端传递数据中文乱码

  • get请求

    • tomcat7

      • 全局设置

        • 在tomcat里的sever.xml中修改

        • 这一行加入URIEncoding=”UTF-8”

      • 单项目设置

      • user_name = new String(user_name.getBytes(“ISO8859-1”),“UTF-8”);

    • tomcat8

      • 默认为UTF-8,不需要修改
  • post请求

    • 在web.xml中配置过滤器

    • characterEncodingFilter

    • org.springframework.web.filter.CharacterEncodingFilter

    • encoding

    • UTF-8

    • forceRequestEncoding

    • true

    • forceResponseEncoding

    • true

    • characterEncodingFilter

    • /*

服务端传递数据到客户端

  • 返回类型ModelAndView传递数据

    • 指明KEY

    • @GetMapping("/server02")

    • public ModelAndView test02() {

    • ModelAndView mav = new ModelAndView();

    • // mav.addObject() 没有指明KEY

    • //一步一步的追源码,发现一个ModelMap的类实例化对象.用它的addAttribute方法添加,ModelMap又是继承了HashMap

    • mav.addObject(“title”, “通过ModelAndView传递数据”);

    • mav.addObject(“hs”, “中国和尚”);

    • mav.addObject(“class”, “计算机计科”);

    • mav.addObject(“number”, 11);

    • mav.setViewName(“jsp/result02”); //请求转发,通过视图解析器

    • return mav;

    • }

    • 没有指明KEY,默认传递数据的KEY的名称为类名的首字母小写

    • @GetMapping("/server03")

    • public ModelAndView test03() {

    • ModelAndView mav = new ModelAndView();

    • mav.addObject(“integer”, 100);

    • mav.addObject(200);

    • mav.addObject(“string”, “字符串”);

    • mav.addObject(“悟空”);

    • // 规则:客户端获取没有加key的数据,默认key正常是数据对应的类型的首字母小写 Integer—integer String—string

    • // 两个key一样的,只认最后一个

    • // double是关键字,不能 <math> <semantics> <mrow> <mrow> <mi> d </mi> <mi> o </mi> <mi> u </mi> <mi> b </mi> <mi> l </mi> <mi> e </mi> </mrow> <mo separator="true"> , </mo> <mi mathvariant="normal"> 只 </mi> <mi mathvariant="normal"> 能 </mi> </mrow> <annotation encoding="application&#47;x&#45;tex"> {double},只能 </annotation> </semantics> </math>double,{requestScope[“double”] }

    • double a = 123.123;

    • mav.addObject(a);

    • User user = new User();

    • user.setMydate(new Date());

    • mav.addObject(user);

    • mav.setViewName(“jsp/result03”); //请求转发,通过视图解析器

    • return mav;

    • }

  • 返回类型String传递数据

    • Map

    • @GetMapping("/server04")

    • public String test01(Map<String,Object> map) {

    • map.put(“title”, “Map在形参中定义,可以传递数据”);

    • map.put(“hs”, “123”);

    • map.put(“class”, “12222”);

    • map.put(“number”, 1111);

    • return “jsp/result04”; //通过请求转发视图解析器

    • }

    • ModelMap

    • @GetMapping("/server05")

    • public String test02(ModelMap modelMap) {

    • modelMap.addAttribute(“title”, “ModelMap进行传递数据”);

    • modelMap.addAttribute(“hs”, “123”);

    • modelMap.addAttribute(“class”, “12222”);

    • modelMap.addAttribute(“number”, 1111);

    • return “jsp/result04”; //通过请求转发视图解析器

    • }

    • Model

    • @GetMapping("/server06")

    • public String test03(Model model) {

    • model.addAttribute(“title”, “Model接口进行传递数据”);

    • model.addAttribute(“hs”, “123”);

    • model.addAttribute(“class”, “12222”);

    • model.addAttribute(“number”, 1111);

    • return “jsp/result04”; //通过请求转发视图解析器

    • }

  • @ResponseBody返回JSON数据格式

    • 返回JSON格式数据

      • Map

      • @GetMapping("/json03")

      • @ResponseBody //把java数据转换为JSON的字符串 存在BUG(IE浏览器不好使,解决办法在springmvc.xml配置)

      • public Map<String, Object> test03() {

      • Map<String, Object> map = new HashMap<>();

      • map.put(“name”, “马老板”);

      • map.put(“sex”, “男”);

      • return map;

      • }

      • List

      • @GetMapping("/json04")

      • public @ResponseBody List<Map<String, Object>> test04() {

      • List<Map<String,Object>> tempList = new ArrayList<Map<String,Object>>();

      • Map<String,Object> map = new HashMap<String, Object>();

      • map.put(“name”, “马老板”);

      • map.put(“sex”, “男”);

      • tempList.add(map);

      • map = new HashMap<String, Object>();

      • map.put(“name”, “悟空”);

      • map.put(“sex”, “男”);

      • tempList.add(map);

      • return tempList;

      • }

    • IE浏览器的下载问题

    • text/html;charset=UTF-8

    • text/plan;charset=UTF-8

    • application/json;charset=UTF-8

    • 返回日期格式的问题

      • @JsonFormat

      • 需要在user的date属性下加注解

      • // 相放哪里就放哪里,pattern:格式,timezone:时区,这是设置东八区

      • // @JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”)

      • Date mydate;

      • // @JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”,timezone = “GMT+8”)

      • // @JsonFormat(pattern = “yyyy-MM-dd”,timezone = “GMT+8”)

      • public Date getMydate() {

      • return mydate;

      • }

      • 使用SpringMvc配置

  • 前台如何接收

  • ${title}

  • ${requestScope.hs} --指明范围了的

  • ${requestScope["class"]}

  • ${number} ---默认情况下是从pageContext->request->session->application下开始寻找

  • ${requestScope.integer }

  • ${requestScope.string }

  • ${requestScope["double"] }-----因为double是关键字,所以不能.double

  • ${requestScope.user.mydate }

  • ${requestScope["user"]["mydate"] }

文件的上传和下载

  • 上传

  • <%@ page contentType=“text/html;charset=UTF-8” language=“java” %>

  • 单文件上传

  • 标题:

  • 文件:

  • 文件上传

    • 要求

      • form表单传递数据
      • 请求必须为POST请求
      • 使用二进制流的方式传递数据 enctype=“multipart/form-data”
      • 文件域
    • 工具

      • Servlet3.0

      • Commons-FileUpload

      • @PostMapping("/upload01")

      • public ModelAndView test01(String title, MultipartFile myfile, HttpServletRequest request) throws IOException {

      • ModelAndView mav = new ModelAndView();

      • // System.out.println(title);

      • //1.获取上传文件的名称

      • String fileName = myfile.getOriginalFilename();

      • mav.addObject(“fileName”, fileName);

      • //2.判断文件名称是否有值,isEmpty是这个字符串的length=0为true

      • if (!fileName.isEmpty()) {

      • //3.获取服务器的绝对路径

      • String path = request.getServletContext().getRealPath("/upload");

      • //4.建立联系

      • File folder = new File(path);

      • //5.判断该文件是否存在,不存在则创建文件夹

      • if (!folder.exists()) {

      • folder.mkdirs(); //创建文件夹

      • }

      • //6,获取上传文件的后缀名称

      • String ext = FilenameUtils.getExtension(fileName);

      • //7.创建新的文件名称

      • //String newFileName = UUID.randomUUID().toString() + “.” + ext;

      • //或者用时间戳创建名称

      • String newFileName = new Date().getTime() + “_” + new Random().nextInt(100000) + “.” + ext;

      • mav.addObject(“newFileName”, newFileName);

      • // System.out.println(newFileName);

      • //8.文件上传,File.separator为斜线

      • myfile.transferTo(new File(path + File.separator + newFileName));

      • }

      • mav.addObject(“hs”, “和尚”);

      • mav.setViewName(“jsp/result”);

      • /*System.out.println(“测试是否可以获取正常的数据:”+title);

      • System.out.println("=====");

      • System.out.println(“文件的MIME类型 :”+myfile.getContentType());

      • System.out.println(“文件NAME属性对应的值 :”+myfile.getName());

      • System.out.println(“上传文件的名称 :”+myfile.getOriginalFilename());

      • System.out.println(“上传文件的大小 :”+myfile.getSize());*/

      • return mav;

      • }

        • commons-fileupload-1.3.1.jar
  • 下载

  • @GetMapping("/download")

  • public ResponseEntity<byte[]> test02(String newFileName, String fileName, HttpServletRequest request) throws IOException {

  • //获取服务端的绝对路径

  • String path = request.getServletContext().getRealPath("/upload/");

  • HttpHeaders headers = new HttpHeaders();

  • //设置相应的内容为流

  • headers.setContentType(MediaType.TEXT_EVENT_STREAM);

  • //设置下载的名称–和中文乱码的问题

  • headers.setContentDispositionFormData(“attachment”,

  • new String(fileName.getBytes(“UTF-8”), “ISO8859-1”)

  • );

  • //找到文件

  • File file = new File(path + File.separator + newFileName);

  • return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),/将文件转换为byte数组/

  • headers,

  • HttpStatus.CREATED);

  • }

  • 需要的jar包

    • commons-io-2.4.jar

异常处理

  • 注解方式

    • 局部处理@ExceptionHandler
    • 全局处理@ControllerAdvice+@ExceptionHandler
  • XML方式

  • jsp/error

  • jsp/error

  • jsp/error

  • jsp/error

***

  • ***有且只能拦截Controller

Spring框架

概述

  • Spring是IoC(DI)和AOP的容器框架

IoC #控制反转:白话:让别人为我们服务,帮我new对象

  • 管理Bean的声明周期
    • 范围Scope
      • 默认情况下是单例模式single
      • 多例模式prototype
      • request
      • session
  • 实现方式有两种
    • 注解方式
      • @Component
      • @Controller
      • @Service
      • @Repository

DI(注入方式) #白话:注入就是实例化,赋值

  • Setter方式–推荐

    • XML方式
      • com.hs.model.User类中的属性必须要提供set方法
      • 形式如下
        • <property name=“属性名” value=“值”
        • ref引用对象
        • 标准写法
        • 缩写
        • p方式(p方式的引用)
      • 各个类型如何注入
        • 普通属性的值 value
        • 集合 list/set/array
        • map/props
        • 自定义类型
          • 内部使用
          • 外部实例化,内部使用ref进行引用
          • 外部实例化,使用p:xxx-ref引用
        • 接口注入实现类(接口回调)
          • 外部定义接口实现类实例化,内部使用进行引用
          • 外部定义接口实现类实例化,使用p:xxx-ref引用
        • util:list | set | map | properties----不常用
          • 内部定义,内部引用
          • 外部定义,p引用
    • 注解方式
      • @Autowired–推荐
        • @Qualifier(“bookDaoImpl”),指明具体的id
      • @Resource
      • 概要: 区别
        • @Autowired先按类型再按照名称查找
        • @Resource先按名称再按照类型查找
  • 构造函数注入方式

    • XML方式
      • 标准写法
      • 缩写
      • 各个类型如何注入
        • 普通属性的值 value
        • 集合 list/set/array
        • map/props
        • 自定义类型
          • 内部使用
          • 外部实例化,内部使用ref进行引用
        • 接口注入实现类(接口回调)
          • 外部定义接口实现类实例化,内部使用进行引用
    • 注解方式
      • @Autowired–推荐
      • @Resource
  • @Value注解注入值

  • @Value(“我是其他属性”)

  • private String anotherValue;

  • 或者写在set方法上

    • 注入普通字符串
    • 注入操作系统属性
    • 注入表达式运算结果
    • 注入其他bean的属性。
    • 注入文件内容。
    • 注入网址信息。
    • 注入属性文件。

AOP #白话:在不改变原来代码的基础上,增加新的功能,AOP的底层的实现就是使用的是Java的动态代理

  • 概念

    • Aspect Oriented Programming with Spring 面向切面(方面)编程
      • 面向切面编程是面向对象编程的一个补充而已
      • 白话:我的理解—->在不改变原来的代码的基础上增强(增加)新的功能
  • 静态代理

  • 动态代理

  • CGLIB动态代理

  • proxy-target-class=“true”

  • 切面

  • 连接点

    • 表达式 execution(* com.hs…service.Service.(**)
  • 切点

    • @PointCut
    • <aop:point-cut
  • 通知

    • 前置通知
      • 不管程序是否正确都会执行
    • 后置通知
      • 不管程序是否正确都会执行
    • 返回通知
      • 只有程序是正确的时候才会执行,并且可以获取运行后的数据
    • 异常通知
      • 只有程序是错误的时候才会执行
    • 环绕通知-------不推荐!!!
  • 代理对象

JdbcTemplate工具类

  • 配置数据源

  • 配置工具类

  • SQL语句

    • 查询

      • 返回Map数据

      • @Test

      • public void test01() {

      • /*String sql = “select * from oa_user where user_id = 3”;

      • Map<String, Object> map = this.jdbcTemplate.queryForMap(sql);*/

      • String sql = “select * from oa_user where user_id = ?”;

      • Map<String, Object> map = jdbcTemplate.queryForMap(sql, 2);

      • System.out.println(map);

      • }

      • 返回List<map>数据</map>

      • @Test

      • public void test02() {

      • String sql = “select * from oa_user”;

      • System.out.println(jdbcTemplate.queryForList(sql));

      • }

      • 返回一个值

      • @Test

      • public void test03() {

      • String sql = “select count(*) from oa_user”;

      • System.out.println(jdbcTemplate.queryForObject(sql, Integer.class));

      • }

      • 返回一个对象

      • @Test

      • public void test04() {

      • String sql = “select * from oa_user where user_id = ?”;

      • User user = jdbcTemplate.queryForObject(sql, /匿名内部类/new RowMapper() {

      • @Override

      • public User mapRow(ResultSet rs, int rowNum) throws SQLException {

      • User user = new User();

      • user.setUser_id(rs.getInt(“user_id”));

      • user.setUser_name(rs.getString(“User_name”));

      • user.setSex(rs.getString(“sex”));

      • user.setMoney(rs.getBigDecimal(“money”));

      • user.setBirthday((Date) rs.getObject(“birthday”));

      • return user;

      • }

      • }, 2);

      • System.out.println(user);

      • }

      • 返回一个List<对象>

      • @Test

      • public void test06() {

      • String sql = “select * from oa_user where user_name like concat(’%’,?,’%’)”;

      • List userList = jdbcTemplate.query(sql,/处理一条一条的数据,,,可以不用写/new BeanPropertyRowMapper(User.class), “沙僧”);

      • System.out.println(userList);

      • }

    • 增删改

    • @Test

    • public void test07() {

    • String sql1 = “insert into oa_user(user_name,sex,money,birthday) values(?,?,?,?)”;

    • String sql2 = “update oa_user set user_name=?,sex=? where user_id = ?”;

    • String sql3 = “delete from oa_user where user_id = ?”;

    • int num1 = jdbcTemplate.update(sql1, “唐僧”, “男”, 220.00, “2018-8-9”);

    • int num2 = jdbcTemplate.update(sql2, “和尚”, “男”, 16);

    • int num3 = jdbcTemplate.update(sql3, 17);

    • System.out.println(num1+"–"+num2+"—"+num3);

    • }

事务

  • 事务

    • 概念
      • 一个工作单元由多个动作组成,只有动作全部正确的时候才能执行成功,如果有一个动作错了,其他的动作都是无效的(回滚)
    • 关键属性(ACID)
      • 原子性(atomicity):事务是一一个原子操作,由一系列动作组成,事务的原子性确保动作要么全部完成要么完全不起作用
      • 一致性(consistency):一旦所有事务动作完成,事务就被提交,数据和资源就处于一种满足业务规则的一-致性状态中.
      • 隔离性(isolation):可能有许多事务会同时处理相同的数据,因此每个事物都应该与其他事务隔离开来,防止数据损坏
      • 持久性(durability): 一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,通常情况下,事务的结果被写到持久化存储器中
  • 事务管理

    • 事务管理就是管理事务,用来确保数据的完整性和一致性.
  • 事务管理器

    • 就是对事务管理的实现,数据的完整性和一致性(数据库—>数据源)
  • 传播性

    • 当你事务方法被另一个事务方法调用的时候,需要检查其事务的传播性
  • 调用过程

    • XML版—推荐 #XML版本完成事务,需要跟AOP配合使用

      • 配置事务管理器

      • 告知哪些方法是需要被事务管理器进行管理的

XMind: ZEN - Trial Version