ssm-note

笔记3

# ssm 自己的理解
> spring springmvc mybatis

# maven
作用: 项目管理工具(管理jar包) 
仓库: 中央/镜像/本地  

> 创建springboot工程   使用的2.3.12版本

> SpringMVC 前后端整合起来

# SpringBoot
> 基于maven机制  是mavne的扩展
> springboot项目存在父工程  springboot   spirng+spirngmvc都在工程中

创建model  添加web依赖spring-boot-starter-web
pom.xml 依赖文件
Application.java  启动类  @SpringBootApplication
> 添加了web依赖测试  
    写类 方法   
        类上添加@RestController    @RequestMapping("/boot/")   
        方法添加@GetMapping    
          SpringMVC中 ------方法添加返回值-会打印在页面中------
> 使用SpringMVC 控制层方法的返回值给页面传值

# SpringMVC
> web依赖 webmvc依赖
[作用:-]   
> 接收浏览器发来的请求      服务器获取请求
> 给浏览器响应数据     服务器返回给客户端数据

[Springmvc]
松耦合 : 改一个地方的代码另一个地方不会有影响
当前端请求 先工作的是SpringMVC  梳理请求

>>>>>>>>>>>>>>>>    __SpringMVC内部工作流程   有哪些组件__     >>>>>>>>>>>>>>>>>>>>>>>>>>
>1. servlet机制
        Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。
        概念: java实现前后端数据交互的一种机制
        核心对象: Request对象(存储提交的数据)   浏览器 -> java后端
                 Response对象(服务器端返回数据信息)  java后端 -> 浏览器

>>>>> 后端路由 / 后端返回页面  页面在class中写
    @Controller
    配置: mvc-

>2. springmvc 执行流程/调用流程图
> 组件
        1. 前端控制器 DispatcherServlet 实现请求的流转
        2. 处理器映射器 实现了请求路径与方法之间的映射.
        3. 处理器适配器 处理器的管理器 内部有N个处理器. 针对不同的用户请求 调用不同的处理器完成任务
        4. 视图解析器 直线页面路径的拼接
> 父子容器
        父子容器概念:
        1.Spring容器(内存中的一大块空间)由于IOC/DI的机制,可以作为第三方的管理者 所以作为父级.
        2.SpringMVC容器,其中只负责Controller层的相关的对象的管理.

        说明: 当SpringMVC容器启动时,提前将SpringMVC中的所有请求路径方法方法完成映射.
> 流程


        1. 用户发起请求时,第一步经过前端控制器,

        2. 但是前端控制器 只负责请求的转发和响应.不做任何业务处理.将请求转发给处理器映射器.

        3. 处理器映射器接收到前端控制器的请求之后,查询自己维护的服务列表信息.
        如果服务列表中没有这个URL的key. 该程序不能处理用户的请求,则返回特定数据,前端控制器接收之后响应用户404.
        如果服务列表中有该URL key 则说明请求可以正常执行. 将该方法的对象返回给前端控制器.

        4. 前端控制器将返回的方法进行接收,但是由于前端控制器只负责转发和响应,不能直接执行该方法.所以交给处理器适配器执行.

        5. 处理器适配器根据方法的类型(xml配置文件/注解/其他方法),处理器适配器在自己的处理器库中挑选一个最为合适的处理器去执行该方法. 当处理器执行该方法时标识业务开始. 将最终的处理的结果通过ModelAndView对象进行包裹,返回给前端控制器.
        ModelAndView: Model: 代表服务器返回的业务数据 View: 服务器端返回的页面的名称

        6. 视图解析器 将View中的数据进行解析 拼接一个完整的页面路径 前缀/hello后缀

        7. 视图渲染: 将数据与页面进行绑定. 这样用户就可以在页面中看到具体的数据.

        8. 由于现在流行前后端分离. 所以SpringMVC省略了视图解析和视图渲染.只有前5. 核心注解: @ResponseBody 省略6-7> @RequestMapping 
    获取/对url进行处理  
> @RestController
    接收请求
    如果执行的方法有返回值   springmvc会自动把返回结果java对象解析为json字符串
> 解析参数的值
http://localhost:8614/car/get2?id=10&name=BMW&price=9.9
springmvc的注解 获取请求  
    注解所在方法  中添加参数 即可在方法中使用请求中的参数
--form表单提交到url后端通过springmvc注解获取 参数
--包装类型 和  基本类型
    -基本类型 访问url中必须有参数
    -包装类型 访问url中可以没有参数

    @GetMapping("get2")
    public Car get2(Car car){
        return car;
    }
  前端提交表单, 给指定url,后端就能获取url中的参数

> url参数
 get 提交方式
    http://localhost:8614/car/get2?id=10&name=BMW&price=9.9
    获取参数 
        直接在方法参数中定义  public Car get2(Car car)
 RestFul 提交方式  
    url方式 : http://localhost:8614/car/get2/10/BMW/9.9
    获取参数
        使用注解  @PathVariable
            @GetMapping("get31/{id}/{name}/{price}")
            public String get31(@PathVariable Integer id, @PathVariable String name,@PathVariable Double price){
                return "[{"+"\""+"id"+"\""+":"+"\""+id+"\""+", "+"\""+"name"+"\""+":"+name+","+"\""+"price"+"\""+":"+"\""+price+"\""+"}]";
            }

# tomcat


[pojo日期格式]
> @DateTimeFormat(pattern = "yyyy-MM-dd")
    1.前端页面 form提交的数据为String类型的    
    2.日期需要date类型   
    3.使用@DateTimeFormat 描述date类型的属性

    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
    // 出参格式化
    // 从服务端传给客户端展示,按指定格式展示, 时区
    @DateTimeFormat(pattern = "yyyy-mm-dd")
    // 入参格式化
    // 从request中获取到的日期格式是String类型, 此注解会把String类型转换为java.util.Date类型

 @JsonFormat   转 json 时按指定格式转换   --日期格式向前端展示时间时按指定格式



# ---
> 使用ajax发起请求
    form表单  点击提交按钮 
        1. 改成 普通按钮   
        2. 添加点击事件submit   
        3. form添加id  
        4. 添加jquery包  --ajax是jquery的功能 <script src="https://cdn.staticfile.org/jquery/2.0.0/jquery.min.js"></script>
        5. 写点击事件的功能
        form method="post" id="form"
        input type="button" onclick="submit()" value="保存"
        function sub(){
            $.ajax({
                url:"http://localhost:8614/student/add",
                data:$("#form").serialize(),
                success:function (data){
                    console.log(data);
                }
            });
        }
  > 跨域问题   
        当前程序 访问 其他程序   具有不同的ip 或 不同端口
        权限
        StudentController.java  
            --类加注解 @CrossOrigin(springmvc提供)   放行所有请求 

# 点击注册之后 提交表单  跳转到登录页面
# 点击登录之后 提交表单  跳转到用户界面
>   ---使用ajax 属性 success:function(data){} 跳转页面 


> 使用json接收数据

# ---

# spring
> 1. 概念
    作用: 管理Bean --把所有的类看做一个bean
        1. 创建对象
        2. 设置对象关联关系
> 2 . 核心概念     
  >> BeanFactory (就是类)
  >> ApplicationContext 外部应用调用  bean容器
  >> Ioc 控制反转   框架实现了反转  无需new对象(不用创建对象,单例模式),使用容器获取User user= context.getBean(user)
  >> DI  依赖注入    对象直接依赖
  >> AOP  面向切面编程
  
  >>> bean context ioc core
        -- Bean就是object , context 数据的环境 并发现bean之间的关系(注解) , 关系集合叫做ico容器 , core 发现 建立 维护 bean之间关系所需的工具

> 3. IoC  
    Inversion of control 对象的创建和生命周期交给spring管理
  >> 如何完成
        1. .xml 配置文件
            applicationContext.xml  ( spring config文件 )
            bean标签 指定类的信息
                属性:class 指定类的全路径(包名.类名)     id bean的唯一标识
            由一个初始化的xml配置文件来创建,也就是由spring容器来创建。遍历xml配置文件,读取到<bean>,获取到class属性的类的全路径,利用反射创建这个类。
        2. 注解
            @Component   配置<context:component-scan base-package="com.cy"/>

> 4. DI
    在创建对象的过程中spring可以依据对象的关系, 自动把其他对象注入
    @Autowired

> 5. 注解

   >>> 接口是一种规范

> 6. 分层结构
    pojo  对象类    --业务层 controller层都会用到
    业务层
    web层
    -- spring进行扫描 把具有注解的类进行ioc管理  
    -- @SpringBootApplication启动类所在包 以及子包

> 7. AOP 面向切面编程
   >> . 通知 就是在某个位置插入的方法
   >> . 定义 切面-Aspect
        .. 通过 通知-Advice 做具体的事情 方法
            ... .通知类型 before after around afterReturning afterThrowing
        .. 通过 切点-PointCut 配置切入点表达式  指定在哪个类
     . 注解
        .. @Aspect  描述类 定义切面
           @Component
           public class TimeAspect{}

        .. @Pointcut("execution( * cn.tedu.mvc..*.*(..))")  
                //  在这里只指定了某个包 会不会执行所有类的所有方法  不会 原因: 执行的是触发的方法  
           public void pointcut(){}

        .. @Around("pointcut()")    具体执行功能
           public Object doAround(ProceedingJoinPoint joinPoint){}
   >> . aop 结合 注解

# mybatis
> 1. 概念 :  mybatis 支持普通sql查询 存储过程 高级映射 持久层框架      --简化/封装jdbc   --更好的完成ORM(对象关系映射 -表和类)
        1.jdbc  2.ORM
> 2. 使用过程
        依赖 : mybatis-spring-boot-starter 
        配置数据库 : 两种方式 
                        1.xml   2.spring配置  
                  : 配置内容 
                        1.url 2.username 3.password 4.mybatis.mapper-location=classpath:/mapper/*.xml         */                    
        映射文件 : 
                头文件 
                mapper属性 : namespace-映射文件的唯一标识,映射的文件操作文件 , 
                select属性 : id-方法名,每条SQL的唯一标识  parameterType/resultType-完成ORM,把表里每个字段的值 自动映射给 类里的属性
> 3. resultType / resultMap
        resultType 可以在 类的属性名和表里的字段名一致时 自动完成ORM
        当不一样时 使用resultMap
              <resultMap id="user" type="com.cy.sys.pojo.Userinfo">
                主键
                <id property="id" column="id">
                普通
                <result property="username" column="user_name">
            </resultMap>
        <select id="select" resultMap="personORM">select * from car</select>
> 4. sql标签 动态sql
        sql/include   ---sql提取共性标签 片段 include哪里用向哪里插入 引用片段
            <sql id="columns">id,name,color,price</sql>
            select * from car -->  select <include refid="columns"/> from car
        where ---过滤  --自动删除条件前面的and或者or
            <where></where>
        if    ---判断
            <if test="name!=null and name!=''"> name = #{name} </if>
        set   ---update中设置新的值  --如果最后一个set条件多余逗号,会自动删除
            <set></set>
        foreach ---循环
                dao接口方法 : List<Car> selectByIds(@Param("ids") Integer... id);
            select * from car where id in (1,2,3,4,?,?,..);
            id in 
                <foreach collection="ids" open="(" close=")" separator="," item="item">#{item}</foreach>
