JavaWeb
前端
vue
vue是一套前端框架,免除原生JavaScript中的DOM操作,简化书写。
基于MVVM(Model-View-ViewModel)思想,实现数据的双向绑定,将编程的关注点放在数据上
框架:是一个半成品软件,是一套课重用的、通用的、软件基础代码模型,基于框架进行开发,更加快捷、更加高效。
- Model: 数据模型,特指前端中通过请求从后台获取的数据
- View: 视图,用于展示数据的页面,可以理解成我们的html+css搭建的页面,但是没有数据
- ViewModel: 数据绑定到视图,负责将数据(Model)通过JavaScript的DOM技术,将数据展 示到视图(View)上
Vue快速入门
- 新建HTML页面,引入Vue.js文件
1 | <script src="js/vue.js"></script> |
- 在JS代码区域,创建Vue核心对象,定义数据模型
1 | <script> |
- 编写视图
1 | <div> |
插值表达式
形式:
内容:可以是变量
、三元运算符
、函数调用
、算术运算
常用指令
指令:HTML标签上带有 v- 前缀的特殊属性,不同指令具有不同的含义。
常用指令如下:
指令 | 作用 |
---|---|
v-bind | 为HTML标签绑定属性,如设置href,css样式等 |
v-model | 在表单元素上创建双向数据绑定 |
v-on | 为HTML标签绑定事件 |
v-if | 条件性的渲染某元素,判定为true时渲染,否则不渲染 |
v-else-if | 条件性的渲染某元素,判定为true时渲染,否则不渲染 |
v-else | 条件性的渲染某元素,判定为true时渲染,否则不渲染 |
v-show | 根据条件展示某元素,区别在于切换的是display属性的值 |
v-for | 列表渲染,遍历容器的元素或者对象的属性 |
- v-bind
1 | <a v-bind:href="url">传智教育</a> |
- v-model
1 | <input type="text" v-model="url"> |
注意:通过v-bind或者v-model绑定的变量,必须在数据模型中声明
- v-on
1 | <input type="button" value="按钮" v-on:click="handle()"> |
1 | <input type="button" value="按钮" @click="handle()"> |
1 | <script> |
- v-if
1 | 年龄{{age}},经判定为: |
- v-show
1 | 年龄{{age}},经判定为: |
- v-for
1 | <div v-for="addr in addrs">{{addr}}</div> |
1 | <div v-for="(addr,index) in addrs">{{index+1}} : {{addr}}</div> |
1 | data:{ |
生命周期
- 生命周期:指一个对象从创建到销毁的整个过程
- 生命周期的八个阶段:每触发一个生命周期事件,会自动执行一个生命周期方法(钩子)
状态 | 阶段周期 |
---|---|
beforeCreate | 创建前 |
created | 创建后 |
beforeMount | 挂载前 |
mounted | 挂载完成 |
beforeUpdate | 更新前 |
updated | 更新后 |
boforeDestory | 销毁前 |
destoryed | 销毁后 |
.png))
1 | <script> |
- mounted:装载完成,Vue初始化完成,HTML页面渲染成功。(发送请求到服务端,加载数据)
Ajax
- 概念:Asynchronous JavaScript And XML ,异步的JavaScript和XML
- 作用
- 数据交换:通过Ajax可以给服务器发送请求,并获取服务器响应的数据
- 异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想、用户是否可用的校验等等
同步与异步
- 同步
同步请求发送过程如下图所示:
.png)
浏览器页面在发送请求给服务器,在服务器处理请求的过程中,浏览器页面不能做其他的操作。只 能等到服务器响应结束后才能,浏览器页面才能继续做其他的操作。
- 异步
异步请求发送过程如下图所示:
.png)
浏览器页面发送请求给服务器,在服务器处理请求的过程中,浏览器页面还可以做其他的操作。
原生Ajax
1.准备数据地址:https://yapi.smart-xwork.cn/mock/169327/emp/list
2.创建XMLHttpRequest对象:用于和服务器交换数据
3.向服务器发送请求
4.获取服务器响应数据
1 | //1. 创建XMLHttpRequest |
Axios
1.引入Axios的js文件
1 | <script src="js/axios-0.18.0.js"></script> |
2.使用Axios发送请求,并获取响应结果
- get请求
1 | axios({ |
- post请求
1 | axios({ |
axios()是用来发送异步请求的,小括号中使用 js的JSON对象传递请求相关的参数:
method属性:用来设置请求方式的。取值为 get 或者 post。
url属性:用来书写请求的资源路径。如果是 get 请求,需要将请求参数拼接到路径的后面,格式为: url?参数名=参数值&参数名2=参数值2。
data属性:作为请求体被发送的数据。也就是说如果是 post 请求的话,数据需要作为 data 属性的值。
then() 需要传递一个匿名函数。我们将 then()中传递的匿名函数称为 回调函数,意思是该匿名函数在发送请求时不会被调用,而是在成功响应后调用的函数。而该回调函数中的 resp 参数 是对响应的数据进行封装的对象,通过 resp.data 可以获取到响应的数据。
Axios还针对不同的请求,提供了别名方式的api,具体如下:
方法名 | 描述 |
---|---|
axios.get(url[,config]) | 发送get请求 |
axios.delete(url[,config]) | 发送delete请求 |
axios.post(url[,data[,config]]) | 发送post请求 |
axios.put(url[,data[,config]]) | 发送put请求 |
前端工程化
前后端分离
具体开发一个功能的步骤:
- 需求分析:首先我们需要阅读需求文档,分析需求,理解需求。
- 接口定义:查询接口文档中关于需求的接口的定义,包括地址,参数,响应数据类型等等
- 前后台并行开发:各自按照接口文档进行开发,实现需求
- 测试:前后台开发完了,各自按照接口文档进行测试
- 前后段联调测试:前段工程请求后端工程,测试功能
Vue项目
创建
命令行:vue create vue-project01
图形化界面:vue ui
.png)
Element
Element:是饿了么团队研发的,一套为开发者、设计者和产品经理准备的基于Vue2.0的桌面端组件库
组件:组成网页的部件,例如 超链接、按钮、图片、表格、表单、分页条等
- 安装ElementUI组件库(在当前工程的目录下),在命令行执行指令:
1 | npm install element -ui@2.15.3 |
- 引入ElementUI组件库
1 | import ElementUI from 'element-ui'; |
- 访问官网,复制组件代码,调整
shift+alt+f 代码对齐格式
Vue项目中使用Axios:
- 在项目目录下安装axios:npm install axios;
- 需要使用axios时,导入axios:import axios from ‘axios’;
Vue路由
前端路由:URL中的hash(#号)与组件之间的对应关系。
Vue Router
Vue Router是Vue的官方路由
组成:
其工作原理如下图所示:
.png)
- 首先VueRouter根据我们配置的url的hash片段和路由的组件关系去维护一张路由表;
- 然后我们页面提供一个组件,用户点击,发出路由请求;
- 接着我们的VueRouter根据路由请求,在路由表中找到对应的vue组件;
- 最后VueRouter会切换中的组件,从而进行视图的更新
- 安装(创建Vue项目时已选择)
1 | npm install vue-router@3.5.1 |
- 定义路由
打包部署
- 打包
.png)
- 部署
nginx: Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。 其特点是占有内存少,并发能力强,在各大型互联网公司都有非常广泛的使用。 niginx在windows中的安装是比较方便的,直接解压即可。如下图所示就是nginx的解压目录以及目录结构说明:
.png)
将我们之前打包的前端工程dist目录下得内容拷贝到nginx的html目录下
然后我们通过双击nginx下得nginx.exe文件来启动nginx,nginx服务器的端口号是80,所以启动成功之后,我们浏览器直接访问http://localhost:80 即 可,其中80端口可以省略,其到此,我们的前端工程发布成功。 PS: 如果80端口被占用,我们需要通过conf/nginx.conf配置文件来修改端口号。如下图所示:
.png)
后端
Maven
Maven是apache旗下的一个开源项目,是一款用于管理和构建java项目的工具
作用:
- 依赖管理:方便快捷的管理项目依赖的资源(jar包),避免版本冲突问题
- 统一项目结构:提供标准、统一的项目结构
- 项目构建:标准跨平台(Linux、Windows、MacOS)的自动化项目构建方式
仓库:用于存储资源,管理各种jar包
- 本地仓库:自己计算机上的一个目录
- 中央仓库:由Maven团队维护的全球唯一性的仓库,仓库地址为:https://repo1.maven.org/maven2/
- 远程仓库(私服):一般由公司团队搭建的私有仓库
安装步骤:
- 解压apache-maven-3.6.1-bin.zip
- 配置本地仓库:修改conf/settings.xml中的
为一个指定目录
1 | <localRepository>D:\delvelop\apache-maven-3.6.1\mvn_repo</localRepository> |
- 配置阿里云私服:修改conf/settings.xml中的
标签,为其添加如下子标签:
1 | <mirrors> |
- 配置环境变量:MAVEN_HOME为maven的解压缩目录,并将其bin目录加入PATH环境变量
配置Maven环境(当前工程)
- 选择IDEA中 File –> Settings –> Build,Execution,Deployment –> Build Tools –> Maven
- 设置IDEA使用本地安装的Maven,并修改配置文件及本地仓库路径
配置Maven环境(全局)
直接在创建项目栏按上述操作即可,不必打开项目
选择IDEA中 File –> Settings –> Build,Execution,Deployment –> Build Tools –> Maven
设置IDEA使用本地安装的Maven,并修改配置文件及本地仓库路径
IDEA创建Maven项目
- 创建模板,选择Maven,点击Next
- 填写模块名称,坐标信息,点击finish,创建完成
- 编写HelloWorld,并运行
Maven坐标
- Maven中的坐标是资源的唯一标识,通过该坐标可以唯一定位资源位置
- 使用坐标来定义项目或者引入项目中需要的依赖
Maven坐标主要组成
- groupId:定义当前Maven项目隶属组织名称(通常是域名反写,例如:com.ithema)
- artifactId:定义当前Maven项目名称(通常是模块名称,例如:order-service,goods-services)
- version:定义当前项目版本号
1 | <groupId>com.ithema</groupId> |
1 | <dependency> |
导入Maven项目
方式一:打开IDEA,选择右侧Maven面板,点击+号,选中对应项目的pom.xml文件,双击即可
方式二:File => Project Structure => Modules => + => Import Module
依赖管理
- 依赖:指当前项目运行所需的jar包,一个项目可以引用多个依赖
- 配置:
- 在pom.xml中编写
标签 - 在
标签中使用 引入坐标 - 定义坐标的groupId、artifacId、version
- 点击刷新按钮,引入最新加入的坐标
- 在pom.xml中编写
1 | <dependencies> |
注意事项:
- 如果引入的依赖,在本地仓库不存在,将会连接远程仓库/中央仓库,然后下载依赖。(这个过程会比较耗时,需要耐心等待)
- 如果不知道依赖的坐标信息,可以到https://mvnrepository.com/中搜索
依赖传递
依赖具有传递性
直接依赖:在当前项目中通过依赖配置建立的依赖关系
间接依赖:被依赖的资源如果依赖其他资源,当前项目间接依赖其他资源
排除依赖:排除依赖指主动断开依赖的资源,被排除的资源无需指定版本,通过添加
标签来排除依赖
1 | < !-- 排除依赖 --> |
依赖范围
依赖的jar包,默认情况下,可以在任何地方使用,可以通过<scope>...</scope>
设置其作用范围。
作用范围:
- 主程序范围有效。(main文件夹范围内)
- 测试程序范围有效。(test文件夹范围内)
- 是否参与打包运行。(package指令范围内)
1 | <dependency> |
scope值 | 主程序 | 测试程序 | 打包(运行) | 范例 |
---|---|---|---|---|
compile(默认值) | Y | Y | Y | log4j |
test | - | Y | - | junit |
provided | Y | Y | - | servlet-api |
runtime | - | Y | Y | jdbc驱动 |
生命周期
Maven的生命周期就是为了对所有的maven项目构建过程进行抽象和统一
Maven中有3套相互独立的生命周期:
- clean:清理工作
- default:核心工作,如:编译、测试、打包、安装、部署等
- site:生成报告、发布站点等
每套生命周期包含一些阶段(phase),阶段是有顺序的,后面的阶段依赖于前面的阶段。
.png)
我们看到这三套生命周期,里面有很多很多的阶段,这么多生命周期阶段,其实常用的并不多,主要关注以下几个:
- clean:移除上一次构建生成的文件
- compile:编译项目源代码
- test:使用合适的单元测试框架运行测试(junit)
- package:将编译后的文件打包,如:jar、war等
- install:安装项目到本地仓库
注意事项:在同一套生命周期中,当运行后面的阶段时,前面的阶段也会运行。
执行指定生命周期的两种方式:
- 在idea中,右侧的maven工具栏,选中对应的生命周期,双击执行
- 在命令行执行时,通过命令执行
1 | mvn clean |
Web入门
Spring
官网:spring.io
Spring发展到今天已经形成了一种生态开发生态圈,Sring提供了若干个子项目,每个项目用于完成特定的功能
SpringBootWeb快速入门
需求:使用SpringBoot开发一个web应用,浏览器发起请求/hello后,给浏览器返回字符串”Hello World ~”
步骤:
- 创建springboot工程,并勾选web开发相关依赖
- 定义HelloController类,添加方法Hello,并添加注解
- 运行测试
创建请求处理类HelloController,添加请求处理方法Hello,并添加注解
.png)
运行启动类,打开浏览器测试
1 | localhost:8080/hello |
HTTP协议
概念:Hyper Text Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则
特点:
- 基于TCP协议:面向连接、安全
- 基于请求-响应模型的:一次请求对应一次响应
- HTTP协议是无状态的协议:对于事务处理没有记忆能力,每次请求-响应都是独立的
- 优点:速度快
- 缺点:多次请求间不能共享数据
请求协议
请求数据格式
请求行:请求数据第一行(请求方式、资源路径、协议)
请求头:第二行开始,格式:key - value
Host | 请求的主机名 |
---|---|
User-Agent | 浏览器版本,例如Chrome浏览器的标示类似Mozilla/5.0…Chrome/79,IE浏览器的标示类似Mozilla/5.0(Windows NT …) like Gecko(考虑浏览器兼容问题) |
Accept | 表示浏览器能接收的资源类型,如text/*,image/或者/*表示所有 |
Accept-Language | 表示浏览器偏好的语言,服务器可以根据此返回不同语言的网页 |
Accept-Encoding | 表示浏览器可以支持的压缩类型,例如gzip、deflate等 |
Content-Type | 请求主体的数据类型 |
Content-Length | 请求主体的大小(单位:字节) |
请求体:POST请求,存放请求参数
请求方式-GET:请求参数在请求行中,没有请求体,如/brand/findAll?name=OPPO&status=1。GET请求是有大小限制的
请求方式-POST:请求参数在请求体中,POST请求是没有大小限制的
响应协议
响应行:响应数据第一行(协议、状态码、描述)
响应头:从第二行开始,格式为 key : value
响应体:最后一部分,存放响应数据
HTTP响应格式
1xx | 响应中-临时状态码,表示请求已经接收,告诉客户端应该继续请求或者如果它已经完成则忽略它 |
---|---|
2xx | 成功-表示请求已经被成功接收,处理已完成 |
3xx | 重定向-重定向到其他地方:让客户端再发起一次请求以完成整个处理 |
4xx | 客户端错误-处理发生错误,责任在客户端,如:请求了不存在的资源、客户端未授权、禁止访问等 |
5xx | 服务器错误-处理发生错误,责任在服务端,如:程序抛出异常等 |
Contenet-Type | 表示该响应内容的类型,例如text/html,application/json |
---|---|
Content-Length | 表示该响应内容的长度(即字节) |
Content-Encoding | 表示该响应压缩算法,例如gzip |
Cache-Control | 提示客户端如何缓存,例如max-age=300表示可以最多缓存300秒 |
Set-Cookie | 告诉浏览器为当前页面所在的域设置Cookie |
常见的响应状态码
状态码 | 英文描述 | 解释 |
---|---|---|
==200== | OK |
客户端请求成功,即处理成功,这是我们最想看到的状态码 |
302 | Found |
指示所请求的资源已移动到由Location 响应头给定的 URL,浏览器会自动重新访问到这个页面 |
304 | Not Modified |
告诉客户端,你请求的资源至上次取得后,服务端并未更改,你直接用你本地缓存吧。隐式重定向 |
400 | Bad Request |
客户端请求有语法错误,不能被服务器所理解 |
403 | Forbidden |
服务器收到请求,但是拒绝提供服务,比如:没有权限访问相关资源 |
==404== | Not Found |
请求资源不存在,一般是URL输入有误,或者网站资源被删除了 |
405 | Method Not Allowed |
请求方式有误,比如应该用GET请求方式的资源,用了POST |
428 | Precondition Required |
服务器要求有条件的请求,告诉客户端要想访问该资源,必须携带特定的请求头 |
429 | Too Many Requests |
指示用户在给定时间内发送了太多请求(“限速”),配合 Retry-After(多长时间后可以请求)响应头一起使用 |
431 | Request Header Fields Too Large |
请求头太大,服务器不愿意处理请求,因为它的头部字段太大。请求可以在减少请求头域的大小后重新提交。 |
==500== | Internal Server Error |
服务器发生不可预期的错误。服务器出异常了,赶紧看日志去吧 |
503 | Service Unavailable |
服务器尚未准备好处理请求,服务器刚刚启动,还未初始化好 |
状态码大全:https://cloud.tencent.com/developer/chapter/13553
Web服务器-Tomcat
Web服务器是一个软件程序,对HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让Web开发更加便捷。主要功能是“提供网上信息浏览服务”。
Tomcat是Apache软件基金会的一个核心项目,是一个开源免费的轻量级web服务器,支持Servlet/JSP少量JavaEE规范
JavaEE:java Enterprise Edition,java企业版。指java企业级开发的技术规范总和,包含13项技术规范:JDBC、JNDI、EJB、RMI、JSP、Servlet、XML、JMS、java IDL 、JTS、JTA、javaMall、JAF
Tomcat也被称为Web容器、Servlet容器,Servlet程序需要依赖于Tomcat才能运行
Tomcat的基本使用:
- 下载:官网地址 https://tomcat.apache.org/download-90.cgi
- 安装:绿色版,直接解压即可
- 卸载:直接删除目录即可
- 启动:双击Tomcat文件中bin文件里的startup.bat
控制台中文乱码:修改conf/logging.properties
1 | java.util.logging.ConsoleHandler.level = FINE |
- 关闭:
- 直接x掉运行窗口:强制关闭
- bin\shutdown.bat:正常关闭
- Ctrl+C:正常关闭
- 配置Tomcat端口号(conf/server.xml)
1 | <Connector port="8080" protocol="HTTP/1.1" |
- Tomcat部署项目
将项目放置到webapps目录下,即部署完成
常见问题:
- 启动窗口一闪而过:检查JAVA_HOME环境变量是否正确配置
- 端口号冲突:找到对应程序,将其关闭掉
注意事项:HTTP协议默认端口号为80,如果将Tomcat端口号改为80,则将来访问Tomcat时,不需要输入端口号
起步依赖:
- spring-boot-starter-web:包含了web应用开发所需要的常见依赖
- spring-boot-starter-test:包含了单元测试所需要的常见依赖
- 官方提供的starter:https://docs.spring.io/spring-boot/docs/2.7.4/reference/htmlsingle/#using.build-systems.starters
基于Springboot开发的web应用程序,内置了tomcat服务器,当启动类运行时,会自动启动内嵌的tomcat服务器
请求响应
- 请求(HttpServletRequest):获取请求数据
- 响应(HttpServletResponse):设置响应数据
- BS架构:Brower/Server,浏览器 / 服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。(维护方便 体验一般)
- CS架构:Client / Server,客户端 / 服务器架构模式。(开发、维护麻烦、体验不错)
请求
Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。
作用:常用于进行接口测试
简单参数
简单参数:参数名与形参变量名相同,定义形参即可接收参数
如果方法形参名称与请求参数名称不匹配,可以使用@RequestParam
完成映射
1 |
|
注意事项:@RequestParam中的required属性默认为true,代表该请求参数必须传递,如果不传递则报错。如果该参数是可选的,可以将required属性设置为false
- 原始方式
在原始的web程序中,获取请求参数,需要通过HttpServletRequest对象手动获取。
1 |
|
实体参数
简单实体对象:请求参数名与形参名对象属性名相同,定义POJO接收即可
1 |
|
复杂实体对象:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数。
1 |
|
数组集合参数
数组参数:请求参数名与形参数组名称相同且请求参数为多个,定义数组类型形参即可接收参数
- 数组接收:请求参数名与形参中数组变量名相同,可以直接使用数组封装
1 |
|
- 集合接收:请求参数名与形参中集合变量名相同,通过
@RequestParam
绑定参数关系
1 |
|
日期参数
日期参数:使用@DateTimeFormat
注解完成日期格式参数转换
1 |
|
JSON参数
JSON参数:JSON数据键名与形参对象属性名相同,定义POJO类型形参即可接收参数,需要使用@RequestBody
标识
1 |
|
路径参数
路径参数:通过请求URL直接传递参数,使用{…}来标识该路径参数,需要使用@PathVariable
获取路径参数
1 |
|
获取多个路径参数
1 |
|
响应
ResponseBody
- 类型:方法注解、类注解
- 位置:Controller方法上 / 类上
- 作用:将方法返回值直接响应,如果返回值类型是 实体对象 / 集合,将会转换为JSON格式响应
- 说明:@RestController = @Controller + @ResonseBody
响应-字符串
1 |
|
响应-JSON对象
1 |
|
响应-JSON集合
1 |
|
统一响应结果
Result(code、msg、data)
1 | public class Result { |
1 |
|
Springboot项目的静态资源(html、css、js等前端资源)默认存放目录为:classpath:/static,classpath:/public,classpath:/resources
分层解耦
三层架构
- controller:控制层,接收前端发送的请求,对请求进行处理,并响应数据。
- service:业务逻辑层,处理具体的业务逻辑。
- dao:数据访问层(Data Access Object)(持久层),负责数据访问操作,包括数据的增、删、改、查。
按员工案例拆分成三层架构后如下:
- controller层:接收请求,响应数据
1 |
|
- dao层:数据访问操作
1 | public class EmpDaoA implements EmpDao { |
- service层:业务逻辑处理
1 | public class EmpServiceA implements EmpService { |
分层解耦
- 内聚:软件中各个功能模块内部的功能联系。
- 耦合:衡量软件中各个层/模块之间的依赖、关联的程度。
- 软件设计原则:高内聚低耦合。
控制反转:Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转。
依赖注入:Dependency Injection,简称DI。容器为应用程序提供运行时所依赖的资源,称之为依赖注入。
Bean对象:IOC容器中创建、管理的对象,称之为bean。
IOC & DI 入门
- Service层 及 Dao层的实现类,交给IOC容器管理。– 加上
@Component
- 为Controller及Service注入运行时依赖的对象。 – 在成员变量前面加上
@Autowired
- 运行测试。
- Dao层
1 |
|
- Service层
1 |
|
- Controller层
1 |
|
若需要使用其他接口的实现类,则只需要将当前使用的接口实现类中的@Component
注释掉即可
IOC详解
Bean的声明
要把某个对象交给IOC容器管理,需要在对应的类上加上如下注解之一:
注解 | 说明 | 位置 |
---|---|---|
@Component | 声明bean对象的基础注解 | 不属于以下三类时,用此注解 |
@Controller | @Component的衍生注解 | 标注在控制器类上 |
@Service | @Component的衍生注解 | 标注在业务上 |
@Repository | @Component的衍生注解 | 标注在数据访问类上(由于与mybatis整合,用的少) |
注意事项:
- 声明bean的时候,可以通过value属性指定bean的名字,如果没有指定,默认为类名首字母小写。
- 使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用
@Controller
。
Bean组件扫描
- 前面声明bean的四大注解,要想生效,还需要被组件扫描注解
@ComponentScan
扫描。 @ComponentScan
注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解@SpringBootApplication
中,默认扫描的范围是启动类所在包及其子包。
如果其中一个包未放在启动包下面,则可以通过以下方法解决:
- 手动添加@ComponentScan注解,指定要扫描的包 (==仅做了解,不推荐==)
1 | //添加以下注解 |
- 将我们定义的controller,service,dao这些包都放在引导类所在包com.itheima的子包下,这样我们定义的bean就会被自动的扫描到
DI详解
依赖注入,是指IOC容器要为应用程序去提供运行时所依赖的资源,而资源指的就是对象。
@Autowired注解,默认是按照类型进行,如果存在多个相同类型的bean,将会报错,以下是几种解决方案
@Primary
设定优先级
1 |
|
@Qualifier
配合@Autowired
使用(@Antowiredf + @Qulifier(“bean的名称”))
1 |
|
- 使用
@Resource
(@Resource(name = “bean的名称”))
1 |
|
@Resource和@Autowired区别
- @Autowired是springboot框架提供的注解,而@Resource是JDK提供的注解。
- @Autowired默认是按照类型注入,而@Resource默认是按照名称注入。
MyBatis
MyBatis是一款优秀的持久层框架,用于简化JDBC的开发。
MyBaits本是Apache的一个开源项目iBatis,2010年该项目由Apache迁移到了google code,并且改名为MyBatis。2013年11月迁移到Github。
官网:https://mybatis.org/mybatis-3/zh/index.html
入门
案例:使用mybatis查询所有用户数据
- 准备工作(创建springboot工程,数据库表user,实体类user)
- 引入Mybatis的相关依赖,配置Mybatis
- 编写SQL语句(注解/XML)
JDBC
JDBC:(Java Database Connectivity),就是使用Java语言操作关系模型数据库的一套API。
本质:
- sun公司官方定义的一套操作所有关系型数据库的规范,即接口。
- 各个数据库厂商去实现这套接口,提供数据库驱动jar包。
- 我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
1 |
|
数据库连接池
数据库连接池,是个容器,负责分配、管理数据库连接(Connection),它允许应用程序重复使用一个现有的数据库连接,而不是重新再建立一个,释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接泄漏
优势
- 资源重用
- 提升系统响应速度
- 避免数据库连接泄漏
标准接口:DataSource
- 官方(sun)提供的数据库连接池接口,由第三方组织实现此接口。
- 功能:获取连接
connection getConnection() throws SQLException;
常见产品:C3P0、DBCP、Druid、Hikari(springboot默认)
Druid(德鲁伊)
- Druid连接池是阿里巴巴开源的数据库连接池项目
- 功能强大、性能优秀、是Java语言最好的数据库连接池之一
切换Druid数据库连接池
官方地址:https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
1 | <!-- 添加到pom.xml文件--> |
1 | #添加到application.properties文件中 |
lombok
Lombok是一个实用的Java类库,能通过注解的形式自动生成构造器、getter / setter、equals、hashcode、toString等方法,并可以自动化成日志变量,简化Java开发、提高效率。
注解 | 作用 |
---|---|
@Getter / @Setter | 为所有属性提供get/set方法 |
@ToString | 会给类自动生成易阅读的toString方法 |
@EqualsAndHashCode | 根据类所拥有的非静态字段自动重写equals方法和hashCode方法 |
@Data | 提供了更综合的生成代码的功(@Getter+@Setter+@ToString+@EqualsAndHashCode) |
@NoArgsConstructor | 为实体类生成无参的构造器方法 |
@AllArgsConstructor | 为实体类生成除了static修饰的字段之外带有各参数的构造器方法。 |
使用lombokl需要引入依赖
1 | <dependency> |
注意事项:Lombok会在编译时,自动生成对应的java代码,我们使用lombok时,还需要安装一个lombok的插件(idea自带)
基础操作
案例:根据提供的《tlias智能学习辅助系统》页面原型及需求,完成员工管理的需求开发。
功能列表:
- 查询(根据主键ID查询、条件查询)
- 新增
- 更新
- 删除(根据主键ID删除,根据主键ID批量删除)
准备工作
- 准备数据库表emp
- 创建一个新的springboot工程,选择引入对应的起步依赖(mybatis、mysql驱动、lombok)
- application.properties中引入数据库连接信息
- 创建对应的实体类Emp(实体类属性采用驼峰命名)
- 准备Mapper接口EmpMapper
根据主键删除ID
SQL语句
1 | delete from emp where id = 17; |
接口方法
1 |
|
注意事项:如果mapper接口方法形参只有一个普通类型的参数,#{…}里面的属性名可以随便写,如:#{id}、#{value}
日志删除
可以在application.properties中,打开mybatis日志,并指定输出到控制台
1 | #指定mybatis输出日志的位置,输出控制台 |
预编译SQL
.png)
预编译SQL优势:
- 性能更高
- 更安全(防止SQL注入)
SQL注入是指通过操作输入的数据来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法。
由于没有对用户输入进行充分检查,而SQL又是拼接而成,在用户输入参数时,在参数中添加一些SQL关键字,达到改变SQL运行结果的目的,也可以完成恶意攻击。
占位参数符
#{…}:执行SQL时,会将#{…}替换为?,生成预编译SQL,会自动设置参数值。使用时机:参数传递,都使用#{…}
${…}:直接将参数拼接在SQL语句中,存在SQL注入问题。使用时机:如果对表名、列表进行动态设置时使用。
新增员工
- SQL语句
1 | insert into emp (username, name, gender, image, job, entrydate, dept_id, create_time, update_time) |
- 接口方法
1 |
|
新增(主键返回)
描述:在数据添加成功后,需要获取插入数据库数据的主键,如添加套餐数据时,还需要维护套餐菜品关系表数据。
- 实现
1 |
|
更新
- SQL语句(根据ID更新员工信息)
1 | update emp set username='songdaxia',name='宋大侠',gender='1',image='1.jpg',job='2', |
- 接口方法
1 |
|
查询(根据ID查询)
- SQL语句
1 | select * from emp where id = 19; |
- 接口方法
1 |
|
数据封装
- 实体类属性名和数据表查询返回的字段名一致时,mybatis会自动封装。
- 如果实体类属性名和数据表查询返回的字段名不一致时,不能自动封装。
解决方案:
- 起别名:在SQL语句中,对不一样的列名起别名,别名和实体类属性名一样
1 | //方案一:给字段起别名,让别名与实体类属性一致 |
- 手动结果映射:通过@Results及@Result进行手动结果映射
1 | //方案二:通过@Results,@Result注解手动映射封装 |
- 开启驼峰命名:如果字段名与属性名符合驼峰命名规则,mybatis会自动通过驼峰命名规则映射
1 | #方案三:开启mybatis的驼峰命名自动映射开关 ---- a_cloumn ---------> aColumn |
查询(条件查询)
- SQL语句
1 | select * from emp where name like '%张%' and gender = 1 and entrydate between '2010-01-01' and '2020-01-01' order by |
- 接口方法
1 |
|
使用$会存在性能低、不安全、存在SQL注入问题,可以通过字符串拼接函数concat
来解决这个为题
1 |
|
参数名说明
- 在springboot的2.x版本
.png)
- 在springboot的1.x版本 / 单独使用mybatis
.png)
XML映射文件
规范
- XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置到相同包下(同名同包)
- XML映射文件的namespace属性为Mapper接口全限定名一致
- XML映射文件中SQL语句的id与Mapper接口中的方法名一致,并保持返回类型一致
1 | //Mapper接口 |
1 | <!-- XML映射文件--> |
MybatisX
MybatisX是一款基于IDEA的快速开发Mybatis的插件,为效率而生。
使用Mybatis的注解,主要是来完成一些简单的增删改查功能。如果需要实现复杂的SQL功能,建议使用XML来配置映射语句。
官方说明:https://mybatis.net.cn/getting-started.html
动态SQL
随着用户的输入或外部条件的变化而变化的SQL语句,我们称为动态SQL。
1 | <select id="list" resultType="com.ithema.pojo.Emp"> |
:用于判断条件是否成立。使用test属性进行条件判断,如果条件为true,则拼接SQL。
1 | <if test=" name != null"> |
1 | <select id="list" resultType="com.ithema.pojo.Emp"> |
引入
1 | <select id="list" resultType="com.ithema.pojo.Emp"> |
动态更新修改员工信息
1 | <update id="update2" > |
1 | <update id="update2" > |
- SQL语句
1 | delete from emp where id in(18,21,24); |
- 接口方法
1 | public void deleteByIds(List<Integer> ids); |
- XML映射文件
1 | <delete id="deleteByIds"> |
属性
- collection:集合名称
- item:集合遍历出来的元素 / 项
- separator:每一次遍历使用的分割符
- open:遍历开始前拼接的片段
- close:遍历结束后拼接的片段
sql片段
1 | <sql id="commonSelect"> |
1 | <select id="list" resultType="com.ithema.pojo.Emp"> |
:定义可重用的SQL片段 :通过属性refid,指定包含的sql片段