1.Spring
(1)什么是spring?
-
一个轻量级Java开发框架,目的是为了解决企业级应用开发 的业务逻辑层和其他各层的耦合问题.
-
两个核心特性,也就是依赖注入(dependency injection,DI)和面向切面编程(aspect- oriented programming,AOP)
(2)IOC(控制翻转)
- Inversion of control(控制反转): 是一种面向对象的编程思想。就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这 些对象的整个生命周期。
- Dependency Injection(依赖注入): 是IOC思想的实现方式。即组件之间的依赖关系由容器在应用系统运行期来决定,也就是 由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。
- IOC container:本质上是一个工厂。 提供了控制反转功能,用来把应用的配置和依赖从真正的应用 代码中分离
- 优点:
- 举个例子:
(3)Bean类
-
Spring 应用程序有哪些不同组件:
-
接口 - 定义功能。
-
Bean 类 - 它包含属性,setter 和 getter 方法,函数等。
-
Bean 配置文件 - 包含类的信息以及如何配置它们。
-
Spring 面向切面编程(AOP) - 提供面向切面编程的功能。
-
用户程序 - 它使用接口。
-
-
什么是 Spring beans:Spring beans 是那些形成 Spring 应用的主干的 java 对象(各种类 dao,controller,service)。它们被 Spring IOC 容 器初始化,装配,和管理。Spring 框架定义的beans都是单件beans。在beantag中有个属性”singleton”。
-
如何给 Spring 容器提供配置元数据:XML 配置文件、基于注解的配置、 基于 java 的配置。
-
Spring 框架中的单例 bean 是线程安全的吗:不是
-
什么是 bean 装配:指在 Spring 容器中把 bean 组装到一起,前提是容器需要知 道 bean 的依赖关系
(4)Spring 注解
-
@Component:这将 java 类标记为 bean。它是任何 Spring 管理组件的通用构造型。spring 的 组件扫描机制现在可以将其拾取并将其拉入应用程序环境中。
-
@Controller:该注解表明该类扮演控制器的角色.
-
@Service:该注解表明该类扮演业务处理的角色
-
@Repository:该注解表明该类扮演连通数据库的角色
-
@Required :这个注解表明 bean 的属性必须在配置的时候设置,通过一个 bean 定义的显式的属 性值或通过自动装配,若@Required 注解的 bean 属性未被设置,容器将抛出 BeanInitializationException。
-
@Autowired :即自动装配 默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它 required属性为false)。@Autowired 注解提供了更细粒度的控制,包括在何处以及如何完成自 动装配。它的用法和@Required一样,修饰setter方法、构造器、属性或者具有任意名称和/或多 个参数的PN方法。
-
@Qualifier :
当您创建多个相同类型的 bean 并希望仅使用属性装配其中一个 bean 时,您可以使用@Qualifier注解和 @Autowired 通过指定应该装配哪个确切的 bean 来消除歧义。
-
@RequestMapping : 用于将特定 HTTP 请求方法映射到将处理相应请求的控制器中的特定类/ 方法。此注释可应用于两个级别:
类级别:映射请求的 URL
方法级别:映射 URL 以及 HTTP 请求方法
(5)简单调用过程
2.Spring MVC
1.HTTP
(1)什么是HTTP
“超文本传输协议”,是一种应用非常广泛的 应用层协议
(2)工作过程
- 客户端建立一条 TCP 连接(如果传输层不是 TCP,也可以是其他适合的连接)。
- 客户端发送请求并等待应答。
- 服务器处理请求并送回应答,回应包括一个状态码和对应的数据。
(3)HTTP流
当客户端想要和服务端进行信息交互时(服务端是指最终服务器,或者是一个中间代理),过程表现为下面几步:
- 打开一个 TCP 连接:TCP 连接被用来发送一条或多条请求,以及接受响应消息。客户端可能打开一条新的连接,或重用一个已经存在的连接,或者也可能开几个新的 TCP 连接连向服务端。
- 发送一个 HTTP 报文:HTTP 报文(在 HTTP/2 之前)是语义可读的。在 HTTP/2 中,这些简单的消息被封装在了帧中,这使得报文不能被直接读取,但是原理仍是相同的。
- 读取服务端返回的报文信息:
- 关闭连接或者为后续请求重用连接。
当 HTTP 流水线启动时,后续请求都可以不用等待第一个请求的成功响应就被发送。然而 HTTP 流水线已被证明很难在现有的网络中实现,因为现有网络中有很多老旧的软件与现代版本的软件共存。因此,HTTP 流水线已被在有多请求下表现得更稳健的 HTTP/2 的帧所取代。
(4)HTTP报文
请求:
请求由以下元素组成:
- 一个 HTTP 的请求方法,经常是由一个动词像 GET、POST 或者一个名词像 OPTIONS、HEAD 来定义客户端的动作行为。通常客户端的操作都是获取资源(GET 方法)或者发送 HTML 表单(POST 方法),虽然在一些情况下也会有其他操作。
- 要获取的资源的路径,通常是上下文中就很明显的元素资源的 URL,它没有 protocol(
http://
),domain(developer.mozilla.org
),或是 TCP 的 port (en-US)(HTTP 一般在 80 端口)。- HTTP 协议版本号。
- 为服务端表达其他信息的可选标头。
- 对于一些像 POST 这样的方法,报文的主体(body)就包含了发送的资源,这与响应报文的主体类似。
响应:
- HTTP 协议版本号。
- 一个状态码(状态码(status code)),来告知对应请求执行成功或失败,以及失败的原因。
- 一个状态信息,这个信息是非权威的状态码描述信息,可以由服务端自行设定。
- HTTP 标头,与请求标头类似。
- 可选项,比起请求报文,响应报文中更常见地包含获取资源的主体。
(5)POST GET
- post get 没有本质区别:使用场景一般可以替换
- GET的语义:获取 POST的语义:提交。但是GET 完全可以用于提交数据;POST 也完全可以用于获取数据。
- 给服务器传输数据时,GET通常是放在URL的QUERY STRING中,POST通常放在BODY中
- GET建议实现成“幂等”的----输入确定即输出也确定。 POST则不要求
- 在幂等的基础上 GET请求结果可以被缓存,POST不可
2.SPRING MVC
(1)什么是Spring MVC
Spring MVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把模 型-视图-控制器分离,将web层进行职责解耦。
-
模型封装了具体的数据
-
视图主要用于呈现模型数据,并且通常它生成客户端的浏览器可以解释的 HTML 输出。
- 控制器主要用于处理用户请求,并且构建合适的模型并将其传递到视图呈现。
(2)DispatcherServlet
DispatcherServlet 用来处理所有的 HTTP 请求和响应
-
收到一个 HTTP 请求后,DispatcherServlet 根据 HandlerMapping 来选择并且调用适当的控制器。
-
控制器接受请求,并基于使用的 GET 或 POST 方法来调用适当的 service 方法。Service 方法将设置基于定义的业务逻辑的模型数据,并返回视图名称到 DispatcherServlet 中。
-
DispatcherServlet 会从 ViewResolver 获取帮助,为请求检取定义视图。
- 一旦确定视图,DispatcherServlet 将把模型数据传递给视图,最后呈现在浏览器中。
上面所提到的所有组件,即 HandlerMapping、Controller 和 ViewResolver 是 WebApplicationContext 的一部分,而 WebApplicationContext 是带有一些对 web 应用程序必要的额外特性的 ApplicationContext 的扩展。
(3)工作流程
(4)模版引擎
(5)SpringBoot获取http请求参数的方法
1.使用 HttpServletRequest 获取参数,适用于post和get方法。
@RequestMapping("/http")
public void http(HttpServletRequest request, HttpServletResponse response){
//获取请求数据
System.out.println(request.getMethod()); //获取请求方法 GET POST
System.out.println(request.getServletPath()); //获取请求路径
Enumeration<String> enumeration=request.getHeaderNames(); //返回一个Enumeration对象,其中包含所有请求头名称
while (enumeration.hasMoreElements()){
String name = enumeration.nextElement(); //得到每个请求头
String value = request.getHeader(name); //得到对应请求头后面内容
System.out.println(name + value);
}
System.out.println(request.getParameter("code")); //获取 参数名字为code的值
}
2.用注解@RequestParam绑定请求参数到方法入参
@RequestMapping(value="/addUser",method= RequestMethod.GET)
public String addUser(@RequestParam("username") String username, @RequestParam("password") String password) {
System.out.println("username is:"+username);
System.out.println("password is:"+password);
return "demo/index";
}
3.通过 PathVariable 获取传进的参数 写激活码链接时 可以用到
@RequestMapping(value="/addUser/{username}/{password}",method=RequestMethod.GET)
public String addUser(@PathVariable String username,@PathVariable String password) {
System.out.println("username is:"+username);
System.out.println("password is:"+password);
return "demo/index";
}
4.直接把表单里面的参数写进 Controller 相应方法的形参中去(前段参数=后端形参),这个获取参数的方法适合get提交,而不适合post提交。
@RequestMapping("/addUser")
public String addUser(String username,String password) {
System.out.println("username is:"+username);
System.out.println("password is:"+password);
return "demo/index";
}
(6)响应JSON数据
@RequestMapping(value="/getUser",method= RequestMethod.GET)
@ResponseBody
public List<Map<String, String>> getUser(){
List<Map<String,String>> list = new ArrayList<>();
Map<String,String> map1 = new HashMap<>();
map1.put("name","xiaoma");
map1.put("school","山东小学");
Map<String,String> map2 = new HashMap<>();
map2.put("name","xiaomama");
map2.put("school","南洋理工小学");
list.add(map1);
list.add(map2);
return list;
}
3.MyBatis
(1)介绍
-
MyBatis是什么
Mybatis 是一个半 ORM(对象关系映射)框架,它内部封装了 JDBC,开发时只需要关注 SQL 语 句本身,不需要花费精力去处理加载驱动、创建连接、创建statement 等繁杂的过程。
MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO 映射成数据库中的记录,避免了 几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
- 优缺点
基于SQL语句编程,相当灵活,SQL写在 XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用
与JDBC相比,消除了JDBC大量冗余的代码,不需要手动开关连接
很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库 MyBatis都支持) 提供映射标签,支持对象与数据库的ORM字段关系映射;
提供对象关系映射标签,支持对象关系 组件维护
能够与Spring很好的集成
SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定 要求
- JDBC编程有哪些不足之处,MyBatis是如何解决的?
1、数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库连接池可解 决此问题。
解决:在mybatis-config.xml中配置数据链接池,使用连接池管理数据库连接。
2、Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代 码。-
解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
3、向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参 数一一对应。
解决: Mybatis自动将java对象映射至sql语句。
4、对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装 成pojo对象解析比较方便。
解决:Mybatis自动将sql执行结果映射至java对象。
(2)配置application.properties文件
#mysql??
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#mysql????
spring.datasource.url=jdbc:mysql://localhost:3306/community?characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
#?????
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.maximum-pool-size=15
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=30000
#mybatis
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.example.community.entity
mybatis.configuration.use-generated-keys=true
mybatis.configuration.map-underscore-to-camel-case=true
#debug
logging.level.com.py.pycommunity=debug
spring.datasource.hikari.maximum-pool-size=15——最大连接数
spring.datasource.hikari.minimum-idle=5——最小空闲连接
spring.datasource.hikari.idle-timeout=30000——连接的最大时长(毫秒),超时则被释放
mybatis.mapper-locations=classpath:mapper/*.xml——mapper映射文件放在类路径下mapper目录中
mybatis.type-aliases-package=com.py.pycommunity.entity——封装表的实体类所在的包,写了后在映射文件中引用实体类就不用写包名
mybatis.configuration.use-generated-keys=true——启用自动生成主键
(3)编写User实体类,放在entity包下
(4)编写UserMapper接口,dao层
@Mapper
public interface UserMapper {
User selectById(@Param("id") int id);
User selectByName(@Param("username") String username);
User selectByEmail(@Param("email") String email);
int insertUser(User user);
int updateStatus(@Param("id") int id, @Param("status") int status);
int updateHeader(@Param("id") int id, @Param("headerUrl") String headerUrl);
int updatePassword(@Param("id") int id,@Param("password") String password);
}
(5)编写user-mapper.xml 放在resources.mapper下
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.community.dao.UserMapper">
<sql id="selectFields">
id,username,password,salt,email,type,status,activation_code,header_url,create_time
</sql>
<sql id="insertFields">
username,password,salt,email,type,status,activation_code,header_url,create_time
</sql>
<select id="selectById" resultType="User">
select <include refid="selectFields"></include>
from user
where id=#{id}
</select>
<select id="selectByName" resultType="User">
select <include refid="selectFields"></include>
from user
where username=#{username}
</select>
<select id="selectByEmail" resultType="User">
select <include refid="selectFields"></include>
from user
where email=#{email}
</select>
<insert id="insertUser" parameterType="User" keyProperty="id">
insert into user (<include refid="insertFields"></include>)
values ( #{username},#{password},#{salt},#{email},#{type},#{status},#{activationCode},#{headerUrl},#{createTime})
</insert>
<update id="updateStatus">
update user set status=#{status} where id=#{id}
</update>
<update id="updateHeader">
update user set header_url=#{headerUrl} where id=#{id}
</update>
<update id="updatePassword">
update user set password=#{password} where id=#{id}
</update>
</mapper>
- user-mapper.xml中的namespace写mapper接口的全限定名(即此xml对应的是哪一个Mapper接口)
- sql语句id要写对应的方法名
- 参数类型是java中自带的可以不用声明否则用parameterType声明,返回值类型必须用resultType声明。
- keyProperty="id"表示主键和实体类的id属性绑定。
4.简单的调试
设置断点:
DEBUG:
5.版本控制 GIT
(1)介绍
- 是一个版本控制工具,源码服务器;SVN
- 团队合作先pull后push
DOS命令
ls -l------详查
cd E----到E盘
dir----遍历盘
cd …----回到上一级
cd /----回到根目录
dir /a----遍历目录包含隐藏文件
echo “文本内容” >b.txt
(2)本地仓库
1.安装成功后 注册本地账户
#用户名 git config --global user.name "XXXX" #邮箱 git config --global user.email "XXXX@XX.com" # 查看信息 git config -l
2.创建本地git仓库
仓库本质就是一个目录,这个目录中的所有文件被git管理起来,这个根目录就是仓库;仓库中每个文件的改动都由git跟踪;
创建文件夹例如demo 切换到demo目录下 ,用git init 初始化git库 将在demo目录下出现 .git 文件夹
3.初始化仓库
执行git init的目录即为工作区,
工作区的文件进入仓库时,要先进入暂存区,
分支就是版本控制,是记录文件的诸多版本,分支就是这些版本的最终记录位置;
# 新建仓库(初始化仓库) git init
4.查看仓库状态
#查看仓库状态 git status
5.暂存文件添加到缓冲区
git.add
6.提交文件 ---将暂存区的文件存入分支
git commit -m "本次提交的描述信息"
(3)远程仓库
1.关联远程仓库--本地即可用origin”代指远程仓库
git remote add origin 远程仓库的地址
2.查看远程仓库地址
git remote -v
3.将文件推送至远程仓库--将本地仓库中已经commit的内容push到远程仓库,以共享自己的代码; 需要输入码云的账号和密码
#将本地的master分支上传到远程的master分支上 git push origin master git push -u origin master
4.克隆远程仓库 --当前目录在哪就克隆到哪
git clone 克隆的远程仓库地址
5.远程仓库下载
git pull origin master
(4)常用命令
# 配置用户名
git config [--global] user.name <用户名>
# 配置邮箱,邮箱不一定是真实邮箱,仅用于标识身份
git config [--global] user.email <邮箱>
# 查看git的所有设置
git config --list
# 初始化本地仓库,生成.git文件夹
git init
# 查看本地仓库状态
git status
# 克隆仓库
git clone <远程仓库地址>
# 指定本地仓库的目录
git clone <远程仓库的网址> <本地目录>
# -b 指定要克隆的分支,默认是master分支
git clone <远程仓库的网址> -b <分支名称> <本地目录>
# --------------- git add ---------------
# 添加指定的文件到暂存区中
git add <path>
# 添加所有已修改、已删除的文件到暂存区中,不包括新增的文件
# 省略<path>表示 . ,即当前目录
git add -u [<path>]
# 添加所有文件到暂存区中,包括新增、已修改、已删除的文件
# 省略<path>表示 . ,即当前目录
git add --all [<path>]
git add -A [<path>]
git add . 相当于 git add -A
# 查看所有已修改或已删除但没有提交的文件,不包括新增的文件
git add -i [<path>]
# --------------- git commit---------------
# 把暂存区中的文件提交到本地仓库,调用文本编辑器输入该次提交的描述信息
git commit
# 把暂存区中的文件提交到本地仓库中并添加描述信息
git commit -m "<提交的描述信息>"
# 修改上次提交的描述信息
git commit --amend
# 打印所有的提交记录
git log
# 打印所有的提交记录,精简版
git reflog
# --------------- git reset ---------------
# --hard(回退全部,包括HEAD,暂存区,工作区) --soft(只回退HEAD) --mixed(回退HEAD,暂存区)
git reset --[hard, soft, mixed ] # 其中 --mixed为默认值
# 版本穿梭,跳到指定的提交版本
git reset --hard <commit ID>
# 回退到上一次提交
git reset --hard HEAD^
git rest --hard HEAD~1
# 回退到上两次提交
git reset --hard HEAD^^
git rest --hard HEAD~2
# 回退后强制推送到远端
git push --force
# --------------- 拉取分支 ---------------
# 拉取和当前本地分支对应的远端分支并合并到本地分支
git pull # 相当于 git fetch + git merge
# 拉取远端分支并合并到本地分支
git pull origin <分支名称>
# 拉取和当前本地分支对应的远端分支
git fetch
# 拉取远端分支
git fetch origin <分支名称>
# 查看git fetch刚取回的更新信息
git log -p FETCH_HEAD
# 将取回的更新信息合并到当前分支
git merge FETCH_HEAD
# --------------- 查看分支 ---------------
# 列出本地的所有分支,当前所在分支以 "*" 标出
git branch
# 列出远程的所有分支
git branch -r
# --------------- 创建分支 ---------------
# 创建新分支,新的分支基于上一次提交建立
git branch <分支名>
# --------------- 修改分支 ---------------
# 修改分支名称
# 如果不指定原分支名称则为当前所在分支
git branch -m [<原分支名称>] <新的分支名称>
# 强制修改分支名称
git branch -M [<原分支名称>] <新的分支名称>
# --------------- 删除分支 ---------------
# 删除指定的本地分支
git branch -d <分支名称>
# 强制删除本地分支
git branch -D <分支名称>
# 删除远程分支
git push origin --delete <分支名称>
git push origin :<分支名称>
# --------------- 切换分支 ---------------
# 切换到已存在的指定分支
git checkout <分支名称>
# 创建并切换到指定的分支,保留所有的提交记录
# 等同于 "git branch" 和 "git checkout" 两个命令合并
git checkout -b <分支名称>
# 创建并切换到指定的分支,删除所有的提交记录
git checkout --orphan <分支名称>
# --------------- 合并分支 ---------------
# 把指定的分支合并到当前所在的分支下
git merge <分支名称>