> 5. 知识点
    .0. -------
        mybatis的一级缓存 : mybatis 重复执行相同的sql语句 , 只会与数据库查询一次 , 放在缓存中 .  前提: 同一个会话session 
        @BeforeEach 在测试类中 在测试方法之前执行

    .1. # 和 $ 
        #: 使用#{parameterName}引用参数的时候,Mybatis会把这个参数认为是一个字符串,
            传入参数是"Smith",那么在SQL(Select * from emp where name = #{employeeName})使用的时候就会转换为Select * from emp where name = 'Smith'。
        $: 不做字符串拼接,
            SQL(Select * from emp where name = ${employeeName})使用的时候就会转换为Select * from emp where name = Smith。此时,如果字段是varchar类型直接抛出SQL异常。

    .2. 特殊字符
        <![CDATA[ ?? ]]>  在xml文件中得到表达式,不被xml文件解析
            在 XML 元素中,"<""&" 是非法的。
            "<" 会产生错误,因为解析器会把该字符解释为新元素的开始。
            "&" 也会产生错误,因为解析器会把该字符解释为字符实体的开始。
            <![CDATA[<=]]> 在xml文件中表示 小于等于
    
    .3. 别名alias
        写在MybatisConfig.xml中    在映射文件使用指定对象时可以直接写-别名-使用
        <typeAliases>
            <typeAlias type="cn.mybatis.pojo.User" alias="User"/>
        </typeAliases>

    JDBC和MyBatis的区别?
    XML和接口方式的区别?
    接口方式怎么找到xml执行的?

> 6. 实现
  ----------------
    使用mybatis配置文件 实现
        1. 配置文件 configuration  --配置数据库  --配置映射文件路径
        2. 映射文件 1. mapper  --namespace    2. sql语句  例如select标签 --id,paramterType,resultType
        3. pojo对象 
        4. 测试
            读取配置文件 , 创建SqlSessionFactory , 初始化SqlSession , 从SqlSession中获取指定sql语句执行sql
                InputStream resourceAsStream = Resources.getResourceAsStream("MybatisConfig.xml");
                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
                SqlSession sqlSession = sqlSessionFactory.openSession();
                List<User> list = sqlSession.selectList("user.selectUsers");
  ----------------

  ----------------
    使用dao接口 实现
        1. 配置文件 configuration  --配置数据库  --配置映射文件路径
        2. 映射文件 1. mapper  --namespace 接口路径+2. sql语句  例如select标签 --id,paramterType,resultType
        3. pojo对象
        4. 接口文件 
        5. 测试
            读取配置文件 , 创建SqlSessionFactory , 初始化SqlSession , 从sqlSession中获取接口
                InputStream resourceAsStream = Resources.getResourceAsStream("MybatisConfig.xml");
                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
                SqlSession sqlSession = sqlSessionFactory.openSession();
                DeptDao deptDao = sqlSession.getMapper(DeptDao.class);
  ----------------

  ----------------
    文件 :
        mybatis配置文件         MybatisConfig.xml
        pojo对象                User.java 类
        dao接口                 UserDao.java 接口
        映射文件                mapper/UserMapper.xml
        测试文件                UserDaoTests.java Test
  ----------------

ssm-note_第1张图片
笔记2

# java  
    oracle公司的
# Spring       
    框架 javaBean提供具有控制反转特性的容器  可以应用在服务器端 web应用
# SpringMVC    
    mvc框架   Spring中为构建web应用提供功能全面的框架   通过url请求并返回的核心组件
# SpringBoot   
    基于Spring4.0设计
    简化Spring的配置,简化了Spring应用的整个搭建和开发过程     
    解决依赖包版本冲突,引用的不稳定性
# mybatis  
    apache公司的    
    持久层框架   支持定制化SQL,存储过程,高级映射
    .. 几乎避免了所用jdbc代码 手动设置参数  获取结果集
    .. 使用简单xml 注解 来配置和映射原生信息   将java的pojo映射成数据库中的记录    pojo--plain oridinary java object 普通java对象

# servlet
    小服务程序 服务连接器
    主要功能: 交互式的浏览和生成数据 生成动态web内容
    大多数情况 servlet用于扩展基于http协议的web服务器
# tomcat
    apache公司
    tomcat支持servlet和jsp规范 
    web应用服务器

# ??? servlet 和 tomcat 在哪里能体现到   使用 ???




spring 中    容器Bean   机制IoC AOP
    IoC 实现方式 DI 依赖查找
    spring容器通过 DI实现IoC
     DI 注入方式  Setter注入 构造器注入


# Spring 
    .. 应用开发框架
    .. 使用本身的功能,也可以结合第三方框架
    .. 本质 : 管理软件中的对象,创建对象和维护对象之间的关系
  **- IoC AOP -**
    .. 将组件的耦合度降到最低,解耦
 > 主要功能
    DAO   AOP  Web   ORM   JEE   Core

## Bean
   在spring中, 任何java类和javaBean都被当成Bean处理, 这些Bean通过容器管理和应用
 > 容器 BeanFactory ApplicationContext

## IoC
    .. Inversion of Control  控制反转
    .. 指的是对象的获取发生反转,new方式创建 变为由第三方框架创建,注入
        . 第三方框架一般是通过配置方式指定注入哪一个具体实现, 从而降低了对象之间的耦合度
  > 实现方法  
   **- 依赖注入DI  依赖查找 -**
    .. spring容器采用DI方式实现IoC      IoC是Spring框架基础和核心

### DI
 > 基本原理 : 
    将一起工作具有关系的对象, 通过构造方法参数或方法参数传入建立关联, 
      因此容器的工作就是创建bean时注入哪些依赖关系
 > 注入方式 :
   **- Setter注入  构造器注入 -**

#### Setter注入
    无参构造器 或 无参static工厂方法实例化bean后, 调用该bean的setter方法 实现setter方式注入
    xml中配置 注入参数

#### 构造器注入
    调用带参数的构造器来实现的

## 自动装配
 Autowire
   Spring IoC容器可以自动装配相互协作bean之间的关联关系, autowrie对单个bean进行设置
        减少xml的注入配置
        自动装配规则 : 
            no  byName   byType    constructor    autodetect

## 组件扫描
    指定一个包路径, Spring会自动扫描该包机器子包所有组件类, 当发现组件类定义前有特定的注解标记时, 就将该组件纳入到Spring容器
    指定扫描类路径xml文件中 : <mapper namespace="com.cy.pj.notice.dao.SysNoticeDao"></mapper>
    注解标记 : @Component 通用注解   @Name 通用注解   @Repository 持久层组件注解   @Service 业务层组件注解    @Controller 控制层组件注解 
    @Scope("protetype") Spring管理组件的范围  
    指定依赖注入 : @Resource   @Autowired/@Qualifier  @Inject/Named 
        @Resource 字段定义或setter方法   首先按名称匹配注入,然后类型匹配注入
        @Autowired字段定义或setter方法   按类型匹配注入    
                ? 遇到多个匹配Bean时注入会发生错误,  @Autowired @Qualifier("myUserDao") private UserDao userDao;   @Autowired@Qualifier 配额使用
                        @Autowired public void setUserDao(@Qualifier("myUserDao") userDao dao){this.userDao=dao;}
        @Inject/@Named@Autowired/@Qualifier  用法相同
    @Value 注解可以注入Spring表达式值,使用方法
            application.properties bootstrap.yml 从配置文件中获取 配置文件中的信息
            @Value("${server.port}")

# Spring Web MVC
## MVC 
    .. M Model 模型  业务逻辑   包含: 业务数据Dao 业务处理逻辑Service
    .. V View 视图   显示界面,用户交互   属于视图的组件不包含业务逻辑和控制逻辑的 JSP
    .. C Controller 控制器  是模型层和视图层之间的桥梁 用于控制流程

## Spring web mvc
    是Spring框架非常重要的功能模块,
    实现了mvc结构,便于简单,快速开发mvc结构的web程序
    Spring web mvc提供的api封装了web开发中常用的功能,简化了web过程

## 核心组件
  > DispatcherServlet   控制器,请求入口
  > HandlerMapping   控制器,请求派发
  > Controller   控制器,请求处理流程
  > ModelAndView   模型,封装业务处理结果和视图
  > ViewResolver   视图,视图显示处理器      

过程:
	request (/car/get) 必须进入核心分发器 DispatcherServlet  (做校验 安全)  
	URL  进入  处理器映射HandlerMapping  (找到ControllerClassName)
	通过controllerClassName 进入处理器适配器HandlerAdapator(找到对应的controller内容)
	通过Controller控制器 传递给  Service业务层  进行业务处理
	通过Repository持久层在Database数据库中找到响应的数据 
	返回给Repository 给Service  处理业务
	返回给  Controller 形成 ModelAndView  传递给 HandlerAdapator  形成  ModelAndView
	传递给 ViewResolver 形成 Model  传递给  VIew(h5+css+Vue)   返回json字符串

	好处:
		MVC封装 代码量
		单一职责 , 分层  职责明晰(每个部分有每个部分的作用   清楚各部分内容)         (controller  业务逻辑    数据交互)               为大项目做,方便团队开发(前端,后端,数据库DBA)
	
	组件:
		 1)DispatcherServlet,本质封装Servlet,核心分发器,请求转发 
		 2)HandlerMapping, 处理器映射,解析url,/car/get,包括参数封装 name,age,hobby,Student 
		 3)HandlerAdapator,处理器适配器,负责找到对应Controller,CarController,底层解析 @RequestMapping("/car/get"),找到这个所对应方法,反射 
		 4)执行完成Controller,把数据封装Model对象中 
		 5)ViewResolver,视图解析器,把model传递页面jsp,把model转成json字符串,返回页面

### 使用注解配置
    @RequestMapping("/notice/")   请求url
    @Controller 声明controller组件
    @Requestparam("pwd")  接收请求参数
    @ModelAttribute("user") 向页面传值

### 重定向
    redirect

### 拦截器
  必须实现HandlerInterceptor接口

### 异常
  Spring MVC提供的简单异常处理器  SimpleMappingExceptionResolver
  实现HandlerExceptionResolver接口 自定义异常
  使用@ExceptionHandler注解实现异常处理

### Spring mvc 文件上传简介

笔记1

# 2021-02-20  day01--------------------------------------

### 知识回顾

#### vue+element-ui前端界面
	element-ui 很多大公司采用,写法,语法 Vue 数据驱动,组件化Item.vue 
	1)数据驱动,体系开发者关心不在是代码api,只关心数据(业务) 
	2)组件化,复用,一旦创建好一个组件,这个组件就可以给其他人共享

#### 自己定义一个组件 Item.vue
	1.vue文件,它有3部分组成 
			a. template 模板,html+vue片段(SPA单页面开发,它只是这个页面一部分) 
			b. script 脚本,形式 export default{},本质js脚本,数据区,方法区 
			c. style 样式 只对自己组件有效!避免不同的组件冲突。 
	2)注册,Vue项目(工程),所有组件都是App.vue根组件的子组件。 
			import导入,注意路径,相对路径 ./当前目录、../上级目录 
	3)使用 <Item></Item>标签

现今开发拿来主义,站在巨人肩膀上开发,好处开发效率高
组件:element-ui 完美,它形成一套完整的ui界面,比html原生美观很多

#### 列表
	<table><tr><td>
		要写两行,表格头,表格行内容(单元格)    内容是死的
	<el-table><el-table-column>
		只写一行  label表格头 prop单元格
		表格内容是活的, 数据源(js对象,json,数据库结果集)   
					js对象 :data="list"  data中的list    : 是指list为变量不是字符串  
							解析list对象中的内容,vue+element-ui底层实现    对应table中内容
					json   JSON.parse(jsonstr)  js对象
						把data中的list内容换成json请求   最终都是就是对象 list
			ajax请求后台java(springmvc)把后台从数据库返回结果集封装到java对象中 
					把java对象转换json字符串(jackson工具包api),
					返回给ajax ajax底层把json字符串转换js对象 
					scucess方法返回js对象
				拿到js对象 ,对象数组 foreach( o in array) v-for( o,i in list)
>> 添加
	toadd事件,  清空form this.m数据    打开对话框   设置新增flag
>> 修改
	获取同一行  底层可以获取相邻元素,父元素tr
	所在td 获取到tr  从而获取本tr中的所有td    拼成row对象{}
	同一对象的引用 使用JSON.parse(JSON.stringify(row))获得不同对象,相同内容
>> 保存 确认按钮
	添加 和 修改 中包含很多相同功能     使用同一个方法复用
		复用后 有冲突 使用flag isUpdata  判断是否新增 修改  
>> this.list.splice(索引位置,删除条数,新增js对象)
	添加 0,0,m   list.length-1
	修改 index,1,m
	删除 index,1
>> 获取索引值
	slot-scope = "s"   插槽
	v-for="row,index in list"

#################     后端

>>>>>maven+springboot+tomcat+ssm

	Maven SpringBoot Tomcat SpringMVC Spring Mybaits
	HTML Ajax Web Service MySQL
	
	控制层 解析请求(ajax 浏览器)	Controller	SpringMVC
	业务层 处理解析后的请求  业务逻辑    Service          Spring
	持久层 从数据库拿取业务需要的         Mapper          Mybaits
	
	h5 bootstrap element-ui vue 
	tomcat  nodejs
	ajax java sql json

