java项目解析

java项目解析

注解

@PathVariable

使用{…}来标识该路径参数,需要使用@PathVariable获取路径参数

@RequestMapping("/path/{id}")
public String pathParam(@PathVariable Integer id){
System.out.println(id);
return "OK";

//多参
@RequestMapping("/path/{id}/{name}")
public String pathParam2(@PathVariable Integer id, @PathVariable
String name){
System.out.println(id+ " : " +name);
return "OK";
@RestController和@ResponseBody

但是在我们所书写的Controller中,只在类上添加了@RestController注解、方法添加了@RequestMapping注解,并没有使用@ResponseBody注解,怎么给浏览器响应呢?

@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
System.out.println("Hello World ~");
return "Hello World ~";
 }
}

原因:在类上添加的@RestController注解,是一个组合注解。

@RestController = @Controller + @ResponseBody

结论:在类上添加@RestController就相当于添加了@ResponseBody注解。

  1. 类上有@RestController注解或@ResponseBody注解时:表示当前类下所有的方法返回值做为响应数据

  2. 方法的返回值,如果是一个POJO对象或集合时,会先转换为JSON格式,在响应给浏览器

@Component

使用Spring提供的注解:@Component ,就可以实现类交给IOC容器管理

而Spring框架为了更好的标识web应用程序开发当中,bean对象到底归属于哪一层,又提供了

@Component的衍生注解:

@Controller (标注在控制层类上)

@Service (标注在业务层类上)

@Repository (标注在数据访问层类上)

注解声明bean对象png

在IOC容器中,每一个Bean都有一个属于自己的名字,可以通过注解的value属性指定bean的名字。如果没有指定,默认为类名首字母小写。

使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller。

.

使用四大注解声明的bean,要想生效,还需要被组件扫描注解@ComponentScan扫描

@ComponentScan注解虽然没有显式配置,但是实际上已经包含在了引导类声明注解

@SpringBootApplication 中, 默认扫描的范围是SpringBoot启动类所在包及其子包

解决方案:手动添加@ComponentScan注解,指定要扫描的包 ( 仅做了解,不推荐 )

.

@Autowired

使用Spring提供的注解:@Autowired ,就可以实现程序运行时IOC容器自动注入需要的依赖对象

bean对象注入png

Autowired翻译过来叫:自动装配。

.

那如果在IOC容器中,存在多个相同类型的bean对象,程序运行会报错

解决上述问题呢?Spring提供了以下几种解决方案:

  • @Primary(默认实现)

  • @Qualifier(指定名称)

  • @Resource(指定名称)

使用@Primary注解:当存在多个相同类型的Bean注入时,加上@Primary注解,来确定默认的实现。

@Qualifier注解:指定当前要注入的bean对象。 在@Qualifier的value属性中,指定注入的bean的名称。

@Qualifier注解不能单独使用,必须配合@Autowired使用

@Resource注解:是按照bean的名称进行注入。通过name属性指定要注入的bean的名称。

面试题 : @Autowird 与 @Resource的区别

@Autowired 是spring框架提供的注解,而@Resource是JDK提供的注解

@Autowired 默认是按照类型注入,而@Resource是按照名称注入

细节

前端的代码是如何转换成用户眼中的网页的 ?

通过浏览器转化(解析和渲染)成用户看到的网页

浏览器中对代码进行解析和渲染的部分,称为 浏览器内核

Web标准

也称为网页标准,由一系列的标准组成,大部分由W3C( World Wide Web

Consortium,万维网联盟)负责制定。由三个组成部分:

HTML:负责网页的结构(页面元素和内容)。

CSS:负责网页的表现(页面元素的外观、位置等页面样式,如:颜色、大小等)。

JavaScript:负责网页的行为(交互效果)。

前端应该如何从后台获取数据-Ajax

Ajax: 全称Asynchronous JavaScript And XML,异步的JavaScript和XML

与服务器进行数据交换:通过Ajax可以给服务器发送请求,并获取服务器响应的数据。

异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想、用户名是否可用的校验等等

ajax使用方法

创建XMLHttpRequest对象,用于和服务器交换数据,也是原生Ajax请求的核心对象,

