# Java学习笔记 **Repository Path**: ni-zewen/java-learning-notes ## Basic Information - **Project Name**: Java学习笔记 - **Description**: javaWeb-spring-Mybatis-springMVC-springboot的部分学习笔记 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-08-25 - **Last Updated**: 2021-08-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Java学习笔记 #### Description javaWeb-spring-Mybatis-springMVC-springboot的部分学习笔记 ### Ⅰ.javaWeb ### Ⅱ.spring ### Ⅲ.Mybatis ### Ⅳ.springMVC ### Ⅴ.springboot ### Ⅰ.javaWeb部分 ##### 方法不懂怎么用直接敲进去看源码,在structure中可以看到相关的方法使用与参数要求 - tomcat - severlet/jsp - JDBC/mysql - Javase - Ajax - b站:https://www.bilibili.com/video/BV12J411M7Sj?p=3 ## 一,基础 ### 1. tomcat 1.1 目录下各个文件的含义: > bin 启动,关闭的脚本文件 > conf 配置 > lib 依赖的jar包 > logs 日志 > webapps 放网站的 1.2 > 启动关闭如下(.sh为shell脚本,.bat为批处理脚本,在windows和dos中) ![avatar](./1.png) 访问测试为:localhost:8080->127.0.0.1 > 此处出现问题:Java环境未配置 conf目录下的核心配置文件:serve.xml 可以配置启动的端口号 ![avatar](./2.png) *或者在cmd中输入 catalina run* 1.4 ![avatar](./4.png) 1.5 conf下的serve.xml为服务器核心配置文件 ```xml ``` connect标签可以改变访问的端口 ```xml ``` host标签可以配置的主机名 默认主机:localhost->127.0.0.1 默认网站的存放位位置:webapps 1.6 环境变量配置之后可以使用cmd访问 ### 2. Http 2.1 HTTP(超文本传输协议)是一个简单的请求-响应协议,通常运行在TCP之上 - 文本:html,字符串... - 超文本:图片,音乐,视频,定位... - 80端口 - https:安全的443端口 2.2 ![avatar](./3.png) **DNS服务器是域名管理器,全世界的域名都在这里管理** 2.3 - Http请求 客户端--发请求(Request)--服务器 ```json Request URL: https://www.baidu.com/ Request Method: GET //get/post Status Code: 200 OK //状态码 Remote Address: 112.80.248.75:443 Referrer Policy: unsafe-url ``` - Http响应 服务器--响应--客户端 ```json Cache-Control: private //缓存控制 Connection: keep-alive //连接 Content-Encoding: gzip //编码类型 Content-Type: text/html;charset=utf-8 //类型 ``` - 消息头 ```json Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng, Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 //告诉浏览器其语言环境 Cache-Control: max-age=0 Connection: keep-alive //连接状态 Cookie: ``` - **请求行** get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效 post:请求能够携带的参数比较多,没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效 **消息头** ### 3. 发布一个网站 - 将自己写的网站放到服务器(Tomcat)中指定的web应用文件夹(webapps)下,就可以访问了 - 比如 http://localhost:8080/%E6%A8%A1%E4%BB%BF%E5%8F%91/ ### 4.总项目下的pom.xml文件是maven配置的核心文件,在maven的主工程中 ```xml learn.Javaweb2 javaweb2 1.0-SNAPSHOT war ``` - 项目的打包方式包括:war:javaweb应用/jar:java应用 - maven的高级之处在于,他能自动帮助导入jar包使用的其他jar包 (如使用初始的javaweb包,会自动帮助导入tomcat之类) - 关于maven父子工程的理解 父项目中的Java包子项目中可以直接使用(多态) ## 二,servelet ### 1. servelet简介 - servelet是sun公司开发动态web的一门技术,一个war一个servelet - sun在这些API中提供一个接口叫做Servelet,只要俩个步骤 - 编写一个类实现servelet接口 - 把开发好类部署到服务器上 ### 2. Servelet接口Sun公司有俩个默认的实现接口类:HttpServlet和 - 构建一个普通的maven项目,在主文件中添加servelet依赖,接着添加子项目,在子项目中添加web依赖 - 在创建servelet工程时可以直接使用maven包 ```xml javax.servlet javax.servlet-api 4.0.1 ``` ```java package javaweb.servelet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class servelet extends HttpServlet { //由于get和post只是请求实现的不同方式,所以可以相互调用,业务逻辑一样 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); //Ctrl+enter 自动声明类快捷键 响应流 writer.print("Hello,Servelet"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } } ``` - 编写serlet的映射 *疑问:什么是映射* 因为我们写的Java程序需要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务器中注册我们写的servelet,还需要给它一个楼浏览器能访问的路径 ```xml hello javaweb.servelet.servelet hello hello ``` - 配置tomcat - 启动测试 **生成的war包就是网站???** 不能部署源码,需要部署war包 - **在启动测试出现奇怪的错误,IDEA启动Tomcat时报Artifact xxx:war exploded: Error during artifact deploy->java.lang.IllegalStateException: Error starting child->无法找到页面->在生成的target目录下无法找到servelet-mapping,不知道为什么->1.可能是新版本的注释与servelet书写冲突2.url-pattern /hsello /url-pattern 路径映射要加‘/’!!!** ![avatar](./5.png) - servelet原理 Servelet是由web服务器调用,web服务器在收到浏览器请求之后,会 ![avatar](./6.png) *web容器如tomcat,读取响应的信息* *我们自己编写的实现类继承Servelet,重写这些方法,接受并请求处理,给出相应的信息* - 一个servelet可以指定多个mapping路径 多个servelet可以指定统配路径(见一),可以指定后缀(见二) index.jsp是默认请求路径 ```xml /hello/**.do 二 ``` ### 3.ServeletContext对象 web容器在启动是,为每个web程序创建一个serveletcontext对象,其代表当前的web应用 - 共享数据(见servelet-02) - 设置一些初始话参数(键值对,xml) ```xml getP jdbc:mysql//local:3306:mybatis ``` ```java ServletContext servletContext = this.getServletContext(); String url = servletContext.getInitParameter("url"); //键值对 resp.getWriter().print(url); ``` - 请求转发(serveletDemo04) ![avatar](/javaweb/7.png) *上侧为请求转发,url不变;下侧为重定向,url改变* - 读取资源文件 Properties(见serveletDemo05) - 在java目录下新建properties - 在resourses目录下新建properties 发现都被打包到了同一个目录下:classes,我们俗称其为类路径:classpath 需要一个文件流来读取 ### 4.HttpServletResponse web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServeletRequest对象,一个代表响应的HttpServeletResponse - 要获取客户端请求参数:Request - 要给客户端响应信息:Response 1.简单分类 负责向浏览器发送数据的方法 ```java ServletOutputStream getOutputStream() throws IOException; //中文 PrintWriter getWriter() throws IOException; //一般的数据流 ``` 负责向浏览器发送响应头的方法 ```java void setCharacterEncoding(String var1); void setContentLength(int var1); void setContentType(String var1); void setBufferSize(int var1); void setIntHeader(String var1, int var2); void addIntHeader(String var1, int var2); void setStatus(int var1); /** @deprecated */ void setStatus(int var1, String var2); ``` 2.常用功能 - 向浏览器输出消息 - 下载文件(见response) - 获取下载路径 - 下载文件名 ```java realPath.substring(realPath.lastIndexOf("\\")+1); //C中定义了一些字母前加"\"来表示常见的那些不能显示的ASCII字符,如\0,\t,\n等,就称为转义字符 ``` - 设置想办法能让浏览器能够支持下载我们需要的东西 ```Content-Disposition就是当用户想把请求所得的内容存为一个文件的时候提供一个默认的文件名``` - 获取输入流 - 创建缓冲区 - 获取outputstream对象 - 将fileoutputstream流写入缓冲区 ```read(buffer) 将输入流中读取一定数量 并将其存储在缓冲区数组 b 中``` - 使用outputstream缓冲区的数据输出到客户端 - 验证码 - 实现重定向 一个web资源收到客户端请求后,其会通知客户端去访问另外一个web资源,这个过程就叫做重定向 ```java void sendRedirect(String var1) throws IOException; ``` - 常见于用户登陆 - 重定向和转发的区别:请求转发是url不会产生变化,在重定向时会产生变化 ### 5.HttpServletRequest - 获取前端的参数 ![avatar](/javaweb/8.png) - 重定向 ### 6.Cookie,Session(见cookie,session) 服务端给客户端一个信件,客户端下次访问服务端时带上信件就可以了(cookie) 服务端登记你来过了,下次你来的时候我匹配你(session) 1. **会话** 用户打开一个浏览器,点击了很多超链接,访问了多个web资源,关闭浏览器,此次过程称之为会话 - 有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学来过,称为有状态会话 2. **cookie** 是一种客户端技术(请求,响应) - 从请求中拿到一个cookie - 服务器响应给cookie - 一般保存在本地user目录下 一个网站cookie的一些细节 - 一个cookie只能保存一个信息(key-value) - 一个web站点可以给浏览器发送多个cookie,最多存放20个 - cookie大小有限制4kb - 300个cookie是浏览器的上限 删除cookie - 设置响应时间为0 max-age 3. **(重点)session** 是一种服务器技术,利用这个技术,可以保存用户的会话信息,我们可以把信息或者数据放在session中 *查看cookie* ![avatar](/javaweb/9.png) 什么时session - 服务器会给每个用户(浏览器)分配一个session对象 - 一个session独占一个浏览器,只要浏览器没有关闭,这个session就存在 - 用户登陆之后,整个网站它都可以访问!->保存用户信息,购物车信息...... ![avatar](/javaweb/10.png) 4. session和cookie的区别 - cookie是把用户的数据写给用户的浏览器,浏览器保存 - session是 把用户的数据写到用户独占的session中,服务器端保存 - session对象由服务创建 5. 使用场景: - 保存一个登陆用户的信息 - 购物车信息 - 在整个网站中经常会使用的数据,我们将它保存在session中 ![avatar](/javaweb/11.png) **会话自动过期可以在web.xml中配置,手动注销使用session.invaliad** ## 三,JSP(java serve page:java服务器端界面) ### 1.HTML和jsp的区别 HTML只给用户提供静态的数据,jsp页面中可以嵌入java代码,为用户提供动态数据 ### 2.jsp的原理 - 服务器内部工作 tomcat中有work目录,IDEA中也有 - 浏览器向服务器端发送请求,最后都是servelet - jsp最后也会被转换成一个Java类 - jsp继承自servelet,本质就是servelet,web容器(tomcat)会将jsp转换成java文件 ![avatar](/javaweb/12.png) ```linux jsp转化成的java目录 C:\Users\admin\AppData\Local\JetBrains\IntelliJIdea2021.1\tomcat\2e8f8eab-8ed5-418b-8500-bcc157cea9e4\work\Catalina\localhost\cookie_session_war\org\apache\jsp ``` 1. 判断请求, 2. 内置对象 ![avatar](/javaweb/13.png) 3. 输出页面前设置的代码 ![avatar](/javaweb/14.png) 4. 以上这些对象可以在jsp页面中直接使用 java原封不懂的输出 html转化为输出流 ```java out.write("\n"); out.write("\n"); out.write("