### Maven
	项目管理工具:
		1.管理jar包
			复制jar包 java工程 lib目录jar包复制进去  build path引用
			
			Maven 管理jar   中央仓库,镜像仓库,本地仓库	
			Maven解决依赖版本冲突问题(半,你去解决部分问题,阿里dubbo,自己处理)、
			SpringBoot在Maven基础上(全面解决版本冲突,99%由spring组织解决)
			习惯:ssm xml方式,注解方式,springboot,tomcat
		2.依赖 坐标
		3.命令 mvn各阶段操作

#### 管理jar包
	仓库 依赖 坐标 命令
	
	maven.jar   安装配置 setting.xml   在eclipse中配置
	http://maven.apache.org/download.html
	D:\Git\env\apache-maven-3.6.3
	
******....默认本地仓库    Default: ${user.home}/.m2/repository   
		在setting.xml   中修改掉
			<localRepository>D:\Git\env\mvnrepo</localRepository>
******...镜像仓库   默认远程   中央仓库
			<mirror>
				<id>alimaven</id>
				<name>aliyun maven</name>
				<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
				<mirrorOf>central</mirrorOf>       
			</mirror>
		阿里云的镜像仓库可能有问题   需要切换到中央仓库下载个别jar包
	eclipse
		超级文本 配置

#### 使用 创建
	maven project 工程      pom.xml  配置文件    <标签>内容</标签>
	
	添加依赖
	选择maven project    create a simple project
>> 坐标   小写
		group id  		组id     域名倒写   	cn.tedu
		artifact id  	工程名称    				jk2012(项目名称)
		version   		版本号(默认值)
		packaging  	jar
		scope   			compile编译   test测试
	
>> jdbc2012  文件目录
		约定大于配置       目录进行分类 (减少开发配置量)
		pom.xml 核心配置文件
		
		main 业务代码   
		test 测试代码
		java 源代码文件  *.java
		resources  资源 图片 css js   配置文件
		
		target 临时目录  *.class  jar(拷贝)  每次编译自动产生
		
	maven project  使用坐标管理
>> 测试maven项目搭建成功
	jdbc TestTT.java

	依赖  需要用的jar包 中  用到第三方文件    maven自动加载
	
	  <!-- 通过依赖方式  增加jar包
	  		Dependencies -> add
	  		通过坐标输入需要的坐标
	  		
	  		<dependencies>
	  			<dependency>
	  				
	  			</dependency>
	  		</dependencies>
	   -->
	   
	   
	   
	   
	   >>>>>>>>>>>>>>>
	   1)加入jdbc的驱动包
	   2)把数据库测试java文件,复制过来,测试是否成功
	   
	   写坐标是一个jar,mysql.jar为什么会出现两个呢?
	   这就是maven带来好处,传统工程要一个一个加
	   maven自动去找它所依赖jar(pom.xml),它会自动下载
	   
	   使用springboot创建项目过程:
	   怎么导入依赖?
	   http://start.spring.io
	   
	   使用依赖后,maven自动给我们下载jar,jar怎么来的?
	   1)它是你配置的maven环境,它默认到中央仓库(镜像仓库:阿里云)下载
	   2)下载后保存在哪了?
					下载后就放在本地仓库目录中
				   下载非常多的jar包?怎么区分它们,万一重名怎么呢?
				   坐标就是区分它们,每级坐标它就是一个目录,最终jar就放在这个多级目录中
				   cn.tedu 两级目录
	   
	   Maven发明仓库、依赖、坐标,目的就是来管理jar,自动管理!!!
	   SpringBoot它利用官网:start.spring.io,输入关键字,加入依赖,它会自动最高版本
	   一旦使用SpringBoot技术,被牵着鼻子走,2.4.3,它会把所有它做依赖的都是最新
	   副作用:版本不兼容,需要小的范围修改下个别代码
	   
	   pom.xml是在保存时,进行自动下载,我配置Maven工作,它就检查语法,没错,就下载所有依赖
	   更新,提升jdk 1.8
	   
	   一旦jar包在仓库中,无需再次下载!!
	   >>>>>>>>>>>>>
	   
	   
>>通过网站添加依赖      https://start.spring.io/
	添加元数据metadata     add  mysql   在线预览
	
>>jdbc2012 项目   报红叉    
	右键项目名   maven updata  project
	Problems中   

	
>>>>坐标
	D:\Git\env\mvnrepo\mysql\mysql-connector-java\8.0.21
	本地仓库目录
	
	maven 仓库 坐标 依赖 管理jar包 形成本地仓库   自动管理
	SpringBoot  https://start.spring.io/  自动最高版本 

>>>>>>>>>>>  创建SpringBoot项目
	1)创建maven工程 
	2)官网产生pom.xml覆盖本地pom.xml,增加web依赖(springmvc) 
	3)创建HelloController.java,创建hello方法,返回字符串,两个注解修饰 
	4)创建运行类:RunApp.java,两句话,一句注解,一句run方法(固定)
	
	类放在src/main/java中
	
	改端口 
	8090   缓存 project -. clean 清除缓存
	
	我们创建的springboot项目都是springboot子项目,
	为什么需要parent父工程,它就定义好了要或者这些框架的jar包和版本
	
	oracle 10g它会自动启动网页服务,8080端口,端口冲突
	换端口
	在资源文件目录下,添加:application.yml 纯文本,要求很死
	server:
	port: 8090
	
	
#######总结: 后台java:构建项目 maven,springboot

#### maven替代传统项目方式:

传统项目需要自己拷贝jar包,需要自己去管理jar冲突,复制项目带着jar,项目就很大占用空间。
maven就手工维护jar,变成自动找jar,自动下载,项目中依赖这个jar,但这个文件并不在项目中
maven解决jar冲突,变成它来自己管理,springboot,把这些冲突,它的团队都解决,parent父工程
maven是pom.xml,我把这个文件给你,保存pom.xml它会再从外网下载

#### maven要实现上面功能,新的概念

	仓库:远程仓库,镜像仓库,本地仓库
		保存pom.xml,maven底层会检查你依赖jar是否存在,如果有就不下载,如果没有就下载
		先本地仓库,没有,去镜像仓库,去远程仓库,一旦找到,给镜像仓房复制,然后返回,
		本地仓库在复制一份,返回用户
		maven发明这套体系值得学习,仓库空,从每一次调用慢慢充满了
	依赖:
		声明jar,早期你调用的所有jar都需要声明
		会通过jar去找它内部要调用jar(依赖)自动把这个依赖的jar也下载
		同时,去掉版 本冲突
	坐标:
		jar很多,怎么区分这些jar,假如同名
		坐标:groupId 组ID(域名倒写)、artifactId(项目名称)、version(最高)、scope(编译、测试、运行)默认 形成目录:本地仓库路径/cn/tedu/hello/1.0/.jar。解决同名问题
	命令:mvn一套命令,a,b,c,顺序,mvn c,它会自动执行前面的命令
		mvn compile
		mvn test
		mvn install

#### springboot 替代maven来项目管理

最早目的:引入微服务 springcloud
springboot采用maven机制,完全兼容,是maven扩展!
和maven不同在哪里呢?
springboot自动化依赖,父工程,所以项目都是springboot子项目,继承它整理pom.xml
把spring框架直接继承,springmvc+spring都默认在这个工程里,
解决jar冲突,它的工程师帮我们做了整合,开发者就非常方便,主流

####  springboot 工程

1)直接创建springboot工程,idea和sts(spring eclipse),产生一堆垃圾文件
2)创建maven工程,官网产生pom.xml,覆盖

springmvc 框架,死规矩,自动化
1)HelloController.java
@RestController
@RequestMapping 映射 hello
2)启动main函数
两句话
@SpringBootApplication
SpringApplication.run(RunApp.class, args);

#### 下次课

maven环境
eclipse升级
oracle 升级到新自己配置端口:application.yml 约定,底层springboot会自动找这个文件名,进行加载





	
	
	
>>>>>>>>>
	->>下载maven文件	
			配置conf/setting.xml
				镜像仓库
				本地仓库位置
	->>eclipse 配置 maven
			window -. Preferences -. Maven 
						Download Artifact Sources
				-. installations      Add apach-maven-
				-. User Settings    Browse   conf/setting.xml
	->>创建maven project
				Create a simple project    
				Artifact
	->>pom.xml 添加包  依赖

	->src/mian/java   hello   
		HelloController.java
			@RestController
			
			@RequestMapping({"/","/hello"})
	public String hello() {//添加方法返回字符串
		return "你好,莹莹 我叫庆庆";
	}

	->src/mian/java   hello   
		RunApp.java

			@SpringBootApplication

			SpringApplication.run(RunApp.class, args);

	->src/mian/resources
		application.yml
			server:
        	(两个空格)port:(一个空格)8090
	
>>>>>>
	仓库 resources	-阿里仓库   		-setting
	依赖 dependency	-start.spring.io	-pom.xml
	坐标 coordinate	-分组 项目 版本	-jar包文件路径
	命令 mvn cmd
>>>>
项目
hello
jdbc2012


# 2021-02-22 ********************************************

maven
	项目管理工具
		自动管理jar包
		仓库 依赖 坐标 命令

	三大框架基础

##&&& 回顾
>>Maven 项目管理工具
	1.jar包  修改pom.xml文件添加 依赖 需要的jar包(如果又调用第三方jar包 随之下载)
	2.仓库   
		中央仓库(全球唯一,maven官网,Apache组织) 
		镜像仓库( 私服 git镜像   阿里码云10分钟更新一次 所以现在使用 *创建项目是开始是空的*  多级镜像) 
		本地仓库(本机中  在本地仓库总备份一份再给项目使用)
		****************************
		这种仓库的设计方式  Git
		*****************************
	3.坐标 多级目录, 防止同名jar包
		groupID 组ID 域名倒写 cn.tedu
		artifactID 构建ID 项目名
		version 版本号
	4.命令 a/s/s1 在执行s1时自动执行前面阶段命令

##&&SpringBoot
本质微服务
基于Maven 
使用sb 管理 不用他的微服务

它们目标根本就不同 
Maven项目构建工具,
SpringBoot本质把开发者引入到SpringCloud微服务路上 
SpringBoot基于Maven,它也可以项目构建工具,SSM三大框架项目

>>>好处:*******---------
	1.Maven自己维护pom.xml 添加依赖,排除依赖冲突
	2.Spring团队事项父项目, 拥有主流的jar包
	3.程序运行与maven无关  SpringBoot全面接管项目启动和加载
	使用SpringBoot注解 底层做了很多事情

------------------------------------------
	*****404 网页连接没有找到, springmvc的controller没有找到		
			--controller @RestController
			--路径
			--http://localhost:8080/car/get
			--刷新项目 缓存  project/clean

	*****400 类型转换错误
			@RequestParam("id") 注解要求严格,页面必须有id参数提交,没有就报类型转换错误
日期:英文日期:2020/02/12,中文日期:2020-02-12
---------------------------------------------
	
####&##&tomcat web中间件***********     
	nodejs运行javascript容器
	tomcat运行java容器(Servlet)
	glassesfish、jboss、webspare、weblogic(牛,收费) 
	分布式,集群,很多机器(几十台,几百台,几千,几万) 微服务架构对资源(硬件、软件环境)减低

####%%##
浏览器 http://localhost:8090/hello  如何找到HelloController.hello方法 调用
	????????????
	浏览器:http://localhost:8090/hello,怎么找到HelloController.hello方法并且调用 