提供了各种方法。代码如下:

//1. 创建XMLHttpRequest
var xmlHttpRequest = new XMLHttpRequest();

调用对象的open()方法设置请求的参数信息,例如请求地址,请求方式。然后调用send()方法向服务器发送请求,代码如下:

//2. 发送异步请求
xmlHttpRequest.open('GET,'http://yapi.smartxwork.cn/mock/169327/emp/list');
xmlHttpRequest.send();//发送请求

通过绑定事件的方式,来获取服务器响应的数据。

//3. 获取服务响应数据
xmlHttpRequest.onreadystatechange = function(){
//此处判断 4表示浏览器已经完全接受到Ajax请求得到的响应, 200表示这是
一个正确的Http请求,没有错误
if(xmlHttpRequest.readyState == 4 && xmlHttpRequest.status ==
200){
document.getElementById('div1').innerHTML =
xmlHttpRequest.responseText;
 }
}
Axios的基本使用

更加简单的发送Ajax请求的技术Axios 。Axios是对原生的AJAX进行封装,Axios中文文档 | Axios中文网

Axios的使用比较简单,主要分为2步:

引入Axios文件

<script src="js/axios-0.18.0.js"></script>

使用Axios发送请求,并获取响应结果,官方提供的api很多,此处给出2种,如下

发送 get 请求

axios({
method:"get",
url:"http://localhost:8080/ajax-demo1/aJAXDemo1?
username=zhangsan"
}).then(function (resp){
alert(resp.data);
})

发送 post 请求

axios({
method:"post",
url:"http://localhost:8080/ajax-demo1/aJAXDemo1",
data:"username=zhangsan"
}).then(function (resp){
alert(resp.data);
});

axios()是用来发送异步请求的,小括号中使用 js的JSON对象传递请求相关的参数:

method属性:用来设置请求方式的。取值为 get 或者 post。

url属性:用来书写请求的资源路径。如果是 get 请求,需要将请求参数拼接到路径的后面,格式为: url?参数名=参数值&参数名2=参数值2。

data属性:作为请求体被发送的数据。也就是说如果是 post 请求的话,数据需要作为data 属性的值。

then() 需要传递一个匿名函数。我们将 then()中传递的匿名函数称为 回调函数,意思是该匿名函数在发送请求时不会被调用,而是在成功响应后调用的函数。而该回调函数中的 resp 参数是对响应的数据进行封装的对象,通过 resp.data 可以获取到响应的数据。

Axios快速入门
后端实现

查询所有员工信息服务器地址:http://yapi.smart-xwork.cn/mock/169327/emp/list

根据员工id删除员工信息服务器地址:http://yapi.smart-xwork.cn/mock/169327/emp/deleteById

前端实现

首先在VS Code中创建js文件夹,与html同级,然后将资料/axios-0.18.0.js 文件拷贝到js目录下,然后创建名为02. Ajax-Axios.html的文件,工程结果如图所示:

然后在html中引入axios所依赖的js文件,并且提供2个按钮,绑定单击事件,分别用于点击时发送ajax请求,完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initialscale=1.0">
<title>Ajax-Axios</title>
<script src="js/axios-0.18.0.js"></script>
</head>
<body>
<input type="button" value="获取数据GET" onclick="get()">
<input type="button" value="删除数据POST" onclick="post()">
</body>
<script>
function get(){
//通过axios发送异步请求-get
 }
function post(){
//通过axios发送异步请求-post
}
</script>
</html>

然后分别使用Axios的方法,完整get请求和post请求的发送

get请求代码如下:

//通过axios发送异步请求-get
axios({
method: "get",
url: "http://yapi.smart-xwork.cn/mock/169327/emp/list"
 }).then(result => {
console.log(result.data);
 })

post请求代码如下:

//通过axios发送异步请求-post
axios({
method: "post",
url: "http://yapi.smart-xwork.cn/mock/169327/emp/deleteById",
data: "id=1"
 }).then(result => {
console.log(result.data);
 })

完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initialscale=1.0">
<title>Ajax-Axios</title>
<script src="js/axios-0.18.0.js"></script>
</head>
<body>
<input type="button" value="获取数据GET" onclick="get()">
<input type="button" value="删除数据POST" onclick="post()">
</body>
<script>
function get(){
//通过axios发送异步请求-get
axios({
method: "get",
url: "http://yapi.smartxwork.cn/mock/169327/emp/list"
 }).then(result => {
console.log(result.data);
 })
 }
function post(){
// 通过axios发送异步请求-post
axios({
method: "post",
url: "http://yapi.smartxwork.cn/mock/169327/emp/deleteById",
data: "id=1"
 }).then(result => {
console.log(result.data);
 })
 }
</script>
</html>
Element

是饿了么公司前端开发团队提供的一套基于 Vue 的网站组件库,用于快速构建网页。

需要在main.js这个入口js文件中引入ElementUI的组件库,其代码如下:

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
HTTP协议特点

· 基于TCP协议: 面向连接,安全

TCP是一种面向连接的(建立连接之前是需要经过三次握手)、可靠的、基于字节流的传输层通信协议,在数据传输方面更安全

· 基于请求-响应模型: 一次请求对应一次响应(先请求后响应)

· HTTP协议是无状态协议: 对于数据没有记忆能力。每次请求-响应都是独立的

无状态指的是客户端发送HTTP请求给服务端之后,服务端根据请求响应数据,响应完后,不会记录任何信息。

缺点: 多次请求间不能共享数据

优点: 速度快

请求之间无法共享数据会引发的问题:

如:京东购物。加入购物车和去购物车结算是两次请求

由于HTTP协议的无状态特性,加入购物车请求响应结束后,并未记录加入购物车是何商品发起去购物车结算的请求后,因为无法获取哪些商品加入了购物车,会导致此次请求无法正确展示数据

具体使用的时候,我们发现京东是可以正常展示数据的,原因是Java早已考虑到这个问题,并提出了使用会话技术(Cookie、Session)来解决这个问题。

组成

HTTP协议又分为:请求协议和响应协议

请求协议:浏览器将数据以请求格式发送到服务器

包括:请求行、请求头 、请求体

响应协议:服务器将数据以响应格式返回给浏览器

包括:响应行 、响应头 、响应体

GET

获取资源。

POST

传输实体主体。

向指定资源提交数据进行处理请求(例:上传文件),数据被包含在请求体中。

PUT

传输文件。

tomcat中识别 Servlet程序-BS架构

在Tomcat这类Web服务器中,是不识别我们自己定义的Controller的。但是我们前面讲到过Tomcat是一个Servlet容器,是支持Serlvet规范的,所以呢,在tomcat中是可以识别 Servlet程序的。 那我们所编写的XxxController 是如何处理请求的,又与Servlet之间有什么联系呢?

其实呢,在SpringBoot进行web程序开发时,它内置了一个核心的Servlet程序DispatcherServlet,称之为 核心控制器。DispatcherServlet 负责接收页面发送的请求,然后根据执行的规则,将请求再转发给后面的请求处理器Controller,请求处理器处理完请求之后,最终再由DispatcherServlet给浏览器响应数据。

那将来浏览器发送请求,会携带请求数据,包括:请求行、请求头;请求到达tomcat之后,tomcat会负责解析这些请求数据,然后呢将解析后的请求数据会传递给Servlet程序的HttpServletRequest对象,那也就意味着 HttpServletRequest 对象就可以获取到请求数据。 而Tomcat,还给Servlet程序传递了一个参数 HttpServletResponse,通过这个对象,我们就可以给浏览器设置响应数据 。

那上述所描述的这种浏览器/服务器的架构模式呢,我们称之为:BS架构

BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。

day5-postman
接收参数

在Springboot的环境中,对原始的API进行了封装,接收参数的形式更加简单。 如果是简单参数,参数名与形参变量名相同,定义同名的形参即可接收参数。

@RestController
public class RequestController {
// http://localhost:8080/simpleParam?name=Tom&age=10
// 第1个请求参数: name=Tom 参数名:name,参数值:Tom
// 第2个请求参数: age=10 参数名:age , 参数值:10
//springboot方式
@RequestMapping("/simpleParam")
public String simpleParam(String name , Integer age ){//形参名和
请求参数名保持一致
System.out.println(name+" : "+age);
return "OK";
 }
}

参数名与形参变量名不同

运行没有报错。 controller方法中的username值为:null,age值为20

结论:对于简单参数来讲,请求参数名和controller方法中的形参名不一致时,无法接收到请求

解决方案:可以使用Spring提供的@RequestParam注解完成映射

在方法形参前面加上 @RequestParam 然后通过value属性执行请求参数名,从而完成映射

@RestController
public class RequestController {
// http://localhost:8080/simpleParam?name=Tom&age=20
// 请求参数名:name
//springboot方式
@RequestMapping("/simpleParam")
public String simpleParam(@RequestParam("name") String username
, Integer age ){
System.out.println(username+" : "+age);
return "OK";
 }
}

@RequestParam中的required属性默认为true(默认值也是true),代表该请求参数必须传递,如果不传递将报错

请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam 绑定参数关系

默认情况下,请求中参数名相同的多个值,是封装到数组。如果要封装到集合,要使用@RequestParam绑定参数关系

public String listParam(@RequestParam List hobby){

System.out.println(hobby);

@DateTimeFormat注解的pattern属性中指定了哪种日期格式,前端的日期参数就必须按照指定

的格式传递。

后端controller方法中,需要使用Date类型或LocalDateTime类型,来封装传递的参数。

@RestController
public class RequestController {
//日期时间参数
@RequestMapping("/dateParam")
public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd
HH:mm:ss") LocalDateTime updateTime){
System.out.println(updateTime);
return "OK";
 }
}
服务端Controller方法接收JSON格式数据:

传递json格式的参数,在Controller中会使用实体类进行封装。

封装规则:JSON数据键名与形参对象属性名相同,定义POJO类型形参即可接收参数。需要使用@RequestBody标识。

@RequestBody注解:将JSON数据映射到形参的实体类对象中(JSON中的key和实体类中的属性名保持一致)

路径参数

前端:通过请求URL直接传递参数

后端:使用{…}来标识该路径参数,需要使用@PathVariable获取路径参数

@RequestMapping("/path/{id}")
public String pathParam(@PathVariable Integer id){
System.out.println(id);
return "OK";

//多参
@RequestMapping("/path/{id}/{name}")
public String pathParam2(@PathVariable Integer id, @PathVariable
String name){
System.out.println(id+ " : " +name);
return "OK";
响应

controller方法中的return的结果,怎么就可以响应给浏览器呢?

答案:使用@ResponseBody注解

@ResponseBody注解:

类型:方法注解、类注解

位置:书写在Controller方法上或类上

作用:将方法返回值直接响应给浏览器

如果返回值类型是实体对象/集合,将会转换为JSON格式后在响应给浏览器

@RestController注解

但是在我们所书写的Controller中,只在类上添加了@RestController注解、方法添加了@RequestMapping注解,并没有使用@ResponseBody注解,怎么给浏览器响应呢?

@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
System.out.println("Hello World ~");
return "Hello World ~";
 }
}

原因:在类上添加的@RestController注解,是一个组合注解。

@RestController = @Controller + @ResponseBody

结论:在类上添加@RestController就相当于添加了@ResponseBody注解。

  1. 类上有@RestController注解或@ResponseBody注解时:表示当前类下所有的方法返回值做为响应数据

  2. 方法的返回值,如果是一个POJO对象或集合时,会先转换为JSON格式,在响应给浏览器

统一返回结果

按照统一格式的返回结果进行解析(仅一种解析方案),就可以拿到数据。

统一的返回结果使用类来描述,在这个结果中包含:

响应状态码:当前请求是成功,还是失败

状态码信息:给页面的提示信息

返回的数据:给前端响应的数据(字符串、对象、集合)

定义在一个实体类Result来包含以上信息。代码如下:

public class Result {
private Integer code;//响应码,1 代表成功; 0 代表失败
private String msg; //响应码 描述字符串
private Object data; //返回的数据
public Result() { }
public Result(Integer code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
 }
public Integer getCode() {
return code;
 }
public void setCode(Integer code) {
this.code = code;
 }
public String getMsg() {
return msg;
 }
public void setMsg(String msg) {
this.msg = msg;
 }
public Object getData() {
return data;
 }
public void setData(Object data) {
this.data = data;
 }
//增删改 成功响应(不需要给前端返回数据)
public static Result success(){
return new Result(1,"success",null);
 }
//查询 成功响应(把查询结果做为返回数据响应给前端)
public static Result success(Object data){
return new Result(1,"success",data);
 }
//失败响应
public static Result error(String msg){
return new Result(0,msg,null);
}
}

Controller:

@RestController
public class ResponseController {
//响应统一格式的结果
@RequestMapping("/hello")
public Result hello(){
System.out.println("Hello World ~");
//return new Result(1,"success","Hello World ~");
return Result.success("Hello World ~");
 }
//响应统一格式的结果
@RequestMapping("/getAddr")
public Result getAddr(){
Address addr = new Address();
addr.setProvince("广东");
addr.setCity("深圳");
return Result.success(addr);
 }
//响应统一格式的结果
@RequestMapping("/listAddr")
public Result listAddr(){
List<Address> list = new ArrayList<>();
Address addr = new Address();
addr.setProvince("广东");
addr.setCity("深圳");
Address addr2 = new Address();
addr2.setProvince("陕西");
addr2.setCity("西安");
list.add(addr);
list.add(addr2);
return Result.success(list);
 }
}
分层解耦

尽可能让每一个接口、类、方法的职责更单一些(单一职责原

则)。

单一职责原则:一个类或一个方法,就只做一件事情,只管一块功能。

这样就可以让类、接口、方法的复杂度更低,可读性更强,扩展性更好,也更利用后期的维护。

可以分为三个部分:

  1. 数据访问:负责业务数据的维护操作,包括增、删、改、查等操作。

  2. 逻辑处理:负责业务逻辑处理的代码。

  3. 请求处理、响应数据:负责,接收页面的请求,给页面响应数据。

将代码分为三层
  1. Controller:控制层。接收前端发送的请求,对请求进行处理,并响应数据。

  2. Service:业务逻辑层。处理具体的业务逻辑。

  3. Dao:数据访问层(Data Access Object),也称为持久层。负责数据访问操作,包括数据的增、删、改、查。

流程
  1. 前端发起的请求,由Controller层接收(Controller响应数据给前端)

  2. Controller层调用Service层来进行逻辑处理(Service层处理完后,把处理结果返回给Controller层)

  3. Serivce层调用Dao层(逻辑处理过程中需要用到的一些数据要从Dao层获取)

  4. Dao层操作文件中的数据(Dao拿到的数据会返回给Service层)

实例

控制层:接收前端发送的请求,对请求进行处理,并响应数据

@RestController
public class EmpController {
//业务层对象

private EmpService empService = new EmpServiceA();
@RequestMapping("/listEmp")
public Result list(){
//1. 调用service层, 获取数据
List<Emp> empList = empService.listEmp();
//3. 响应数据
return Result.success(empList);
 }
}

业务逻辑层:处理具体的业务逻辑

业务接口

//业务逻辑接口(制定业务标准)
public interface EmpService {
//获取员工列表
public List<Emp> listEmp();
}

业务实现类

//业务逻辑实现类(按照业务标准实现)
public class EmpServiceA implements EmpService {
//dao层对象
private EmpDao empDao = new EmpDaoA();
@Override
public List<Emp> listEmp() {
//1. 调用dao, 获取数据
List<Emp> empList = empDao.listEmp();
//2. 对数据进行转换处理 - gender, job
empList.stream().forEach(emp -> {
//处理 gender 1: 男, 2: 女
String gender = emp.getGender();
if("1".equals(gender)){
emp.setGender("男");
 }else if("2".equals(gender)){
emp.setGender("女");
 }
//处理job - 1: 讲师, 2: 班主任 , 3: 就业指导
String job = emp.getJob();
if("1".equals(job)){
emp.setJob("讲师");
 }else if("2".equals(job)){
emp.setJob("班主任");
 }else if("3".equals(job)){
emp.setJob("就业指导");
 }
 });
return empList;
 }
}

数据访问层:负责数据的访问操作,包含数据的增、删、改、查

数据访问接口

//数据访问层接口(制定标准)
public interface EmpDao {
//获取员工列表数据
public List<Emp> listEmp();
}

数据访问实现类

//数据访问实现类
public class EmpDaoA implements EmpDao {
@Override
public List<Emp> listEmp() {
//1. 加载并解析emp.xml
String file =
this.getClass().getClassLoader().getResource("emp.xml").getFile();
System.out.println(file);
List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
return empList;
 }
}ob = emp.getJob();

.

软件设计原则:高内聚低耦合。

高内聚指的是:一个模块中各个元素之间的联系的紧密程度,如果各个元素(语句、程序段)之间

的联系程度越高,则内聚性越高,即 "高内聚"。

低耦合指的是:软件中各个层、模块之间的依赖关联程序越低越好

程序中高内聚的体现:

EmpServiceA类中只编写了和员工相关的逻辑处理代码

程序中耦合代码的体现:

把业务类变为EmpServiceB时,需要修改controller层中的代码

.

高内聚、低耦合的目的是使程序模块的可重用性、移植性大大增强

控制反转和依赖注入

不能new,就意味着没有业务层对象(程序运行就报错),怎么办呢?

我们的解决思路是:

  • 提供一个容器,容器中存储一些对象(例:EmpService对象)

  • controller程序从容器中获取EmpService类型的对象

.

  1. 控制反转: Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转

对象的创建权由程序员主动创建转移到容器(由容器创建、管理对象)。这个容器称为:IOC容器或Spring容器

  1. 依赖注入: Dependency Injection,简称DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入

程序运行时需要某个资源,此时容器就为其提供这个资源。

例:EmpController程序运行时需要EmpService对象,Spring容器就为其提供并注入EmpService对象

IOC容器中创建、管理的对象,称之为:bean对象

案例

具体将new修改为bean对象操作看day5-52页

@Component

Service层及Dao层的实现类,交给IOC容器管理

使用Spring提供的注解:@Component ,就可以实现类交给IOC容器管理

Spring框架为了更好的标识web应用程序开发当中,bean对象到底归属于哪一层,又提供了

@Component的衍生注解:

@Controller (标注在控制层类上)

@Service (标注在业务层类上)

@Repository (标注在数据访问层类上)

在IOC容器中,每一个Bean都有一个属于自己的名字,可以通过注解的value属性指定bean的名字。如果没有指定,默认为类名首字母小写。

使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller。

.

使用四大注解声明的bean,要想生效,还需要被组件扫描注解@ComponentScan扫描

@ComponentScan注解虽然没有显式配置,但是实际上已经包含在了引导类声明注解

@SpringBootApplication 中, 默认扫描的范围是SpringBoot启动类所在包及其子包

解决方案:手动添加@ComponentScan注解,指定要扫描的包 ( 仅做了解,不推荐 )

.

@Autowired

使用Spring提供的注解:@Autowired ,就可以实现程序运行时IOC容器自动注入需要的依赖对象

Autowired翻译过来叫:自动装配。

.

那如果在IOC容器中,存在多个相同类型的bean对象,程序运行会报错

解决上述问题呢?Spring提供了以下几种解决方案:

  • @Primary(默认实现)

  • @Qualifier(指定名称)

  • @Resource(指定名称)

使用@Primary注解:当存在多个相同类型的Bean注入时,加上@Primary注解,来确定默认的实现。

@Qualifier注解:指定当前要注入的bean对象。 在@Qualifier的value属性中,指定注入的bean的名称。

@Qualifier注解不能单独使用,必须配合@Autowired使用

@Resource注解:是按照bean的名称进行注入。通过name属性指定要注入的bean的名称。

面试题 : @Autowird 与 @Resource的区别

@Autowired 是spring框架提供的注解,而@Resource是JDK提供的注解

@Autowired 默认是按照类型注入,而@Resource是按照名称注入

SQL语句根据其功能被分为四大类:DDL、DML、DQL、DCL

DDL:数据定义语言,用来定义数据库对象(数据库,表,字

段)

DML:数据操作语言,用来对数据库表中的数据进行增删改

DQL:数据查询语言,用来查询数据库中表的记录

DCL:数据控制语言,用来创建数据库用户、控制数据库的

访问权限

sql
数据库操作

创建数据库

create database [ if not exists ] 数据库名;

删除数据库

drop database [ if exists ] 数据库名 ;

创建表

create table 表名(

字段1 字段1类型 [约束] [comment 字段1注释 ],

字段2 字段2类型 [约束] [comment 字段2注释 ],

......

字段n 字段n类型 [约束] [comment 字段n注释 ]

) [ comment 表注释 ] ;

约束描述关键字
非空约束限制该字段值不能为nullnot null
唯一约束保证字段的所有数据都是唯一、不重复的unique
主键约束主键是一行数据的唯一标识,要求非空且唯一primary key
默认约束保存数据时,如果未指定该字段值,则采用默认值default
外键约束让两张表的数据建立连接,保证数据的一致性和完整性foreign key

在上述的表结构中:

id 是一行数据的唯一标识

username 用户名字段是非空且唯一的

name 姓名字段是不允许存储空值的

gender 性别字段是有默认值,默认为男

create table tb_user (
 id int primary key comment 'ID,唯一标识',
 username varchar(20) not null unique comment '用户名',
 name varchar(10) not null comment '姓名',
 age int comment '年龄',
 gender char(1) default '男' comment '性别'
) comment '用户表';

主键自增:auto_increment

每次插入新的行记录时,数据库自动生成id字段(主键)下的值

具有auto_increment的数据列是一个正数序列开始增长(从1开始自增)

.

数据类型

很多大整数值

SMALLINT

BIGINT

TINYINT

类型大小有符(SIGNED)范围无符号(UNSIGNED)范围描述
数值类型
INT/INTEGER4bytes(-2147483648,2147483647)(0,4294967295)大整数值
FLOAT4bytes(-3.402823466 E+383.402823466351 E+38)0 和 (1.175494351 E- 38,3.402823466 E+38)单精度浮
点数
DOUBLE8bytes双精度浮
点数
字符串类型
VARCHAR0-65535 bytes变长字符串(需要指定长度)
CHAR0-255 bytes定长字符串(需要指定长度)
TEXT0-65 535 bytes长文本数据
日期时间类型
DATEYYYY-MM-DD日期值

char 与 varchar 都可以描述字符串,char是定长字符串,指定长度多长,就占用多少个字符,和字段值的长度无关 。而varchar是变长字符串,指定的长度为最大占用长度 。相对来说,char的性能会更高些。

示例:

年龄字段 ---不会出现负数, 而且人的年龄不会太大

age tinyint unsigned

分数 ---总分100分, 最多出现一位小数

score double(4,1)

生日字段 birthday ---生日只需要年月日

birthday date

创建时间 createtime --- 需要精确到时分秒

createtime datetime

添加字段

添加字段

alter table 表名 add 字段名 类型(长度) [comment 注释] [约束];

修改数据类型

alter table 表名 modify 字段名 新数据类型(长度);

alter table 表名 change 旧字段名 新字段名 类型(长度) [comment 注释][约束];

删除字段

alter table 表名 drop 字段名;

删除表语法:

drop table [ if exists ] 表名;

sql操作

insert语法:

向指定字段添加数据
insert into 表名 (字段名1, 字段名2) values (值1, 值2);
批量添加数据(指定字段)
insert into 表名 (字段名1, 字段名2) values (值1, 值2), (值1, 值2);
全部字段添加数据
insert into 表名 values (值1, 值2, ...); 
批量添加数据(全部字段)
insert into 表名 values (值1, 值2, ...), (值1, 值2, ...);

update语法:

update 表名 set 字段名1 = 值1 , 字段名2 = 值2 , .... [where 条件] ;

update tb_emp set name='张三',update_time=now() where id=1;

delete语法:

delete from 表名 [where 条件] ;

delete from tb_emp where id = 1;

注意事项:

• DELETE 语句的条件可以有,也可以没有,如果没有条件,则会删除整张表的所有数据。

• DELETE 语句不能删除某一个字段的值(可以使用UPDATE,将该字段值置为NULL即可)。

• 当进行删除全部数据操作时,会提示询问是否确认删除所有数据,直接点击Execute即可。

  • 27
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值