Hello World!

\n"); out.write("\n"); out.write("\n"); ``` ![avatar](/javaweb/15.png) ### 3.JSP基础语法 ```java <%= new java.util.Date()%> //jsp表达式,显示数据 ``` ```java <%@ page contentType="text/html;charset=UTF-8" language="java" %> //声明 ``` ```java <% //jsp脚本 int sum=0; for (int i = 0;i<100;i++) sum+=i; out.println("

sum = " + sum + "

"); %> ``` ```java ${sessionScope} //EL表达式,在页面中获取变量的值,判断,简单计算 ``` ```java <%@ page contentType="text/html;charset=UTF-8" language="java" %> //jsp指令,设置内置对象属性 <%@ 指令 属性1=" 值 " ……属性n =" 值 " %> //page指令:用于设定JSP页面的全局属性和相关功能 //include指令:用于将特定位置上的资源包含到当前的JSP文件中 //taglib指令:用于定义一个标签库及标签库的前缀 ``` ```java <@! int i; //jsp声明 @> ``` ### 4.九大内置对象及其作用域 - PageContext 存东西 - Ruquest 存东西(新闻) - Response - Session 存东西(购物车) - Application(ServeletContext) 存东西(聊天记录) - config (ServeletConfig) - out 输出到界面 - page 不用 - exception **Scope:page->request->session->application** ```java <% //Scope设置作用域 //保存的数据只在一个界面中有效 pageContext.setAttribute(); //保存的数据只在一次请求中有效,请求转发会携带这个数据 request.setAttribute(); //保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器 session.setAttribute(); //保存的数据只在服务器有效,从打开服务器到关闭服务器 application.setAttribute("name","hello",PageContext.SessionScope); //从pageContext中取出 pageContext.findAttribute("name"); %> ``` ### 5.jsp标签,JSTL表达式,EL表达式(参考vue语法) https://www.runoob.com/jsp/jsp-jstl.html jsp标签是为了弥补HTML标签的不足 ### 6.javaBean 实体类,一般用来做数据库的映射 ORM - 表-->类 - 字段-->属性 - 行记录-->对象 符合下列条件为javaBean: - 有一个无参的构造 - 属性必须私有化 - 必须有特定的get/set方法 ## 四,MVC架构 Model,View,Controller ### 1. 早期 ![avatar](/javaweb/16.png) 用户直接访问控制层,控制层就可以操作数据库 >servelet---crud-->数据库 弊端:程序十分臃肿耦合度高,不利于维护,servevelt的代码中有:处理请求,视图,JDBC..... 架构:没有什么是在架构中加一层解决不了的 ### 2. 现在 ![avatar](/javaweb/17.png) Model - 业务处理 - 数据持久层 View - 展示数据 - 提供链接发起Servelet请求 Control - 接受用户的请求 - 交给业务层处理对应的代码 - 控制视图的跳转 >*例如* 登陆-->接受用户的登陆请求-->处理用户的请求 -->交给业务层处理-->Dao层查询用户名和密码是否正确-->数据库 ### 3. Filter 过滤器 ![avatar](/javaweb/18.png) 用来过滤网站的数据 - 处理中文的乱码 Filter开发步骤: - 导包 - 编写过滤器,实现接口(javax.servlet) ```java /* 1.过滤中的所有代码,在过滤特定的请求时都会执行 2.必须要让过滤器继续执行(向下转交,使用Chain,固定格式) */ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletRequest.setCharacterEncoding("utf-8"); servletResponse.setCharacterEncoding("utf-8"); servletResponse.setContentType("text/html,charset=UTF-8"); System.out.println("Filter执行前"); filterChain.doFilter(servletRequest,servletResponse); //让我们的请求继续走,如果不写,我们的程序到这里就停止了 System.out.println("Filter执行后"); } @Override //过滤器实现权限拦截,在注销用户后自动跳转页面 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest Request = (HttpServletRequest) servletRequest; HttpServletResponse Response = (HttpServletResponse) servletResponse; if(Request.getSession().getAttribute("USER_ID")==null){ Response.sendRedirect("/error.jsp"); } filterChain.doFilter(servletRequest,servletResponse); } ``` - 在web.xml中添加映射 ```xml CharacterF com.Ni.Filter.CharacterEncodeing CharacterF /servlet/* ``` ### 4.监听器 ```java //监听在线人数,实际上就是监听有多少个session public class OnlineListner implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent httpSessionEvent) { ServletContext servletContext = httpSessionEvent.getSession().getServletContext(); Integer onlineCount =(Integer) servletContext.getAttribute("onlineCount"); if(onlineCount == null) onlineCount = new Integer(1); else { int count = onlineCount.intValue(); onlineCount = new Integer(count+1); } servletContext.setAttribute("onlineCount",onlineCount); } ``` ### 5.JDBC ### 6.Junit单元测试 简单使用 @test只在方法上有效,只要加了这个注解的类,就可以直接运行 ## 五,项目实战,smbms(略) https://blog.csdn.net/clisks/article/details/101362850 >- tomcat--No artifacts configured 访问一个网站,需要指定一个文件夹名字 >- 访问servelet页面出现405错误,删除super.get/post(因为若继承自默认接口的servelet为空,用别人的才要继承) >- 页面根路径${pageContext.request.contextPath} 取绝对路劲 >- //解决中文乱码 req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); resp.setContentType("html/text;charset=utf-8"); >- cookie保存中文key名时会出现问题 //传输字符串时出现乱码问题 编码 String string = URLEncoder.encode("你好呀","utf-8") 解码 URLDecoder.decode(string,"utf-8") >- POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称。 >- **JVM的双亲委派机制??????** >- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 此处在服务器(tomcat端未引入,需要导入包到tomcat的bin) >- **在监听器实现用户数检测的时候,servletContext是哪一层???** >- 频繁的创建session是非常消耗资源的,可以在session中新建键值对 session,cookie,servletContext都类似json,键值对集合 >- maven过滤器:target文件目录下路径问题 ```xml src/main/resources **/*.properties **/*.xml true src/main/java **/*.properties **/*.xml true ``` ### Ⅱ.spring部分 >##### 前面有一些在平板上,截止到狂神说P2 #Fir IOC ## 一,Spring ........平板平板直到 ```xml org.springframework spring-webmvc 5.2.0.RELEASE ``` ### 4. 拓展 - springboot - 一个快速开发的脚手架 - 基于srpingboot可以快速开发单个的微服务 - 约定大与配置 - 基础是spring和springMVC - springcloud - 基于springcloud实现 ### 5. 弊端 发展了太久之后,配置十分繁琐,人称配置地狱 ## 二,IOC ### 1. 理论推导 在我们之前的业务中,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求去修改源代码。如果程序代码量十分大,修改一次的代价十分昂贵。 ### 2. **控制接口** 我们使用一个set接口实现,已经发生了革命性的变化 ```java private UserDao userDao; //利用set动态创建 public void setUserDao(UserDao userDao){ this.userDao = userDao; } ``` - 之前程序主动创建对象,控制权在程序员手上 - 使用了set注入后,程序不再具有主动性,而是变成了被动的接受对象 - DI(依赖注入)是实现IOC的方式 这种思想,从本质上解决了问题,不用再去管理对象的创建了,系统的耦合性大大降低,可以更加专注在业务的实现上,此即IOC的原型 ```xml ``` 到了现在 , 我们彻底不用再程序中去改动了 , 要实现不同的操作 , 只需要在xml配置文件中进行修改 , 所谓的IoC,一句话搞定 : 对象由Spring 来创建 , 管理 , 装配 ! **控制反转是一种通过描述(XML或者注释)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IOC容器,实现方式是DI** ### 3. IOC创建类 - 使用无参构造创建对象,默认 (当只设置property时) - 假设我们使用有参对象构造 - 使用下标 - 使用参数类型 - 使用参数名(最常用) - 当ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("beans.xml")时,bean中的所有配置都会被加载 ```xml ``` ### 4.Bean的配置 ```java ``` ### 5.import 这个import一般用于团队开发,它可以导入多个配置文件,导入合并为一个 假设现在项目有多个人开发,这三个人复制不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import将所有的beans合并为一个总的 ## 三,依赖注入 ### 1.构造器注入(前面已经说了) ### 2.**Set方式注入**【重点】(Spring04) - 依赖注入:Set注入 - 依赖:bean对象的创建依赖于容器 - 注入:bean对象中的所有属性由容器来注入 - 环境搭建 - 复杂类型 - 真实测试对象 ### 3.拓展防暑注入 ### 4.p,c命名空间(略)(类似于vue的语法糖) xmlns:p="http://www.springframework.org/schema/bean" ## 四,bean的作用域 ![avator](./1.png) - 单例模式(Spring默认机制) scope="singleton" - 原型模式:每次从容器中get的时候,都会产生一个新对象!(多线程) - 其余的request,session,application,这些只能在外部开发中使用 ## 五,Bean的自动装配 ### 1. xml实现 - 自动装配是Spring满足bean依赖的一种方式 - Spring会在上下文自动寻找,并自动的给Bean装配属性 在Spring中有三种装配的方式 1. 在xml中显示的配置 2. 在java中显示的配置 3. 隐式的自动装配bean【**重要**】 自动装配 beans.xml的上下文中的属性值 - byname 需要保证所有bean的值唯一,且这个bean要和自动注入属性的set方法名一致(id) - bytype 需要保证所有bean的class唯一,且这个bean要和自动注入的属性的类型一致(类似构造器注入的type,一个类型注入一个) ```xml ``` ### 2. 使用注解实现自动装配 - 导入约束 context约束 - 配置注解支持 ```xml ``` ### 3. @Autowired 优先按类型,找不到就按name (@resourse也可) 在属性或者set方式上使用 使用Autowired就不用编写set方法了,前提是自动装配的属性在IOC(Spring)容器中存在,且符合bytype ```java @Autowired private Cat cat; ``` @Nullable @Autowired(required = false) 注解表示这个字段可以为空 ```java public void setName(@Nullable String name) { this.name = name; } ``` @Qualifier(value = "dog222") 当有多个相同类型的取特定id的那个 **注释要放在对应的set方法上方** ```java @Autowired @Qualifier(value = "dog221") public void setDog(Dog dog) { this.dog = dog; } ``` 小结 @resourse和@autowired区别 - 都是用来自动装配,放在属性字段上 - 前者是byname - 后者是bytype ## 六,使用注解开发 spring4之后,要使用注释开发,要导入 AOP的包 ### 1. bean @component,说明此类被spring接管,即为bean @Value(""),注入属性 ```java //等价于 // @Component public class user { public String name = "小倪"; } ``` ### 2.属性如何注入 ```java //相当于 @Value("小倪") public String name; ``` ### 3. 衍生的注解 - service层--> @Service - dao层--> @Repository - control层(servlet)--> @Controller - pojo层 --> @component 这四个注解功能相同,代表将某个类注册到spring容器中装配bean; ### 4. 自动装配注解 上面讲了 ### 5.作用域 @Scope() ### 6. xml与注解 - xml更加万能 - 注解不是自己的类用不了,维护相对复杂 - 一般:xml用来管理bean,注解只负责属性的注入 - 我们在使用的过程中,只要注意一个问题:必须让注解生效,需要开启注解的支持 ## 七,使用java的方式配置spring 用springconfig代替xml配置 Spring的一个子项目,spring4之后成为核心功能 ```java package com.Ni.config; import com.Ni.pojo.user; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @Configuration //这个也会被spring容器托管,因为它本身也是一个componenet,相当于bean.xml的注解 @ComponentScan("com.Ni.pojo") @Import(Niconfig2.class) //引入其他的容器 public class Niconfig { @Bean //注册一个bean,就相当于之前写的一个bean标签 // 这个方法的名字就相当于bean标签中的id属性 //这个方法的返回值,就相当与bean标签中的class属性 public user getUser(){ return new user(); //返回要注入到bean中的对象 } } //配置类中 import com.Ni.config.Niconfig; import com.Ni.pojo.user; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Mytest{ public static void main(String[] args){ //如果完全使用了配置方式去实现,那么我们只能通过 AnnocationConfig来获取容器上下文,通过配置类的class加载 AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Niconfig.class); user us = (user) annotationConfigApplicationContext.getBean("getUser"); System.out.println(us.getName()); } } ``` #Se AOP ### 八,代理模式 SpringAOP的底层!【**springAOP和springMVC**】 - 静态代理 - 动态代理 #### 1 静态代理(Spring-08-proxy) - 抽象角色:一般会使用接口或者抽象类来实现 - 真实角色:被代理的角色 - 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作 - 客户:访问代理对象的人 ![avator](2.png) ##### 1.1 代理模式的好处 - 可以使真实角色的操作更加纯粹,不用关注公共的业务 - 公共的业务交给代理角色,实现业务的分工 - 公共业务发生拓展的时候,利于修改,减低了耦合度 ![avator](3.png) ##### 1.2 缺点 - 一个真实角色产生一个代理角色,代码量会翻倍 #### 2 **动态代理**【???】 - 动态代理角色和静态代理角色一样 - 动态代理的代理类是动态生成的,不是我们直接写的 - 分为俩大类:基于接口的动态代理和基于类的动态代理 - 基于接口 --- JDK 动态代理【此节实现】 - 基于类 --- cglib - java字节码 Javassist - Proxy(代理)和InvocationHandle(调用处理程序) #### 3 AOP是什么 - AOP意为面向切面编程,通过预编译的方式和运行期间动态代理实现程序的同意维护的一种技术 ![avator](4.png) - AOP在spring中的作用 : 提供声明式事务,允许用户自定义参数 ![avator](5.png) #### 4. 使用spring实现AOP ```xml org.aspectj org.eclipse.jdt.core 1.9.7.M2 ``` - 使用spring的API接口(**报错,不知道为什么,spring-09**) - **解决** execution(* com.NI.service.UserServeImpl..*.*(..)) ```xml ``` ![avator](6.png) - 自定义类 - >- xml约束就是在特定应用下,为xml编写的一下语法,用来检测这个应用下的xml文件是否正确。 >- 在改名时直接改动project,不能rename module,会出现混乱 >- 代码原则之:尽量不改变原来的代码 >- 动态代理有些不懂,invoke怎么用,proxy.rent和invoke的关系 >- spring-09 AOP报错 解决 execution(* com.NI.service.UserServeImpl..*.*(..)) 不知道什么意思 ### Ⅲ.mybatis部分 ##### Spring SpringMVC Mybatis ## 一.简介 ... ## 二.如何使用 - 配置文件 ```xml ``` - 编写mybatis工具类 ![avator](1.png) ```java private static SqlSessionFactory sqlSessionFactory; static { //使用mybatis第一步:获取sqlSessionFactory对象 try { String resource = "mybatis-config.xml"; InputStream resourceAsStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); } catch (IOException e) { e.printStackTrace(); } } //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。 //SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。 public static SqlSession getSqlSession(){ SqlSession sqlSession = sqlSessionFactory.openSession(); return sqlSession; } ``` *类似于原来的getConnection,然后statement* - 编写代码 - pojo类 - Dao层 - 接口实现类由原来的impl转换为一个Mapper配置文件 ```xml ``` 出现问题,核心配置文件下resource路径难以找到 ```xml ``` ## 三,测试 ### CRUD #### 1.namespace namespace中的包名要和Dao/mapper接口中的包名一致 #### 2.增删改查 选择,查询语句 - id:就是对应的namespace中的方法名 - resultType:返回的参数类型 - parameterType:传入的参数类型 #### 4.万能map 当传入的参数较多时,考虑使用map ```java public void addUser2(){ SqlSession sSession = mybatisUtils.getSqlSession(); UserDao mapper = sSession.getMapper(UserDao.class); HashMap map = new HashMap(); map.put("Uid","55"); map.put("Uname","Hello"); map.put("Uword","222"); String add = mapper.addUser2(map); System.out.println(add); //提交事务 sSession.close(); } ``` - Map中传递参数值,直接在sql取出key即可 - 对象传递参数,直接在sql中取对象的属性即可 - 只有一个基本参数类型的情况下,可以直接在sql取;多个属性时使用注释或者map #### 5.模糊查询 select * from mybatis.user where name like #{value} (String value = %李%) - java代码执行时,传递通配符%% - 在sql语句中使用通配符 ## 四,使用注解开发 - 面向接口编程 根本原因:解耦,可拓展,提高复用,分层开发,遵守共同的规则使得开发变得容易,规范性更好 - ## 五,数据库连接池 >- SID是System IDentifier的缩写,而ORACLE_SID就是Oracle System Identifier的缩写,在Oracle系统中,ORACLE_SID以环境变量的形式出现,在特定版本的Oracle软件安装(也就是ORACLE_HOME)下,当Oracle实例启动时,操作系统上fork的进程必须通过这个SID将实例与其他实例区分开来,这就是SID的作用。 >- 每个mapper实际上是一个实现类,每个mapper都需要在mybatis核心配置文件下注册,Dao层的xml文件实际上是实现类,test是把静态的类变成动态的,按某种顺序串在一起 >- maven资源过滤问题 文件路径在生成的target目录下 见javaweb问题 >- DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; >- org.xml.sax.SAXParseException; lineNumber: 5; columnNumber: 18; 1 字节的 UTF-8 序列的字节 1 无效。 -->?xml version="1.0" encoding="UTF8"? >- *Unsupported character encoding 'utf8;'*不支持分号 >- mysql57的配置文件:在programdata下 当出现错误 >com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure 需要在my.ini配置文件下将最大待机时间改为一年(默认8小时,无操作数据库禁止Java应用池访问) >- 提交事务 所有增删改的操作需要提交事务 mysql57已经开启自动提交 >- mybatis增加数据时的返回值???Integer.MIN_VALUE + 1001?? >- 变量替换后,#{} 对应的变量自动加上单引号 '' 变量替换后,${} 对应的变量不会加上单引号 '' ### Ⅳ,Ⅴ略,见博客或个人网站