HelloController hc = new HelloController(); //创建对象
hc.hello();	//调用它的hello方法!springmvc(spring)框架IoC控制反转,它来管理对象 
1)Spring它底层去创建对象 
2)它底层去调用方法
3)怎么把http://localhost:8090/hello和hello方法对应呢? 注解:@ReqestMapping("/hello"),规定全局唯一,它是在某个方法之上
------------
浏览器输入http://localhost:8090/hello
请求request(Servlet体系)
浏览器  得到 /hello
解析http://localhost:8090/hello localhost本地 8090端口找到tomcat
tomcat中间件( SpringMVC管理hellocontroller 找到注解@RequestMapping({/hello"})全局唯一  从而找到hellocontroller的hello方法   然后反射这个类(业务写在这个类中)   使用@RestController,返回的String字符串对象底层会使用jackson工具类转换java对象为json字符串,返回给浏览器,浏览器将字符串回显(展示)在页面上。)
---------------

####  
模拟底层  注解 标识


######&&&&%%%%%
	SpringMVC

>>>>三大框架各自负责
	SpringMVC 
		负责 request ajax json
	Spring 框架
		业务逻辑
	Mybatis 
		从数据库拿取业务中需要的数据

	SpringMVC组件
		DispatchServlet 核心分发器 封装  底层java web规范Servlet
		HandlerMapping 处理器映射 url解析
		HandlerAdapator 处理器适配器  找到controller
		CarController 实现请求request映射  调用业务方法 响应reponse
		返回ModelAndView被Model(Car),返回java对象

####&&&&&&&案例  1 .......................
http://localhost:8090/car/get
页面展示car的数据json字符串 
保时捷718 Cayman T, 红色,641000元

car.java对象  利用@RestController java对象 -> json字符串

///  请求连接 -> json字符串 -> ajax 请求
			把json字符串转换js对象 js对象利用vue解析数,最终在页面展示

....步骤.......................................
项目  依赖web pom.xml
CarController.java
Car.java
.............................
	pom.xml
	src/main/java
		1.cn.tedu.car.pojo package
		  Car.java   属性
		2.cn.tedu.car.controller package
		  CarController.java
		3.cn.tedu.car
		  RunApp.java
	src/main/resources
		application.yml
..............................
	

####&&&&&&&案例  2 .......................
表单中填写数据 提交到后台 SpringMVC
**springmvc 如何接收这些参数**

>表单本身可以提交信息到后台
<form action="url" method="get/post">
所有要提交的表单控件必须放在这个标签中,放在外面是不会提交
习惯在body标签下就写form
还要加一个提交按钮,submit,它点击完成会自动提交action指定的地址

action 提交到后台连接地址 
method get/post 请求方式 

>>>>提交的按钮 type="submit" 点击后自动提交action指定的地址
http://localhost:8020
/stu/add
?name=       没填 空字符串 null
&age=        没填 空字符串 null
&sex=on      on/off    没选 没有提交   
			单选框男女 设置value 男10
&hobby=on    on/off
&edu=6        
&button=%E4%BF%9D%E5%AD%98

>--------get请求方式的特点,
html规范自动把表单中的组件所有值拼接成一个字符串
key就是组件name(早期)或者id(新),value就是你填写的值
如果组件名称相同name,id,后台会以一个数组来接收

>----------get和post请求差异:
get是直接可以在浏览器url中看到参数,第一个参数?,后面的多个参数&
http://localhost:8090/stu/add
?name=chen&age=12&sex=0&hobby=%E4%B9%92%E4%B9%93%E7%90%83&hobby=%E7%88%AC%E5%B1%B1&edu=1&submit=%E4%BF%9D%E5%AD%98)
而post请求把这些参数都隐藏,你看不见!!!!会隐藏浏览器请求中,传递后台
http://localhost:8090/stu/add



###%%%%SpringMVC负责把请求中数据传递Controller
1.接收单个 接收id html隐藏框   input type="hidden" 不展示在页面,但会传给后台
2.接收多个 接收name,age,hobby
3.接收对象Student(Model)
4.url特殊RESTFul形式

....步骤.......................................
1)StudentController
a.接收单个参数 pid
b.接收多个参数 name, age, hobby
2)Studenet.java POJO(私有属性,利用对象接收参数)
3)RESTFul (接收少量参数)

****
###小结:

>>1)SpringMVC 帮我们减少工作量,它封装很多开发细节(高级程序员、架构师),坏处不透明
必须死记规则

>>2)注解总结
		a. @Controller ,标识这个类controller类,springmvc会增强它
		b. @RequestMapping,请求映射,把html里的表单组件text,number,radio,checkbox提交内容,
		把http://localhost:8090/car/get,找到对应方法,来利用反射执行这个方法,把html参数值封装到方法参数中 
		c. @RequestParam("id") String pid,它把页面html中id的值,存放参数pid中,不同时才需要这个注解
		d. @DateTimeFormat(pattern="yyyy-mm-dd") 把日期格式yyyy/mm/dd改成yyyy-mm-dd,转换,否则400错误
		e. @SpringBootApplication 标识RunApp类是一个springboot项目,底层会做springboot引导
		
		
>>3)POJO类
		a. 所有属性私有
		b. 一堆get/set
		c. 为了调整 toString()
>>4)前台和后台如何贯通!
		前台:html页面+css+bootstrap,表单和后端来对应
		后台:Java的controller来对应,pojo对象
>>5)请求类型:HTTP协议的规定
		a. GET,url后面直接显示表单值和参数 name=wang&age=18...,不安全,url长度限制:255
		b. POST,url后面干净,没东西,安全,习惯开发就使用POST请求,url长度:8k=8*1024
>>6)开发步骤:
		a. 写pojo对象:Student.java,所有属性,产生get/set,产生toString
		b. 写controller,StudentController,添加方法,添加RequestMapping,使用pojo对象
		c. 复制RunApp.java



>>注解
	@RestController    标识注解是controller    rest标识返回结果   java对象->json字符串.展示
	@RequestMapping("/stu/add")    映射连接
	@SpringBootApplication    标识这是一个springboot程序
	
	@DateTimeFormat(pattern="yyyy-mm-dd")    日期格式
	@Override    重写
>>项目中的文件
	pom.xml						依赖
	Student.java					属性 写pojo对象				src/main/java   /cn/tedu/stu/pojo
	StudentController.java	使用pojo对象					src/main/java   /cn/tedu/stu/controller
	RunApp.java					标明是SpringBoot程序		src/main/java   /cn/tedu/stu
	application.yml				改写端口							src/main/resources
>>文件内容
	pom.xml						https://start.spring.io/    查找,复制粘贴,依赖
	Student.java					属性私有private Integer pid; set/get  toString()
	StudentController.java	@RestController @RequestMapping("/stu/add") add方法
	RunApp.java					@SpringBootApplication   main{SpringApplication.run(RunApp.class, args);}
	application.yml				server:(换行)(两个空格)port:(一个空格)8090
>>前端页面
	<form action="http://localhost:8020/stu/add2" method="post" >   写在body下面
		<input type="hidden" name="pid" id="pid" value="0614"/>
		<div class="container">
			................
			<input type="submit" name="submit" value="保存'/>
		</div>
	<form/>
	
	
	
项目
working
car
stu   hbuilder day03/1form2


# 2021-02-23 *********************************************
## 回顾
### SpringMVC
	基于Spring
	MVC框架(Model,View,Controller(进行Model和View连接))和前台页面交互框架j2ee
	Struts1,Struts2(webwork 有很多bug),SpringMVC3.0注解
	
	性能: ???
>>作用      后台如何接参
Servlet规范:处理http请求(web网站) 
1)处理请求:request html表单提交数据,servlet规范把这些数据就存放在request对象
 request.queryString = "?name=tony&age=18..." 接收到查询串,所有的参数的类型是字符串 
 String name = request.getParameter("name"); 
 Integer age = (Integer)request.getParameter("age"); 日期

SpringMVC,它内部进行转换,如果转换成功,它会自动放入变量中
(String name, Integer age)
如果转换失败,放弃,变量初始值null
(Student student)
name,判断如果是复杂Object,利用反射获取私有属性,如果发现name属性,就设置值,
如果没有发现name属性,放弃

a. 单个参数,日期@DateTimeFormat(pattern="yyyy-mm-dd")
b. 多个参数
c. 对象
2)处理响应:response 返回,html片段,vue template 返回java对象给jsp页面(ModelAndView) 主流方式前台请求处理完成返回json(java对象序列化),和大前端Vue+NodeJS 方法返回java对象,@ResponseBody标识,底层把java对象进行序列化,json字符串

>>SpringMVC内部工作流程   有哪些组件
	localhost:  最终翻译为 IP地址:127.0.0.1:            IP地址定位一台机器     外网中都不同(通过外网访问别人的电脑的程序)
	
	过程:
	request (/car/get) 必须进入核心分发器 DispatcherServlet  (做校验 安全)  
	URL  进入  处理器映射HandlerMapping  (找到ControllerClassName)
	通过controllerClassName 进入处理器适配器HandlerAdapator(找到对应的controller内容)
	通过Controller控制器 传递给  Service业务层  进行业务处理
	通过Repository持久层在Database数据库中找到响应的数据 
	返回给Repository 给Service  处理业务
	返回给  Controller 形成 ModelAndView  传递给 HandlerAdapator  形成  ModelAndView
	传递给 ViewResolver 形成 Model  传递给  VIew(h5+css+Vue)   返回json字符串

	好处:
		MVC封装 代码量
		单一职责 , 分层  职责明晰(每个部分有每个部分的作用   清楚各部分内容)         (controller  业务逻辑    数据交互      )               为大项目做,方便团队开发(前端,后端,数据库DBA)
	
	组件:
		 1)DispatcherServlet,本质封装Servlet,核心分发器,请求转发 
		 2)HandlerMapping, 处理器映射,解析url,/car/get,包括参数封装 name,age,hobby,Student 
		 3)HandlerAdapator,处理器适配器,负责找到对应Controller,CarController,底层解析 @RequestMapping("/car/get"),找到这个所对应方法,反射 
		 4)执行完成Controller,把数据封装Model对象中 
		 5)ViewResolver,视图解析器,把model传递页面jsp,把model转成json字符串,返回页面
	

#三大框架源码
	spring-core.jar
	
	Servlet规范


######       Spring
>>强大
	j2ee,EJB 天生是远程传输,分布式结构,3.0完蛋 
	EJB 2.x (weblogic),写sql查询where,为每一个条件 name=chen and age=18 写的内容很多  每一条都要写
	spring作者,写了一本书 spring without EJB 
	spring3.x 全面引入注解开发,大大简化开发,不是你写,spring底层完成! 
	
	口号:不重复发明轮子!	
	
	拿过来,这个东西非常强大! spring没有所有都自己实现,它把业界最牛的产品集成! 
	
	旧三大框架:struts1	+	spring + hibernate 
					 struts2 + spring + hibernate 
	新三大框架:springmvc + spring + mybatis	小项目 
	微服务:	dubbo 阿里	,dubbox当当	15,16 ,基于ssm 
				springcloud 
					a. netflex 网飞,先开源后闭源
					 b. 自研 springcloud alibaba spring是真正的王者!

	*****不重复发明轮子   把最好的东西结合起来******

>>为什么强大
框架存在设计思想
	1.IoC  控制反转 剥夺对象创建权
		Car car = new Car(); 自己创建  car = null;   java
			struts2 使用对象model,car
		**Spring剥夺java 创建和管理对象权利  对象的声明权利
		---Spring拥有对象的 权利   那其他的框架就依附于Spring框架
		SpringMVC参数封装,    无用大量代码spring框架抽象 写了      
						提高了效率,减少代码量
		
		#*>    把权利方砖,本来是开发者的权利,spring使权利变成框架的权利     <*#
		
		问题:对象依赖
			需求:   员工 username deptname
						员工对象依赖部门对象
			User user = new User(); Dept dept = new Dept();
			user.setDept(dept);   //依赖关系体现
				打印user时也打印了dept
		
	2.DI  依赖注入   dependency injection
		user.setDept(dept);  自动执行
		注解:  @Autowired 注解标识  底层自动执行这句话

>>spring框架两种方式   底层创建对象
	xml方式     注解方式
	
	Car car = new Car();
	告诉框架car对象   全局限定名  cn.tedu.car.pojo.Car
			通过全局限定名,底层通过反射 创建对象
			..xml文件中配置   bean   (java中万物皆object   spring中万物皆bean)
					有多少对象就写多少bean声明
			..注解 包扫描
					一句话n个对象
		xml 文件                               ..maven  项目  spring-xml-ioc
			<!DOCTYPE>  文件头
		注解方式                                ..maven  项目  spring-annotation-ioc
			1)需要配置文件applicationContext.xml,配置包扫描语句,指定扫描目录pojo,所有类会自动创建 
			2)创建ApplicatContext对象,还是ClassPath...... 
			3)ac.getBean("hello")

>>xml开发步骤.......
	1.pom.xml spring框架
	2.applicationContext.xml    核心配置文件   文件写死自己找文件   src/main/resources
		会自动取resources 下去找
		<bean id="hello" class="cn.tedu.pojo.Hello"/>
			这句话有多少对象创建多少bean
	3.xml文件头
	4.Hello.java  普通类		src/main/java/cn.tedu.pojo
	5.xml中配置bean标签
		属性   id(beanName) :hello(驼峰命名 死规定)
			     class 全局限定名  包路径.类名   反射
	6.TestIoCXml.java  src/test/java/test
			测试类    ClassPathXmlApplicationContext (xml文件)   创建spring环境
	7.返回Hello对象    Hello hello = (Hello)ac.getBean("hello"); 会到spring环境(容器)
	8.hello.hi();	无需创建对象,就可以调用这个对象的方法
>>注解开发步骤.......
	1.pom.xml spring框架
	2.applicationContext.xml    src/main/resources
			<context:component-scan base-package="cn.tedu.pojo"/>
					这句话只需要写一次就能创建所有对象
	3.Hello.java  pojo    
			创建方法 验证    @Component有这个注解spring才会创建实例
	4.TestIoCXml.java  src/test/java/test
			测试类    ClassPathXmlApplicationContext (xml文件)   创建spring环境
			main方法中
			//创建spring环境,
			ApplicationContext ac 
						= new ClassPathXmlApplicationContext("applicationCOntext.xml");
					//获取Hello Bean对象,调用齐方法,底层spring创建对象
					Hello hello = (Hello) ac.getBean("hello");
								通过反射 得到实例
					hello.hi();//直接调用对象方法
					
>>错误没有bean  就是没实例    注解方式时 在类文件中加上@@Component
	No bean named 'hello' available
	没有了bean的标签指定,pojo并不是所有的类都需要创建实例?
	给一个标识,标识它需要创建实例,@Componet注解!spring检查pojo类,
	如果有这个注解才创建实例,如果没有这个注解就不创建对象实例!
	
	可以看到,注解框架一旦搭建好,只写业务代码,而无需再次配置环境!
	注解方式优于xml配置方式!
	
>>spring 底层实现工作原理     ......核心是 初始化, 创建对象, 容器, 匹配,getBean  反射
	1.包扫描   拿到对象和包路径
	2.创建容器 map(k,v)
	3.匹配 创建对象,放入容器
	4.创建getBean("hello")
	
	模拟ApplicationContext接口
	模拟ClassPathXmlApplicationContext(inti,createObject,getBean)
	
	........步骤........
		java工程
		ApplicationContext接口
		ClassPathXmlApplicationContext类
		构造方法  (初始化init,bean定义 BeanDefined类,createObject放入容器)
		getBean方法
	
### DI
.....过程.......
	1)创建核心配置文件,设置包扫描(拷贝)
	2)创建pojo,dept,user,这两个对象关系,注解@Component@Autowired
	3)写测试类,调用对象

	需求:用户的所在部门,怎么在pojo中体现这个关系?
	1)传统方式,set注入(利用set方法把关联关系绑定)java编程
	2@Autowired 自动装配,spring自动实现
	
### 小结
	1)spring实现IoC控制反转,把程序创建对象控制权,抓在手里,所有人就必须依赖我
		spring提供很多方便功能,而这些功能自己可以写,代码量很多
	2)IoC控制反转具体怎么实现的?
	a.xml
			在applicationContext.xml核心配置文件,通过来实现
			每个对象要写一行,xml没有编译,字母写错,位置写错,运行时报错
			spring在启动时,找到核心配置文件,解析xml文件,dom4j。拿到所有bean标签
			能拿到id=hello和class=cn.tedu.pojo.Hello,创建对象,反射按class进行反射
			得到对象实例,然后把它放入容器map.put(id, instance)。怎么获取?getBean(id)
	b. annotation 注解方式
			在applicationContext.xml核心配置文件中,通过一行代码
			包扫描:<context:component-scan base-package="cn.tedu.pojo"
			java提供磁盘io一套api,它获取磁盘目录,文件和子目录
			文件名:User.class
			路径:D:\java\ws\2012\spring-annotation-ioc-2012\src\main\
			java\cn\tedu\pojo
			路径+文件名:java.cn.tedu.pojo.User(className) 经过api层层转换,获取到全局限定名
			user(beanName)
	
		把这两个信息放入BeanDefined对象中,利用反射创建user、dept。。。  
		把它放入全局成员变量,beanDefinedList中  
		
		类的构造方法执行createObject方法  
		遍历这个list,获取每个bd(beanName,className)  
		拿到className,利用反射创建对象实例  
		
		放入容器map(key=beanName,value=instance)  
		
		getBean,从容器中获取,"hello"=key,根据key就获取对应value,获取到对象  
	3)IoC和DI什么关系?
		IoC概念,编程思想(好莱坞原则)
		DI具体措施,因为spring要实现IoC,衍生bug!,副作用。来解决问题
		
		Autowired自动装配,实现DI
		
		@Autowired标识,spring通过反射拿到类,拿到类的属性getField();,拿到属性上注解
		user
		@Autowired
		private Dept dept;
	
		如果有这个@Autowired注解,getBean("dept"),获取到容器中dept对象
		反射set方法 set(instance, dept);
		打印user对象时,getDept就可以拿到值!
	
	作页:
	
	1)xml实现ioc
	2)annotation实现ioc
	3)annotation实现di
	实现ssm整合时,就会用到这些知识
	
	明天任务
	
	1)di源码实现
	2)面向切面编程AOP(aspectJ),springmvc 拦截器
	
>>>>>>>>>
	src/main/java  业务
	src/main/resources   .yml   .xml 
>>今日项目
	spring-xml-ioc
	spring-annotation-ioc
	working-spring
	spring-di-annotation

# 2021-02-24 ********************************************

## 回顾
>>Spring
		抓住了面向对象的管理权限  就成为核心
	IoC控制反转概念
		1.剥夺其他框架创建对象的权利      框架围绕对象model(业务数据)开发
			struts1,struts2,springmvc,hibernate,mybatis
			这些框架内部都要围绕对象model(业务数据)而进行开发
			struts1/struts2/springmvc 只负责后台系统前端(前台后台交互),它不能完成整个系统
			hibernate/mybatis 只负责持久层和数据库打交道,它也不能完成整个系统
			spring负责把大家聚拢在一起,完成整个项目,小组长,项目经理,部门经理
			spring野心,它来管理对象,可以在前台和数据库都需要对象,它可以共享给它们。
		
		2.如何实现ioc
			a.反射   在服务开启时就创建了对象, 
				利用反射来动态创建对象,在服务开启时就创建,map,这个对象已经在内存中,直接获取, 性能要比new性能高
			b.DI对象关联(学生类 老师类)  如何关联产生了DI    反射实现set,@Autowried,自动装配
		3.注解开发  有很多约定  约定 cn.tedu.pojo,cn.tedu.controller,cn.tedu.service
			@Componet@Controller@RestController@Service@Repository@Mapper
			@RequestMapping("/car/get")@Autowired 自动装配

>>junit单元测试
	1.在要测试的方法上增加注解    @Test
	2.第三方jar包  但eclipse支持  @Test错误提示,添加5.x
	3.junit专门为测试,    
	注意:     写在方法之上,public方法,无返回值
				一个类有多个@Test   没有执行顺序性
				多个@Test  右键运行会执行所有的@Test方法
				指定方法运行,双击方法名,右键运行
				不能随意几个方法,,,要么一个,要么全部
>>DI核心
	获取User对象,遍历它的所有属性 
	检查每个属性的@Autowired注解,如果没有就没有di,如果有 利用反射对属性.set,把一个对象set到这个属性中 
	private Dept dept; dept.set(getBean("dept"))
	
	这里有个问题,属性是私有的!必须设置一个开关,开关默认值不允许false 调用代码之前,把开关设置true,可以操作私有属性!


>>>
	反射打破了封装

>>>>Spring  AOP面向切面编程
	面向过程  C
	面向对象  Java
	面向切面  

---面向切面
		写日志      动态增加代码
		a.可以纵向编程,一下管理所有类     传统编程横向编程
		b.可以随时加入,随时移除
		c.代码没有侵入性  (给类增加功能,但不在类里写)
				注解(紧耦合)    面向切面(松耦合)
		d.架构松耦合 随时加,随时移
		
	servlet 
	springmvc,
	spring(Controller,service),AOP面向切面编程,aspectJ(第三方)比Java反射要强大  
			动态代理技术(类似反射)  编译时  把动态码加入class(改内存中类)   !!!织入
	
	切面可以多个  n个(功能)   性能会降低       
			每拦截一次执行时间就浪费一点,特殊业务应用时值得消耗

>>>>>>   carAOP  实现拦截器 controller    AOP service
	怎么实现spring的service
	增加两个类,添加@Autowired注解!
	CarController.java
	CarService.java	接口
	CarServiceImpl.java	它的实现类
	
	业务获得car信息
	把写在controller业务,推到service

>>>>>>为什么写接口
	接口是一个规范,公开
	实现类隐私,一个接口有多个实现类
	jdbc,sun接口规范
	mysql驱动,oracle驱动,实现类

	面向接口编程,配置driver : com.mysql.jdbc.Driver

>>>>>>拦截器  interceptor
	拦截类的方法的执行    car/get方法
	三个点  
		pre			方法执行之前
			get
		post			方法执行之后
		complete	方法返回页面之前
	
	>>具体实现
			1.写拦截器 CarInterceptor/UserInceptor    实现接口  HandlerInteceptor
			2.告诉spring框架拦截器的存在   注册			实现接口  WebMvcConfigurer
>>>>>>监控每个方法执行时间
	TimeInterceptor 1)在方法执行前 pre,记录下当前时间 startTime ,System.currentTime 毫秒值
	2)在方法执行后 post,记录下当前时间 endTime
	3)执行时间 = endTime-startTime
	
	>>>多个拦截器
		形成拦截器链
				执行有顺序  谁在前面 谁先执行 
		
		我是拦截器 preHandle				第一个  pre
		2 pre										第二个  pre
		car get									业务方法
		2 post									第二个	post
		执行耗时96ms							第二个	post
		我是拦截器 postHandle				第一个	post
		我是拦截器 afterCompletion		第一个	complete

>>>Component注解
	标识后,spring底层使用包扫描机制,会自动创建类实例,放在容器中
	@Component		不确定这个类分层职责
	@Controller		springmvc的controller
	@Service			spring的service
	@Mapper			Mybatis的Mapper
	
	不配置xml核心文件的包扫描,怎么能执行
	base-pakage="cn.tedu.pojo"
	
	SpringBoot项目默认采用自动使用包扫描(注解)
	基准路径: RunApp启动时目录,
	约定:controller/service所有的都是在这个目录之下      **************


>>>>并发
	高并发  当第一个用户 pre方法之后 还没post  第二个用户插进来 pre
	
		n多个用户访问
			car/get 方法,只创建一个对象,所有用户及共享这个对象
	CarController单例
		用户拥有自己的线程 相当于变量用户私有
		每个用户拥有独立的线程
		--操作系统保证的私有

		ThreadLocal   本地线程 
			使得每个用户拥有自己的线程,

#####  小结
	1)spring框架,是所有框架中最强大,
		它管理对象声明周期,其他框架需要这个信息,只能从它来获取
		不得不依赖它,
	2)IoC和DI、拦截器、AOP,它就能增强我们的项目
		a. IoC 控制反转,创建对象(启动)注解@Component,
		放入容器,创建一次,供多次调用
		b. DI 依赖注入,@Autowired体现,绑定对象关系,对象实例注入
		c. 拦截器,面向切面编程
			面向对象:横向编程,每个类CarController,CarService。关心的是每个类
			面向切面:纵向编程,n多类,每个类所有方法的执行时间!
			先有面向对象,面向切面是面向对象有益补充,有了更好,没有也没关系。
			拦截器:打印日志,时间耗时统计,权限验证
	3)拦截器具体怎么实现?
		a. 写自己拦截器
			1- pre方法,在业务方法执行前执行
			2- post方法,在业务方法执行后执行
			3- complete 完成方法,在业务方法执行完成,返回页面之前执行
		b. 注册这个拦截器
			@Configuration spring底层会全局配置
	
		如果多个拦截器,形成一个拦截器,执行顺序,先进后出   
	4)方法的耗时拦截器实现
		优化一下整个项目,性能!
		先要找出慢地方?找到系统中慢地方,看合理不,有优化余地,优化系统快!


>>>>>>>>
TestReflect .java
	创建对象,执行方法invoke,注解@Autowried(方法使用了就执行,标明)
	
>>>>>>>>项目文件
	working-spring   -annotation
		test						TestReflect     
		spring.annotation 	Autowried
									hello
	
	carAOP   切面
		cn.tedu.car.service   
				CarService.java
				CarServiceImpl.java
		cn.tedu.car.controller
				CarController.java
		cn.tedu.car
				RunApp.java
		
		cn.tedu.car.interceptor      拦截器
				MyInterceptor.java    实现HandlerInteceptor接口
				SysInterceptorConfig.java   配置类
				TimeInterceptor.java    方法执行耗时 测试拦截器
>>>>>>???????    问题
	文件与文件之间如何关联的
		@Autowired

# 2021-02-25 ********************************************

## 回顾
>>>>DI由于spring实现IoC,改变对象为开发者创建实例,为spring框架去创建对象
	随着对象关联关系也变成从开发者主动set注入方式改变di自动装配@Autowired
	......底层实现思路,利用设置关联对象属性上面加一个@Autowired
				spring进行包扫描创建完成所有类对象实例,放入beans容器中
				再次扫描,获取每个类的所有属性,判断属性是否有@Autowired
	User
		@Autowired
		private Dept dept;
		private String userName;
	dept属性加了注解,而userName是没有加
			这个注解就成了是否DI的判断依据,dept进行DI,userName不进行
	dept.getName(),去容器中进行Dept dept = getBean("dept")
	反射 field.set( getBean("user"), dept)
	
	这个过程非常繁琐,这是spring框架底层去实现,无需开发者写代码,
	开发量急剧降低,深受开发者喜爱,主流开发方式提倡注解开发。
	
	企业中程序员,关注点,在于怎么用好框架快速开发,快速迭代,快速交付
		
		
	@Autowired 
>>>>拦截器
		面向过程,关注点:写代码开发步骤,函数(怎么查询某个学生)
		面向对象,关注点:类(学生类)、对象(实例),怎么查询
	CarController,CarServiceImpl,UserController
	如果每个类中有相同功能:打印日志,执行方法耗时,权限
		面向切面,一次通用结构,新加的内容无需额外编码(复用)
				它可以随时干掉(系统测试阶段,试运行阶段:打印日志,执行方法耗时)
				一旦系统稳定,这些功能就关闭
		
	servlet规范:filter过滤器
	springmvc规范:interceptor拦截器
	spring规范:AOP

	面向切面编程  相同的功能,写一次通用

>>>>开发拦截器需要步骤:...........
		a.写拦截器类 TimeInterceptor
		b.注册拦截器 @Configuration
			spring框架在方法执行前去调用对应拦截器
			post有handler参数,它代表被拦截对象,
			handlert="cn.tedu.car.CarController#get"
			
>>>>所有遇到注解,用在哪里
	a. @SpringBootApplication springboot引导项目启动
		以前javaWeb项目手动启动tomcat,而且要配置它,项目war
		tomcat集成在里面,直接运行springboot.main就可以,
		获取这个类上面注解@SpringBootApplication,然后启动spring,初始化类
		把所有@Component@Controller@RestController@Service、
		创建对象实例,把它放入容器,获取对象快!
	
	b. @Controller@RestController有什么区别?
		后者多一个注解标识:@ResponseBody 响应,
		jackson技术api工具包,把java对象转换json字符串,反着来
	
	c. @Autowired 实现DI依赖注入,自动装配
	
	d. @RequestMapping("/car/get")
		springmvc中提供,和浏览器上输入url进行匹配
		http://localhost:8090/car/get
		ip地址找到服务器	:8090/car/get
		端口号固定某个服务:tomcat是servlet规范运行环境:web中间件
		/car/get
		把这个值传给我们的程序:springmvc,DispatcherServlet
		DS去找匹配Controller(user/dept/car)
		某个controller的方法上写注解
		@RequestMapping("/car/get") 唯一值、
		spring框架在初始化时,它初始化完毕,springmvc初始化
		包扫描,扫描所有controller类,然后获取所有方法,拿到方法上的注解
		获取这个注解value属性,都存在一个集合中
		Map.key="/car/get",value=class CarController#get
		反射ass来创建实例,invoke回调get方法
		@RequestMapping({"/","/car/get"})
		@RequestMapping(value="/car/get")
		@RequestMapping("/car/get")
	
	e. @Service 约定它是描述service层
		spring包扫描,创建对象实例,把它放入容器
	
	f. @Override 继承,子类的方法和父类同名,给开发者看到
	
	h. @Configuration spring框架全局配置,全局变量,系统各处进行调用
	
>>>>>ThreaLocal对象用完要自己释放,remove(),防止内存泄漏!

#####   
>>>>AOP
	拦截器思想
	概念:
	通知: advice 五种
		1.前置	pre
		2.后置	post
		3.环绕	pre+业务+post
		4.完成业务之后返回前	afterReturn,afterComplete
		5.异常	error,exception
	aspectJ  比interceptor强大    aspectJ可以应用在各个类,所有系统运行类拦截
			interceptor 局限于springmvc
			filter局限于servlet
	spring集成了aspectJ        B/S  C/S   嵌入式
	
	项目中 一个地方使用   必会
>>>>开发步骤............
	1.导包 springboot 集成了 web(spring+springmvc)   需要手动添加aop
			自己添加依赖   spring-boot-starter-aop
	2.切面类 TimeAspect.java    @Component 关联类    @Aspect   
	3.空方法   @PointCut("切点表达式") 切点 
		private void aopPointCut()  //空方法
			切点表达式(最强大)  "execution(public * cn.tedu.car.service..*(..))"
						方法说明 public  返回值类型 *  包路径(可以很多)..   方法 *  多个参数(..)
						public Car cn.tedu.service.CarServiceImpl get(){}  
						
						public Car cn.tedu.controller.CarController get(){}  不拦截  controller层
				判断依据,项目配置一次就行
	4.around方法    环绕通知:@Around("aopPointCut()")   //  
	5.around方法参数    JoinPoint连接点:   切面切得谁   信息藏在joinPoint中
	6.around方法参数 ProcedingJoinPoint joinPoint 实现类,
	7.获取类名和方法名
>............
	caraspect
		cn.tedu.car.aspect  TimeAspect.java  

### mybatis

	J2EE,EJB框架,hibernate负责java和数据库之间转换 
	ORM,object relationship mapper,把数据库jdbc,ResultSet结果集,它不是java中model对象
	model (pojo ) 属性,代表数据
	ResultSet ( rs.getString("name") );  桥梁转换映射 hibernate/mybatis    model name:"tony"
	hibernate   完全面向对象,
				HQL,对象方式来查询数据,内部最终会转换SQL,利用jdbc操作数据
		SQL:     select * from tb_item   表
		HQL:     from Item  对象
	
	ibatis   mybatis 投身Google  半面向对象  直接拼接SQL(一套规则)  直接操作jdbc
	
	mybatis 性能高
	hibernate 对象状态   OGNL表达式   很难控制  漏洞百出
	
	小型项目使用hibernate 大型项目使用mybatis
	
>>>>mybatis完成orm映射   规则
	jdbc  :   
		String sql = "select * from tb_item"; 
		preparedStatement对象,CRUD方法,executeQuery(sql) 查询:ResultSet对象
		查询返回 ResultSet对象
	mybatis:
		把sql写在xml文件中    ItemMapper.xml
		Item.java  POJO
		<select id="find" resulttype="List">     
			select * from tb_item
		</select>
		
		按mybatis规则写完后,它底层自动将sql查询完成结果集,自动保存对象中 
		返回是一个集合,只声明集合元素类型,默认List集合
	
>>>>mybatis 结构
	
	
>>>>开发步骤.........................
	1.数据库jtdb-small.sql  
	2.pojo对象 Item.java
	3.映射文件 ItemMapper.xml
	4.核心配置文件 sqlMapConfig.xml
		测试类
			 读取配置文件:Resourses 
			 ibatis提供,返回InputStream
			SqlSessionFactory=读取sqlMapConfig.xml
			builder创建工厂对象 
			SqlSession执行sql statement = namespace.id(find) 
			按规则写完,mybatis会把这些按约定规则串接,底层执行xml里sql最终映射到java对象 返回值java对象(model)
			
	创建项目:  springboot   pom.xml  mybatis/web/mysql
		jtsmall
		
	创建上面的两个配置文件,如果没有提示,配置一下DTD文件
		DTD文件描述xml由哪些标签组成,它会和eclipse配置形成提示 
			1)sqlMapConfig.xml (配置后不生效 eclipse) 
			2) ItemMapper.xml
>>>>最爱犯错:
	Mapped Statements collection does not contain value for cn.tedu.jt.mapper.ItemMapper.find
		1)命名空间和statement参数写的一致不一致
		2)sqlMapConfig.xml中忘了导入xml文件
		3)调用statement别写错了
	unknown datasource property dirver
		sqlMapConfig.xml 文件中单词拼写





>>>>项目
	caraspect
		cn.tedu.car.aspect  TimeAspect.java
	jtsmall
		pom.xml
		main/resources    					sqlMapConfig.xml			环境配置
		main/resources/mappers  		itemMapper.xml				sql查询
		main/java
			cn.tedu.jt.pojo			Item.java								私有属性
		test/java
			test							TestMybatis.java


# 2021-02-26 ********************************************
>>>>AOP
	j2ee servlet标准(网络请求request和响应response)  tomcat实现了
	都是拦截方法执行    权限判断
	1.servlet		过滤器filter  只能用于servlet
	2.springmvc	拦截器interceptor  controller(本身不是servlet)
	3.spring aop	aspectJ   b/s  c/s  嵌入式   没有请求和响应,没有servlet和controller   直接操作业务方法     从方法的角度出发
		***spring aop更加强大,不局限于request和response处理

>>>>AOP 结构
	@Aspect  注解,此类为切面类
	@Component  告诉spring这个类要进行管理,创建对象实例
	@PointCut  切点,谁拦截谁不拦截可选择   判断依据:切点表达式(满足或匹配 放行 false 不处理) 
				拦截器,所有的请求都拦截
			切点表达式  修饰符,返回值,包路径.,方法,参数 
			public * cn.tedu.car.service..*(..)
	
	通知:五种 前置pre 后置post 完成返回complete 异常 环绕around
	@Around("空方法")
	around方法参数   ProceedingJoinPoint joinPoint  获取被拦截对象,也能执行对象方法
	
	>>>>拦截器
		在所有类上运行时,动态给类的方法添加代码
		动态改变别人类填写代码,
		
		TestMybatis2.java

>>>>mybatis
	数据库结构化,sun jdbc规范  结果集对象ResultSet(,字段name,类型varchar)
	java model对象 pojo 数据 name,String
		高并发宕机
		对象model
	转换,hibernate小项目,ibatis,mybatis大中型项目
	
	hibernate 全面向对象ORM框架 HQL
	mybatis 半面向对象ORM框架 SQL
		mysql面向过程
		
	>>>>使用mybatis
		sqlMapConfig.xml		核心配置文件 数据库4个参数
		Item.java pojo			model对象,暂存数据,传递数据
		ItemMapper.xml			核心独有的,发明一套标签,标识CRUD <select>sql语句
		SqlSessionFactory		工厂类,产生sqlsession  线程安全支持高并发   单例      
		SqlSession					线程非安全(高并发会出乱)   解决:私有           多例 原型
		.selectList
		
	>>>>卖点sellPoint是null
		数据库是sell_point  pojo是sellPoint   不能匹配
		使用as别名
		mysql    select sell_point form tb_item
					select sell_point as sellPoint form tb_item
					
					select sell_point as sellPoint,t.* form tb_item as t
>>>>解决字段属性不对应
	1.sql
		select sell_point as sellPoint,t.* form tb_item as t
	2.mybatis
		自身特性ResultMap强大
			使用resultMap定义新的映射规则,  pojo 属性名 与 数据库 字段名之间
		
		id id
		title id
		sell_point> ResultMap写一个映射规则 >sellPint
		
		子定义一个ResultMap,在select标签上引用这个映射规则接口 itemRM
				resultMap 新的构造映射规则,使用新的
								字段名和属性名相同省略
					 <resultMap type="cn.tedu.jt.pojo.Item" id="itemRM">
									type 指封装的pojo对象名
									id 命名,在文件中唯一   itemRM
							标签属性
							property 值pojo对象id属性
							column   数据库表结果集中字段名
										<id property="id" column="id" />
										<result property="title" column="title" /> 
										
										<result property="sellPoint" column="sell_point" />
					定义了映射 resultMap 规则
						使用 在<select>
							<select id="find" resultMap="itemRM">
								
				
		
		resultMap 标签
				如果数据库表的字段和属性一样可以省略
			id				表的主键
			result		其他,非主键的字段
			association	多表查询时   一对一关联
			Collection		多表查询时	 多对多关联


>>>>resultMap   多表查询


>>>>  mybatis 操作  查询数据库
	1.xml
	2.xml+接口(面向对象)  
			TestMybatisInterface.java  接口实现查询    //读取资源文件,解析xml文件
			ItemMapper.java  接口文件

>>>>  接口,实现类,,,,怎么找到xml中的find
	不需要实现类
		底层会创建实现类,
	加载  执行顺序
		sqlMapConfig.xml 数据库配置
		ItemMapper.java
		mappers/ItemMapper.xml
	
	真正底层是创建了实现类,动态创建,你看不到,内存中
	
	动态代理技术动态产生类:
	jdk动态代理($Proxyn),cglib动态代理(cgblib....)
	
	断点:观察变量的值,要看变量后面设置断点
	
>>>>操作
			itemMapper.xml
					<select id="find" resultMap="itemRM">
							select * from tb_item
					</select>
			itemMapper.java
					public List<Item> find();
			TestMybatisInterface.java
					@Test
						public void mybatis(){
							SqlSession session = factory.openSession();  
							ItemMapper mapper = session.getMapper(ItemMapper.class);
							List<Item> list = mapper.find();
							for(Item o:list) {
								System.out.println(o);
							}
						}
	查询 select
	新增 insert
	修改 update
	删除 delete
	 
	获取一条get
	查询多条list
	
	mysql默认自动提交为false 手动提交    session.commit();   session数据库

>>>>  mybatis 动态标签    
	配合方法把参数传入,mybatis加入
	单值传递    id  #{id}
	多个 使用对象   item,#{id}=item.id,#{title}=item.title,#{sellPoint}=item.sellPoint
	
	文件中
		itemMapper.xml		标签添加属性parameterType   sql查询语句的 值设置为#{}
		ItemMapper.java	空方法添加参数形参,因为使用方法时动态添加值
		TestMybatisInterface.java    	调用方法时,添加方法的实参
			
	
	select
		parameterType="string"
		select * from tb_item where title like #{title}
	insert
		parameterType="cn.tedu.jt.pojo.Item"  pojo对象
		多个值传递进来,pojo对象 参数类型为pojo对象
				对象方式接收参数  名称和pojo中属性名一致 默认null
			INSERT INTO tb_item 
			(id,title,sell_point,price,num,cid,STATUS,created,updated)
			VALUES(NULL,#{title},#{sellPoint},#{price},#{num},#{cid},1,NOW(),NOW())
			新增为多个值  使用pojo中   class item     Item对象  设置Item对象的值
			Item item = new Item();
					item.setTitle("12345689");
	update
		
		
		表中有多少记录
			select count(*) from tb_item
>>>>mysql表的主键,int/long支持自增
		auto_increment ,数据库会记录当前值,每次新增一条记录时,这个值+1
		不需要开发者填写
		insert 时 id 为null
		
## 小结
mybatis 完成ORM,对数据库封装java对象

	实现两种方式:
	1)xml方式,selectList,insert,update,delete,selectOne
	2)接口方式,重点

>>>接口方式开发步骤:
	1)写映射xml文件,配置各个标签
	2)在接口中增加它的方法,和标签一一对应,
		public resultType/resultMap 标签id( parameterType)
		public List find(String title);
	3)session可以按接口方式调用
		ItemMapper mapper = session.getMapper(ItemMapper.class);
		mapper.find("%诺基亚%");

>>>映射文件 ItemMapepr.xml

		1)namespace命名空间:它要和谁来对应?但是命名空间名字和接口类的名字相同
		2)返回值类型:
				a. resultType:int/long/string/Item
				b. resultMap:对应特有resultMap标签(如果有pojo的属性和结果集字段column不一致)
				多表联查 left join, inner join, right join
				type=返回值对象(数据放到哪个对象中)Item
		3)参数类型:
				a. parameterType:int/long/string 单个参数,/Item 对象参数
				b. parameterMap:废除,被parameterType替代

				参数和返回值需要时声明,不需要时就不写!根据业务需求定。  
		4)占位符
				#{id},代码安全,preparedStatement,?,防止sql注入,安全
				${id},代码不安全,拼串 title = 'title'
		5)自增主键:mysql直接支持,独有 auto_increment
				mysql表会记录最后一次插入值,+1。中间删除了一个id,维护成本过高,舍弃

		6)线程安全,和线程非安全
				线程安全对象:支持高并发,加锁,阻塞(等待)
				SqlSessionFactory,成员变量
		
				线程非安全对象:不支持高并发,不能为成员变量(多个方法共享)
				写在方法内容,局部变量,方法私有,
				SqlSession,只能放在方法内,每次都要创建
		
		7)单元测试 @Test
				4.x	@Before
				5.x	@BeforeEach
				双击执行@Test,jUnit它会先执行@BeforeEach方法
		



			
				

>...项目......................................... 
	jtsmall
		TestMybatis2.java
		itemMapper.xml						写SQL语句
		TestMybatisInterface.java    
		ItemMapper.java					空方法
	

# 2021-03-01 ********************************************
### 知识回顾
>>>>mybatis
	持久层框架,完成数据库的封装,半面向对象框架
	
	一边关注是xml中如何配置sql(面向过程编程),一边关注是java模型对象(面向对象编程)
	半ORM映射框架。
	
>>mybatis完成数据库表的结果集和java模型对象映射
	操作的是结果集,从结果集中获取数据
	select sell_point as sellPoint from tbitem t
			1)根据jdbc提供元数据:getMeta().getColumneName(),根据列名获取某行值
					sell_point,(1232)反射,获得pojo的私有属性,
					private String sellPoint;
					反射 sellPoint.set()
			
>>>> mybatis 动态 sql
	占位符 #{name}  select * from tb where title like #{title}
				prepareStatement 的 ?
			${}  有sql注入问题  字符串拼接  自主拼接''单撇    用户也可以拼接会发生sql注入
			#{} 防SQL注入

	参数  parameterType  mybatis传入参数类型 
			单值    mybatis提供的 string/int/long    java提供的 java.lang.String
			多值    pojo对象,复用 传递数据 参数作用
	返回值 resultType/resultMap 
			resultType: string/int/long/pojo
			resultMap: 表的字段和pojo名称不同时  定义resultMap映射
	标签 xml标签
			select(find get count) insert update delete

>>>> mybatis 3中操作方式
	xml		ItemMapper.xml   使用session.selectList(),selectOne()
	接口		ItemMapper.find() 对象方式
			它通过cn.tedu.jt.pojo.ItemMapper.find()=xml.namespace(约定)
			=cn.tedu.jt.pojo.ItemMapepr,找到映射文件,find找到某个标签id(唯一),获取sql语句来执行
			**本质还是执行xml映射文件!
	接口+注解  把xml消灭掉(99%)多表联查resultMap,需要映射文件

>>>>  jtsmall问题
	查询,用户没有输入条件,
	删除,删除多个  传递多个参数  in(1.2.3.4)


>>>> 动态SQL
	if where set foreach(形成in子查询串,id就可以多个值,批量删除)
			作用:
				if 判断作用,如果条件成立就出现拼接sql字符串中,如果条件不成立,不出现
						null判断条件,空串
				where 自动删除条件前面的and或者or
				set update修改,如果最后一个set条件多余逗号,会自动删除
				foreach批量删除,形成in字查询串
	
	1.查询多个值    select 
			jtsmall2
				itemMapper.xml
				ItemMapper.java
				TestMybatisInterface.java
			
			if标签  :  条件成立就拼接sql语句  条件不成立就不拼接
						利用if可以查询多个 条件
			where标签   :  自动删除where条件 前面的and/or
			-------
			if条件成立时,造成新的错误,sql语法的错误,多了一个and
			有两个方式来解决:
			1)sql技巧 where 1=1
			SELECT * FROM tb_item WHERE 1=1
			AND title LIKE '%诺基亚%'
			AND sell_point LIKE '%超值特价%'
			-------
			
		
		<select id="find" resultMap="itemRM" parameterType="cn.tedu.jt.pojo.Item">
				select * from tb_item 
				<where>
				<if test="title!=null">and title like #{title}</if> 
				<if test="sellPoint!=null">and sell_point like #{sellPoint}</if>
				</where>
			</select>
			调用方法时使用item对象(有多个值),两个值同时成立
		///
	2.更新 
			if标签   :     test测试中item中更新的值    少于   itemMapper.xml中查询语句的值
			set标签  :    解决 sql语句中where前面的逗号去掉
	
SQL syntax  sql语法错误 
		//
		<update id="update" parameterType="cn.tedu.jt.pojo.Item">
				update tb_item 
				<set>
					<if test="title!=null">title=#{title},</if>
					<if test="sellPoint!=null">sell_point=#{sellPoint},</if>
					<if test="price!=null">price=#{price},</if>
					<if test="num!=null">num=#{num},</if>
					<if test="cid!=null">cid=#{cid},</if>
					<if test="status!=null">status=#{status},</if>
					updated=now() 
				</set> 
				where id=#{id}
			</update>
			
		///
	3.删除
			in子查询串  实现多条记录删除
					万能参数 map
					collection集合key item当前元素值 open开始前缀 close结束前缀 separator分隔符
					in(1,2,3,4)
					ids  map的key
					id	foreach中的 i   for(Item i:o){}
					(
					)
					,
			///
			<delete id="deleteMuch" parameterType="map">
					delete from tb_item where id in
						<foreach collection="ids" item="id" open="(" close=")" separator=",">
							#{id}
						</foreach>
				</delete>
				调用时使用map集合 map<"ids",para>   para是数组对应id
			///

>>>>  
	标签
		sql定义字符串变量 include引用
			<sql id="cols">
				id,title,sell_point,price,num,cid,status,created,updated
			</sql>		
			<select id="find2" resultMap="itemRM" parameterType="cn.tedu.jt.pojo.Item">
				select <include refid="cols"></include> from tb_item
			 </select>
	pojo 去掉包路径    参数 返回值
		cn.tedu.jt.pojo.Item    Item
			sqlMapConfig.xml   配置全局别名
				别名 标签放在最前面    
				映射文件xml中的配置 
				所有映射文件中的      用到Item包路径的地方都可以去掉包路径
					<typeAliases>
						<package name="cn.tedu.jt.pojo"/>
					</typeAliases>
>>>> ResultMap
	1.如果数据库表字段(结果集)它和POJO属性名不一致,通过它来做映射
	2.多表查询   在内存中构建一个大的结果集
			表关联: 1:1 1:n n:1 n:n(两个1:n)
			resultmap配置  对一association  对多collection 
		
		约束:
				1)多表联查配置主键 id,需要映射字段result标签(sell_point),同名price可以省略不写
				2)要求:返回大大结果集中不能有同名字段,如果有多个id,取第一个,不会报错(坑)
	3张表
		对多 tb_item_cat 商品分类表 tb_item商品表    一对多
		对一 tb_item  tb_item_desc商品描述表           一对一 

>>>> 实现对多
	1)两张表的查询 inner join,写好SQL,构建大结果集
					
					-- 查询某个分类下是商品信息
					SELECT c.id, c.name,t.id, t.title, t.price
						FROM tb_item_cat c INNER JOIN tb_item t
						ON c.id = t.cid
					
	2)创建java工程:springboot
	3)创建ItemCat.java POJO对象
	4)在映射文件中ItemMapper.xml中添加ResultMapp映射
	5)测试
	
>>>> 实现对一
	SELECT t.id,t.title,t.price,d.item_id,d.item_desc
				FROM tb_item t INNER JOIN tb_item_desc d
				ON t.id = d.item_id
	映射接口xml文件  注意:namespace   多表映射使用resultMap
	创建接口 空方法  注意:返回值 
	pojo对象   主对象与从对象 在主对象中关联
	测试类
	
>>>>>>>>>>>>>
>>>> 小结
1)动态SQL 标签
	if 和java语言判断作用,
			条件成立true,标签中间内容就拼接到sql语句中;条件不成立false,不拼接
	where条件,查询条件变化无穷
	update,修改某几个字段,其它的值不修改
	delete 按某个条件来删除
	where
		如果前面多余一个and或者or,它会干掉,不多余,忽略
	set
		只同于修改,干掉最后多余逗号 set title='123',
	foreach
		用于in子查询,习惯是多个id来删除,
		查询语句:select * from tb_item where id in (1,2,3,4);
		sql+include,在xml中定义变量,多处引用,大量重复值

2)映射ResultMap
	a. 字段和属性不同,通过它来映射
	b. 对象关联
		表关联:一对一,一对多,多对一,多对多(3张表,中间表)
		对象关联:一对一,一对多,多对一,多对多(两个一对多)
			老师和学生多对多(一个老师多个学生:一对多;一个学生可以听多个老师课:一对多)
			mybatis映射关联:不管主体是谁,只关系和它关系,对多,对一(两种关系)
	b1. 对多:collection + ofType
	b2. 对一:association

3)什么时候item(属性property,代表对象实例),什么时候Item(类型,类,首字母大写)
		属性从pojo对象私有属性而来,对象实例名称

4)配置对象关联都是单向关联
	单向关联:
		ItemCat	主
		private List items;	从
		方向:ItemCat > Item
	双向关联:
		ItemCat	主
		private List items;	从
		Item	主
		private ItemCat itemCat;	从
	方向:ItemCat >Item,同时,Item>ItemCat
	
	
>-------------------------项目---------------------------------------------
		jtsmall2
		
		jtsmall3
			pom.xml
			src/main/resources  sqlMapConfig.xml
			src/main/resources  Mappers ItemCatMapper.xml
			src/main/java  cn.tedu.jt.mapper  ItemCatMapper.java 
			src/main/java  cn.tedu.jt.pojo Item.java
			src/main/java  cn.tedu.jt.pojo ItemCat.java
			src/test/java	  test  TestMybatis.java
			
			
			src/main/resources  Mappers ItemMapper.xml
			src/main/java  cn.tedu.jt.mapper  ItemMapper.java 
			src/main/java  cn.tedu.jt.pojo ItemDesc.java
			
# 2021-03-02 ********************************************
### 回顾
>>>> mybatis支持动态SQL
	jdbc实现和数据库操作,自己拼接sql语句(字符串)
		statement,可能会发生特殊字符,造成sql注入。
		preparedStatement,sql分成两个部分,
			select * from tb_item where title like '%诺基亚%'
			第一个部分:select * from tb_item where title like ? (预编译,速度快)
			第二个部分:'%诺基亚%'替换掉?,防止恶意,转码 ''(安全)
	
	
	优点:快捷
	缺点:大量拼接sql字符串;开发者需要专门学习jdbc的api
	Connection、PreparedStatement、Executor。。。
	jdbc原生它无法直接面对大型项目,sql和java代码混杂,后期不易维护,也不是适合大型团队
>>>> jdbc是啥:?????
	
	
	
>>>> mybatis框架
	xml中写sql  调用接口是java代码      
	----把SQL和java代码分开,方便各层开发    无需了解jdbc的api
	
>>>> mybatis缓存
	自身支持缓存框架   一级框架   二级框架    
	jdbc耗费资源:请求数据库
	mybatis缓存:把每次查询缓存起来,  下一次如果sql一致, 直接返回缓存中的数据  缓存放在内存中
	
>>>>  框架的约定 约定大于配置
	分层开发:开发步骤:
	1)全局配置文件sqlMapConfig.xml,
			配置jdbc事务、datasource数据源(4个参数)、加载有哪些xml映射文件
		(*****三大框架整合ssm,核心配置大多被spring接管,
					springboot更加全面接收,配置放在application.yml****2)映射文件mybatis核心,它发明了一套支持xml配置方式
		操作标签:select、insert、update、delete
		动态SQL标签:if、where、set、foreach、sql+include
		
		数据库字段名(数据库的设计规范 sql92:全大写、全小写,多个单词使用下划线隔开)和
		POJO的属下名不一致(java面向对象思想,数据封装model对象中,属性(数据)和方法
			映射:结果集字段和POJO的属性来映射:ResultMap,人工的做一个映射
	3)ResultMap需要两步
		a.定义ResultMap,id标签代表主键,result标签代表普通字段,
			对一:association 声明关联对象
			对多:collection,声明关联对象,搭档,集合标明集合元素类型 ofType
		b.使用ResultMap,给标签的返回值,配置定义resultMap的id值
	4)提倡面向接口开发,一个接口多个实现类,如果实现类新需求改了,程序升级后,程序报错
			约束行为,接口就约束了它的行为。接口中定义方法,参数,返回值 都不能变只能增加
			mysql驱动,oracle驱动,底层实现很多不同,java.sql.*,
	5)mybatis接口方式发展有两个阶段:
			a. 接口假的,它只是利用接口方式调用,最终调用xml映射文件中的配置
						接口并没有实现类,,在xml映射中调用的
			b. 接口+注解(mybatis plus)
		底层实现,使用动态代理技术,动态创建实例,类似反射!
	6)测试类调用 session.getMapper...


>>>>  namespace工作原理
		怎么调用xml映射文件中某个方法呢??????     select id=find
		
		1)给定类的文件ItemMapper.class,可获得类的全路径:cn.tedu.jt.mapper.ItemMapper
		2)namespace=cn.tedu.jt.mapper.ItemMapper
		3)获得类的全路径,mybatis加载时,会把所有xml映射文件解析(找到所有xml映射文件,里面namespace获取)
		还有所有标签select,获取这个标签id,(专门技术:dom4j解析xml文件)
		解析得到:namespace=cn.tedu.jt.mapper.ItemMapper,标签的id,find
		4)最终两个匹配;
		类的全局限定名=namespace
		标签的id=执行接口方法
		反射,invoke回调,执行接口方法(mybatis创建实现类:动态)
		
Test中的  Resources.getResourceAsStream("sqlMapConfig.xml");
找到 解析 sqlMapConfig.xml 文件  包含 < mapper resource="mappers/ItemMapper.xml"/>
找到 解析  ItemMapper.xml  获取标签sleect 获得id=find方法  执行     同时得到namespace

>>>>  多表联查
	一对多而言:一的表称作主表,多的表称作子表,也称作:主从关系
	需求1:一个部门多个员工,部门是主,员工是从
	对象关联关系:在部门表中:private List emps;
	
	需求2:一个员工他所在部门,员工是主,部门是从
	对象关联关系:在员工表中:private Dept dept;
	
	用户只要实现需求1,单向关联;
	用户只要实现需求2,单向关联;
	用户需要实现需求1和需求2,两句话都需要配置,双向关联
  
>>>>  
*********************************************
前端
	H5
	BootStrap
	vue+axios
	
后端
	pom.xml
	application.yml
	
	控制层
		ItemController.java
			@RestController
			@Autowired
	业务层
		ItemService.java
		ItemServiceImpl.java
			@Service
			@Autowired
	持久层
		Item.java pojo
		ItemMapper.xml
		ItemMapper.java
			@Mapper

	RunApp.java
	
MySQL
	tb_item
	
*********************************************
>>>> 链接池
	数据库jdbc,,,每个请求会有一个链接Connection   
	
	作用: 事先创建多个链接  暂存在池中    
				使用时 直接从池中获取 没有新的链接对象
				结束后 关闭对象 还回池中  可以复用
			创建 维护 销毁  交给链接池完成
		
		Hikari  HikariCP    springcloud默认集成链接池
			遵循jdbc  把driver 换成hakari配置
>>>> application.yml  springboot配置
	把sqlMapConfig.xml文件配置  放在   application.yml中
	
	1.有层次 每个层次前面有两个空格
	2.结构   key:value   value前面有一个空格
	3.中间不能掺杂注释
*******************-文件内容-*******************
tomcat 端口
server:
  port: 8060
------------
数据库链接配置 参数 hikari  数据库厂家驱动  jdbc数据库链接  
spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3307/jtdb-small?characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: root
    password: root
------------
mybatis框架配置   替代sqlMapConfig.xml
	配置pojo包路径 
	指定映射路径   springboot中resources不存在的  .class文件在classpath
						java编译后文件在bin目录下
						maven编译后 xml文件在 target中classes main的  test-classes
mybatis:
  typeAliasesPackage: cn.tedu.ssm.pojo
  mapperLocations: classpath:mappers/.xml
  下划线和驼峰规则 自动映射    无需ResultMap
  configuration:
    map-underscore-to-camel-case: true
------------
打印sql语句  日志信息 log4j
logging:
  level:
    cn.tedu.ssm.mapper: debug
----------------------------*******************----------------------------
>>>> 错误
400  类型转换错误
404  页面找不到.  url  @RequestMapping("/item/list")
500  含糊其辞,内部转换错误,代码是否正确


>>>>  前台请求后台  跨域问题
	前台8848
	后台8060
	浏览器输入请求:ajax(axsio)不能从8848去请求8060,只能请求自己的端口
	在ItemController.java中@RestController@CrossOrigin(origins = "*")
	
	javascript规定,它不允许跨域,为了安全 CORS policy: No 'Access-Control-Allow-Origin
>>>> ${num}和#{num}有什么不同?

内容拼接到sql语句,sql注入,字符串类型,整数是不会有注入的问题
mybatis提供内容拼接到sql语句,sql注入,字符串类型,整数是不会有注入的问题
mybatis提供就可以使用,只是使用,字符串类型时,有注入风险!不是用户输入的就没有注入风险!
${num}
两部分:
第一部分:"SELECT * FROM tb_item LIMIT "
第二部分:${num}这个部分就被替代1
两个字符串拼接:"SELECT * FROM tb_item LIMIT "+1
Preparing: SELECT * FROM tb_item LIMIT 1

 -# 内部走的?占位符preparedStatement方式,替换?占位符
Preparing: SELECT * FROM tb_item LIMIT ?	预编译,性能高
Parameters: 1(Integer)
两部分:
第一部分:SELECT * FROM tb_item LIMIT ?
第二部分:参数值1
把第一分部问号?替换成1
SELECT * FROM tb_item LIMIT 1



>>>>>  前台架构
	html页面,创建vue对象,发起ajax(axios),在console.log结构打印出来
	
	method定义方法:直接调用
	mounted定义方法:加载完dom树,才调用这个,jQuery.Ready(){}
	调用时机不同
	
				mounted() {			自定义方法就放在mouted放在中
					axios({				axios封装ajax,本质ajax
						method: "post",		以post方式发起请求
						url: "http://localhost:8070/item/list?num=3"
					})
					.then(				请求之后响应处理方法,返回对象封装response(res)
						res => {		数据:res.data属性 json字符串
							console.log( res.data )
						}
					)
				}
>>>> 页面请求的方式:

HTTP协议规定:http://
GET:url参数可以看到,提交参数少url最大长度限制:256512,不安全
POST:url参数看不到,8k=1024*7,安全,提倡

RESTFul ,请求形式,和get请求结构很相似(get请求)
http://localhost:8070/item/list?num=10	(get请求传参形式)
http://localhost:8070/item/list/10/标题/卖点	安全,数据量get形成多些

		除了页面url形式不同,后台controller接收参数地方也要修改
		
		@RequestMapping("/item/list")
		1)一个参数
		@RequestMapping("/item/list/{num}")
		public List list(@PathVariable Integer num)
			http://localhost:8060/item/list/5
		2)多个参数
		@RequestMapping("/item/list/{num}/{title}")
		public List list(@PathVariable Integer num, @PathVariable String title)
		3)对象参数
		@RequestMapping("/item/list/{num}/{title}/{sellPoint}/{num}")
		public List list(Item item);
		
		RESTFul参数少,使用它,参数多,使用post传参!



## 小结:

1)数据库,面向SQL题,面试前抱佛脚。看到SQL题目,直接写出SQL语句
2)前端,h5/css/js/jQuery不用去看,看Vue+element,最后整合,照着抄,但是明白每句意思,熟练敲代码
3)三大框架,应用(必须掌握,ssm整合的代码敲熟练),底层源码(了解)

>>>>>>>>
	后端整合:ssm+springboot构建项目
	前端整合:h5+css3+bootstrap+vue+axios(ajax)

--------项目----------------------------------------------------
ssm20210302  
	pom.xml
		web mybatis  mysql
	application.yml					src/main/resources
	Item.java							src/main/java     cn.tedu.ssm.pojo
	ItemMapper.xml
	ItemMapper.java
	ItemService.java
	ItemServiceImpl.java
	ItemController.java
	RunApp.java
	
	
	```
	

你可能感兴趣的:(note)