本文部分我是在B站看的尚硅谷教程,教程官网也有下载,
引自spring bean是什么
Bean是Spring框架中最核心的两个概念之一(另一个是面向切面编程AOP)。
Spring 官方文档对 bean 的解释是:
In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container.
在 Spring 中,构成应用程序主干 并由Spring IoC容器管理的对象称为bean。bean是一个由Spring IoC容器实例化、组装和管理的对象。
概念简单明了,我们提取处关键的信息:
Bean有时候,会称呼为功能类bean,Bean的ID 就是 将原本类名的第一个字母变成小写
在Spring中,你不需要自己创建对象,你只需要告诉Spring,哪些类我需要创建出对象,然后在启动项目的时候Spring就会自动帮你创建出该对象,相当于我们把控制权交给了Spring,我们不用写一个new ,但是后台会帮你把需要的类的实例都创建好,你只需要声明你用那个类就行。
下面使用官网的一个例子来说明
您可以自由使用任何标准的Spring框架技术来定义bean及其注入的依赖项(这里我的理解就是 一个类里面 有另一个类的属性,比如StudentManage 类 有 Student类的属性)。为了简单起见,我们经常发现使用@ComponentScan(查找bean)和使用@Autowired(进行构造函数注入)
以下示例显示了一个@Service Bean,它使用构造函数注入来获取所需的RiskAssessor Bean:
package com.example.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DatabaseAccountService implements AccountService {
private final RiskAssessor riskAssessor;
@Autowired
public DatabaseAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}
// ...自动正在了函数参数,并赋值给类的属性
}
参考网址:https://blog.csdn.net/litavadaski/article/details/79487945
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-spring-beans-and-dependency-injection
在Spring中,bean可以被定义为两种模式:prototype(多例)和singleton(单例)
singleton(单例):只有一个共享的实例存在,所有对这个bean的请求都会返回这个唯一的实例。
prototype(多例):对这个bean的每次请求都会创建一个新的bean实例,类似于new。
参考网址:https://blog.csdn.net/w1014074794/article/details/88403568
@SpringBootApplication 注解本身包含了很多注解了,其实他自身就相当于
下面三个注释
您应该只添加一个@springbootsapplication或@EnableAutoConfiguration注释。我们通常建议您只将其中一个添加到主@Configuration类中
在启动类上加上@SpringBootApplication注解,当前包下或者子包下所有的类都可以扫到。
下面这个图展示的时候,是用平面模式展示包的,在Eclispe可以设置
包展示设置
结果如下
所以这样我们使用的请求处理SpringBoot也就能识别到了
当然还可以不使用默认的约定,我们自己手动指定
我们再通过Ctrl+左键会进入爷爷辈工程里面的pom.xml文件
会发现有个DepencyManagement,DepencyManagement应用场景
当我们的项目模块很多的时候,我们使用Maven管理项目非常方便,帮助我们管理构建、文档、报告、依赖、scms、发布、分发的方法。可以方便的编译代码、进行依赖管理、管理二进制库等等。
由于我们的模块很多,所以我们又抽象了一层,抽出一个itoo-base-parent来管理子项目的公共的依赖。为了项目的正确运行,必须让所有的子项目使用依赖项的统一版本,必须确保应用的各个项目的依赖项和版本一致,才能保证测试的和发布的是相同的结果。
在我们项目顶层的POM文件中,我们会看到dependencyManagement元素。通过它元素来管理jar包的版本,让子项目中引用一个依赖而不用显示的列出版本号。Maven会沿着父子层次向上走,直到找到一个拥有dependencyManagement元素的项目,然后它就会使用在这个dependencyManagement元素中指定的版本号。
就是省略了我们引入依赖后,还需要自己确定版本号,避免了出兼容bug的问题
SpringBoot根据行业多年积累,将典型应用场景抽取出来,每个场景封装成一个starter.导入一个场景的starter,就能够导入这个场景所需要的全部ar包,非常方便。对于开发者来说,需要使用什么场景,就导入对于的starter即可。
开发Web,肯定web的Starter要添加的,或者直接自己到pom去手动添加
@Controller配合@ResponseBody等价与@RestController
@Controller用于标记在一个类上,使用它标记的类就是一个SpringMvc Controller对象,分发处理器会扫描使用该注解的类的方法
@ResponseBody 通常注解在方法上,作用是将Controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据。
如果一个Controller类全都是返回的JSON数据,而不会跳转页面,直接在该类上使用@RestController
@RequestMapping注释提供了“路由”信息。它告诉Spring,任何带有/路径的HTTP请求都应该映射到home方法。
RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
@GetMapping等价于@RequestMapping的GET请求方式
@RestController
@RequestMapping("/user")
public class HelloController {
//@RequestMapping(value = "hello", method= RequestMethod.GET )
@GetMapping("hello") // 响应 http://localhost:8080/user/hello
public String hello() {
return "hello spring boot";
}
}
参考:https://blog.csdn.net/weixin_42323802/article/details/83626041
https://blog.csdn.net/ff906317011/article/details/78552426
参考 SpringBoot-@RequestParam
先说@RequestParam ,Request参数
在访问各种各样网站时,经常会发现网站的URL的最后一部分形如:?xxxx=yyyy&zzzz=wwww。这就是HTTP协议中的Request参数
比如我们在知乎中搜索web
浏览器跳转到新页面后,
URL变为https://www.zhihu.com/search?type=content&q=web
这里type=content&q=web就是搜索请求的参数,不同参数之间用&分隔,每个参数形如name=value形式,分别表示参数名字和参数值。
我们输入不同的搜索关键词,在搜索结果页面的URL的q参数是不同的,也就是说,HTTP参数实际上可以认为是一种用户的输入,根据不同的用户输入,服务器经过处理后返回不同的输出(例如搜索spring和搜索java,显示结果是不一样的。)
@RequestParam对POST支持主要是form-data和x-www.form-unencoded两种编码
下面是一个实例,关于@RequestParam get方法的实例,其中下面的第二种方法,我们其实可以完全省略 @RequestParam
@Controller
public class MyWeb {
@GetMapping("/ceshi1")
@ResponseBody
public String ceshi(int i) {
return "ceshi1";
}
//省略写法
@GetMapping("/ceshi2")
@ResponseBody
public String ceshi2(@RequestParam(name = "i")Integer i) {
return "ceshi2";
}
}
但是写上@RequestParam 注解的灵活性更大,我们可以看到 注解里面可以设置的三个重要属性
name 就是说参数的名字,比如我们请求变为
http://localhost:8080/ceshi1?id=2,我们如果想在后台得到参数名为id的具体数值
public String ceshi2(@RequestParam(name="id")Integer i) {
return "ceshi2,参数i为:"+ i;
}
这样参数i 的数值就是2了。
而defaltValue 顾名思义了,默认参数,通常会配合required使用
如果我们的映射函数仍然如下图
@GetMapping("/ceshi2")
@ResponseBody
public String ceshi2(@RequestParam(name="id")Integer i) {
return "ceshi2,参数i为:"+ i;
}
访问http://localhost:8080/ceshi2 肯定报错,因为我们虽然有处理/ceshi2的映射函数,但是这个函数必须要求有名为id的参数
修改代码位
@GetMapping("/ceshi2")
@ResponseBody
public String ceshi2(@RequestParam(name="id",required = false)Integer i) {
return "ceshi2,参数i为:"+ i;
}
可以看到参数i的 数值是null,那么我们只要再指定一个默认值属性,再访问下面的网址,参数i的值就是我们指定的默认值
当然前端也是可以使用ajax的GET方法或者 form标签 get方式
上面的是直接通过GET 方法,使用网址访问的,当然也是可以通过ajax get访问的
$("#send1").click(function() {
$.ajax({
url : "/send1", // 请求的url地址
//dataType : "json", // 返回格式为json
type : "get", // 请求方式
success : function(data) {
console.log(data);
}
})
});
@GetMapping("/send1")
@ResponseBody
public student resGET() {
//System.out.println(stu.getId()+" , "+stu.getName());
String str="{\"id\":1,\"name\":\"wo\"}";
student stu=new student(123, "qwdqw");
return stu;
}
如果是返回json字符串
@GetMapping("/send1")
@ResponseBody
public String resGET() {
//System.out.println(stu.getId()+" , "+stu.getName());
String str="{\"id\":1,\"name\":\"wo\"}";
return str;
}
如果使用POST方法,比如在SpringBoot 官网上就有一个上传文件的演示Demo
当然 需要之前的get 映射 修改为post映射了
然后我们测试一下,在一个HTML中代码如下
显示为
在浏览器通过F12调试
当form的 enctype= “multipart/form-data” 时发送的POST输出 payload为
首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 mutipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 –boundary 开始,紧接着内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 –boundary– 标示结束
引自:https://www.cnblogs.com/jpfss/p/10449287.html
当 enctype=“application/x-www-form-urlencoded” 。 浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。提交的数据按照 key1=val1&key2=val2 的方式进行编码
但是上面两种方法 都可以使用 @RequestParam(“id”) String id 来获取name=id 的input ,但是最大的区别就是,默认的 application/x-www-form-urlencoded的方法传递文件其实就是传递个文件名字,传文件还是第一种编码multipart/form-data
后台获取文件对象 :@RequestParam(“file”) MultipartFile file
图片来自:https://www.cnblogs.com/anywherego/p/9600871.html
contentType=“application/json” 这个类型在HTML中的form标签中设置没用,还是会按照application/x-www-form-urlencoded的类型来传递请求。
但是ajax 中可以设置响应头类型为form-data,不设置就是默认的x-www-form-urlencoded类型,如下代码
$.ajax({
url:"/login/searchface", //请求的url地址
dataType:"json", //返回格式为application/json
async:true,//请求是否异步,默认为异步,这也是ajax重要特性
//contentType:"application/json",
//设置请求头的 类型,这里就是默认的application/x-www-form-urlencoded类型
data: {"imagebast64": img} , //参数值 传递的就是json对象
type: "POST", //请求方式
success: function (data) {
}
})
后台映射函数 参数 为@RequestParam(“file”) MultipartFile file
如果是JSON对象
$("#send1").click(function(){
$.ajax({
url:"/send1", //请求的url地址
dataType:"json", //返回格式为json
async:true,//请求是否异步,默认为异步,这也是ajax重要特性
//contentType:"application/json",
data: {"id":1,"name":123}, //参数值
type: "POST", //请求方式
success: function (data) {
console.log(data);
}
})
});
后台响应
@PostMapping("/send1")
@ResponseBody
public String resPost(@RequestParam String name) {
//System.out.println(stu.getId()+" , "+stu.getName());
System.out.println(name);
String str="{\"id\":1,\"name\":\"wo\"}";
return str;
}
如果用ajax 配合multipart/form-data 会麻烦一点
必须将contentType选项设置为false,强制jQuery不Content-Type为您添加标题,否则,边界字符串将丢失。此外,您必须将processData标志设置为false,否则,jQuery将尝试将您FormData转换为字符串,这将失败。
var request = new FormData();
request.append('name', 'upload');
request.append('id', 123);
$("#send1").click(function() {
$.ajax({
type : 'POST',
url : "/send1",
data : request,
processData : false,
contentType : false,
success : function(r) {
console.log(r);
// if (errors != null) { } else context.close();
},
error : function(r) {
alert('jQuery Error');
}
})
});
后台
@PostMapping("/send1")
@ResponseBody
public String resPost(@RequestParam String name) {
//System.out.println(stu.getId()+" , "+stu.getName());
System.out.println(name);
String str="{\"id\":1,\"name\":\"wo\"}";
return str;
}
如果只是form表单的普通post方法就简单了,就设置一下enctype就行了
@PostMapping("/form")
@ResponseBody
public String resPost2(@RequestParam String name) {
//System.out.println(stu.getId()+" , "+stu.getName());
System.out.println(name);
String str="{\"id\":1,\"name\":\"wo\"}";
return str;
}
引自:https://blog.csdn.net/ff906317011/article/details/78552426
@PathVariable 注解,其用来获取请求路径(url )中的动态参数。例如/blogs/1
而@RequestParam是在在参数部分 例如blogs?blogId=1
因为@PathVariable 是根据URL路径访问的,URL中模板变量{id}绑定到通过@PathVariable注解的同名参数
实例如下
@GetMapping("/ceshi3/{id}")
@ResponseBody
public String ceshi3(@PathVariable(name="id")Integer i) {
return "ceshi2,参数i为:"+ i;
}
访问测试:
当然前端也是可以自己写代码访问的
使用 AJAX 的 HTTP GET 请求从服务器加载数据
function login() {
var url = "${pageContext.request.contextPath}/person/login/";
var query = $('#id').val() + '/' + $('#name').val() + '/' + $('#status').val();
url += query;
$.get(url, function(data) {
alert("id: " + data.id + "name: " + data.name + "status: "
+ data.status);
});
}
后端
/**
* @RequestMapping(value = "user/login/{id}/{name}/{status}") 中的 {id}/{name}/{status}
* 与 @PathVariable int id、@PathVariable String name、@PathVariable boolean status
* 一一对应,按名匹配。
*/
@RequestMapping(value = "user/login/{id}/{name}/{status}")
@ResponseBody
//@PathVariable注解下的数据类型均可用
public User login(@PathVariable int id, @PathVariable String name, @PathVariable boolean status) {
//返回一个User对象响应ajax的请求
return new User(id, name, status);
}
先介绍一下json对象,首先说到对象的概念,对象的属性是可以用:对象.属性进行调用的。例如: 引自:https://www.cnblogs.com/agansj/p/9053547.html
var person={"name":"tom","sex":"男","age":"24"}//json对象
console.log(person.name);//在控制台输出tom
alert(typeof(person));//object
以上就是json对象。是一个用perosn.name这种方式进行属性的调用。第三行代码就是看person的类型,为object类型。
JSON字符串
字符串,我们常说的javascript中的字符串是单引号或者双引号引起来的。那么json字符串是什么概念呢?
var b='{"name":"2323","sex":"afasdf","age":"6262"}';//json字符串
console.log(b);//{"name":"2323","sex":"afasdf","age":"6262"}
alert(typeof(b));//string
以上就是b就是一个字符串,也是一个json字符串,之所以叫json字符串,因为字符串的格式符合json的格式,所以叫做json字符串,第三行代码也匹配其中的类型为string。
二者转换如下
JSON字符串到JSON对象
var b='{"name":"2323","sex":"afasdf","age":"6262"}'//json字符串
var bToObject=JSON.parse(b);
console.log(bToObject.name);//2323
JSON对象到JSON字符串
var a={"name":"tom","sex":"男","age":"24"}//json对象
var aToString=JSON.stringify(a);
console.log(aToString);//{"name":"tom","sex":"男","age":"24"}
Post请求也可以直接与对象类绑定,但需要参数名一致,不支持json字符串格式,只支持form-data和x-www.form-urlencoded格式
下图直接传递的就是一个JSON对象
$("#send1").click(function(){
$.ajax({
url:"/send1", //请求的url地址
dataType:"json", //返回格式为json
async:true,//请求是否异步,默认为异步,这也是ajax重要特性
//contentType:"application/json",
data: {id: 11,name: "asd"} , //参数值
type: "POST", //请求方式
success: function (data) {
console.log(data);
}
})
});
@PostMapping("/send1")
@ResponseBody
public String resPost(student stu) {
//System.out.println(stu.getId()+" , "+stu.getName());
System.out.println(stu.getName());
String str="{\"id\":1,\"name\":\"wo\"}";
return str;
}
@RequestBody接受的是一个json格式的字符串,一定是一个字符串。
Post使用@RequestBody注解将Json格式的参数自动绑定到Entity类,但是需要是JSON字符串
发送的json对象必须要使用JSON.stringify进行序列化成字符串才能和设定的这个类型匹配。同时,对应的后端如果使用了Spring,接收时需要使用@RequestBody来注解,这样才能将发送过来的json字符串解析绑定到对应的 pojo 属性上。另外,需注意一点,json字符串在书写时名称部分需要加上“”双引号,以免一些json解析器无法识别。
@RequestBody 注解详解
作用:
var obj={};
obj.id=1;
obj.name="aadaqwwe";
JSON.stringify(obj);
//{"id": 11,"name": "asd"}
//{id: 11,name: "asd"}
$("#send1").click(function(){
$.ajax({
url:"/send1", //请求的url地址
dataType:"json", //返回格式为json
async:true,//请求是否异步,默认为异步,这也是ajax重要特性
contentType:"application/json",//设置为application/json,必须传递字符串
data: JSON.stringify(obj) , //参数值
//data: '{"id":1,"name":123} ', //参数值 也可以
type: "POST", //请求方式
success: function (data) {
console.log(data);
}
})
});
@PostMapping("/send1")
@ResponseBody
public String resPost(@RequestBody student stu) {
//System.out.println(stu.getId()+" , "+stu.getName());
System.out.println(stu.getName());
String str="{\"id\":1,\"name\":\"wo\"}";
return str;
}
参考网址 https://www.cnblogs.com/anywherego/p/9600871.html
https://www.cnblogs.com/hanszhao/p/10166277.html
更改一下配置:
添加了下面两行
server.port=1000
server. servlet.context-path=/atguigu
第一行是修改端口,默认是8080现在是1000
第二行是在我们运行时候添加一些路径,我们默认启动如下图
ip地址加端口号,但是现在添加配置后,不行了,如题下图
访问地址改为如下图了,更改配置时候,atguigu前面的/必须要有
这里直接在test里面运行,所以
先建立一个student类
properties文件的属性命名必须全部小写或以中横线分割,绝对不能出现大写
package com.example.demo.entity;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
//读取配置文件,要求当前类也在IOD容器中
@Component
@ConfigurationProperties(prefix="student") //这里配置文件就是默认的application
//就不用在使用@PropertySource(value="classpath:自定义的配置文件.properties", encoding="UTF-8")保存
//指定配置文件源了
public class Student {
private Integer stuID;
private String stuName;
private String position;
public Student() {
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "Student [stuID=" + stuID + ", stuName=" + stuName + ", position=" + position + "]";
}
public Integer getStuID() {
return stuID;
}
public void setStuID(Integer stuID) {
this.stuID = stuID;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
}
需要添加两个注释,然后添加依赖
注意加入configuration-processor依赖后,在属性文件写的时候会有提示
然后代码创建的时候,需要无参构造器 有参构造器 每个内部变量的set 和get方法,以及tosstring方法,这些我们的Eclipse都能提供,别害怕,都能提供
然后在test的主类里面输入如下,打印到控制台,让我们查看
运行结果
上面是在test里面运行了,如果想在main中运行,那么可以借助CommandLineRunner 接口实现,两种方式,第一种是在主启动类里面直接实现 CommandLineRunner 接口
然后会提示有没有实现的方法
添加CommandLineRunner 接口未实现的run方法
整体代码如下
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
Logger log = LoggerFactory.getLogger(Handler.class);
@Autowired
private Student stu;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
// TODO Auto-generated method stub
log.info(stu.toString());
}
还有一种就好一点,从新新建一个类,来实现CommandLineRunner 接口,并且重载run方法,就行,记得添加@Component 注解
@Component
public class CommandLineRunnerImpl implements CommandLineRunner {
Logger log = LoggerFactory.getLogger(Handler.class);
@Autowired
private Student stu;
@Override
public void run(String... args) throws Exception {
log.info(stu.toString());
}
}
但是会发现配置文件读取的中文字符是乱码
换成UTF-8 点击apply应用,但是并没有解决配置文件中文乱码的问题。。无语
把能改的都改了,配置文件中的中文还是无法传输到类的变量里面
然后最终找到原因了,properties文件的问题,可以用yml文件来代替
properties文件,yml文件是支持中文的,默认utf-8编码,或者在IDEA上面勾选下面的选项
Transparent native-to-ascii conversion的意思是:自动转换ASCII编码。
他的工作原理是:在文件中输入文字时他会自动的转换为Unicode编码,然后在idea中发开文件时他会自动转回文字来显示。
这样做是为了防止文件乱码。。。
原因涉及到源码问题,
SpringBoot使用@Value读取.properties中文乱码及解决方法
Spring properties文件中文乱码的原因及解决方案
其实就是properties的默认读取不是utf8,而且默认的properties文件是不能修改编码方式的。
要不然就是这直接输入\u8863\u9f99\u5ddd这种编码后的字符,要不然就如下图,自己定义一个配置文件,就能通过注解定义编码方式了
value有个好处就是直接在控制类或者其他类使用,啥都哦不用做,省的再新建一个实体类了,当然如果是你自己新建的 自定义配置文件,还需要添加一个@PropertySource(value=“classpath:application2.properties”, encoding=“UTF-8”)注解(UTF-8 只是为了方便中文输出)
再次补充一下Date类添加属性里面的时间配置
下图是属性里面的时间变量
对应的实体类如下
但是如果时间的格式比较特殊,我们就不能使用Date的默认格式了 1995-10-22了,只能使用注解搞定
配置文件还是尽量全小写为好,而且字符串也不用加引号,直接写就行
自动配置类所在的属性
想查看具体的自动化配置类就是用ctrl shift t 输入名字就好
拿RabbitAutoConfiguration自动化配置类举例,
打开划线部分的具体属性类RabbitProperties.class
会发现都是定义的各种配置属性
数据库连接池的作用:
建立数据库连接是相当耗时和耗费资源的,而且一个数据库服务器能够同时建立的连接数也是有限的,在大型的Web应用中,可能同时会有成百上千个访问数据库的请求,如果Web应用程序为每一个客户请求分配一个数据库连接,将导致性能的急剧下降。为了能够重复利用数据库连接,提高对请求的响应时间和服务器的性能,可以采用连接池技术。连接池技术预先建立多个数据库连接对象,然后将连接对象保存到连接池中,当客户请求到来时,从池中取出一个连接对象为客户服务,当请求完成后,客户程序调用close()方法,将连接对象放回池中。
在普通的数据库访问程序中,客户程序得到的连接对象是物理连接,调用连接对象的close()方法将关闭连接,而采用连接池技术,客户程序得到的连接对象是连接池中物理连接的一个句柄,调用连接对象的close()方法,物理连接并没有关闭,数据源的实现只是删除了客户程序中的连接对象和池中的连接对象之间的联系。引自:https://blog.csdn.net/u011038738/article/details/80680215
MyBatis,他是真正和数据库打交道了,他上面是连接池
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。引自:https://www.w3cschool.cn/mybatis/
OK,介绍完毕后,尝试配置使用MyBatis 和druid 连接数据库
第一步:
建立一个新的项目,导入两个包
添加依赖去,xml文件注释 快捷键就是ctrl shift 和/
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.0
mysql
mysql-connector-java
com.alibaba
druid
1.0.5
搞定数据库表单,我这里使用的免解压版本的mysql
然后用可视化工具连接一下
新建一个表单
创建一个表,使用SQL语句创建
CREATE TABLE `table_emp` (
`emp_id` int NOT NULL AUTO_INCREMENT ,
`emp_name` varchar(100) NULL ,
`emp_age` int NULL ,
PRIMARY KEY (`emp_id`)
)
ok,到此我们数据库就搞定了,剩下的就是配置SpringBoot了
首先,我们有了表了,这个表在SpringBoot就看成一个类了 (术语好像叫持久化对象),所以新建一个实体的类,类里面的属性和数据库的表对应
Emp.java代码如下
package com.example.demo.entity;
public class Emp {
private Integer empId;
private String empName;
private Integer empAge;
// 写完三个类,然后就是 无参 有参 构造器 每个参数的set 和get方法,以及tostring方法
//右键选择source 就看到自动生成的选项了
public Emp(Integer empId, String empName, Integer empAge) {
super();
this.empId = empId;
this.empName = empName;
this.empAge = empAge;
}
public Emp() {
super();
// TODO Auto-generated constructor stub
}
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Integer getEmpAge() {
return empAge;
}
public void setEmpAge(Integer empAge) {
this.empAge = empAge;
}
@Override
public String toString() {
return "Emp [empId=" + empId + ", empName=" + empName + ", empAge=" + empAge + "]";
}
}
然后新建一个接口,下面图选错了,应该是一个接口
完毕后,一个包的名字,一个接口类的名字
接口中的代码如下
package com.example.demo.mapping;
import java.util.List;
import com.example.demo.entity.*;
public interface EmpMapper {
List selectAll();
}
建立Mybatis 的映射文件
打开文件后输入一下代码,注意
不知道具体路径,查看方法如下
关于Myybatis的配置文件xml的解释参考了如下网址:Mybatis笔记(一)-----Mybatis基础xml配置文件解释
上面的mapper 标签 为这个mapper指定一个唯一的namespace,
它习惯上设置为:“包名+sql映射文件名”,这样可以保值名的唯一。
这是一个带参数的查询语句
为这个mapper指定一个唯一的namespace,它习惯上设置为:“包名+sql映射文件名”,这样可以保值名的唯一。
id:这个select语句的id
parameterType:指定查询是传入的参数类型
resultType:即返回结果集的类型,这理指定为User类型
useGeneratedKeys="true" 使用数据库的自动增长策略
我们这里没有用这个带参数的SQL语句
然后再主启动类里面添加@MapperScan(“com.example.demo.mapping”)
还是需要注意你定义接口所在的位置
这里使用了@MapperScan(“com.example.demo.mapping”)注解扫描Mapper接口所在的包。配置了这个扫描我们才能对Mapper接口进行自动装配。
package com.example.demo;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.example.demo.entity.Emp;
import com.example.demo.mapping.EmpMapper;
@SpringBootTest
class Demo1ApplicationTests {
//添加如下代码
@Autowired
private EmpMapper empMapper;
@Test
void contextLoads() {
}
//添加如下代码
@Test
public void testSelectAll() {
List selectAll = empMapper.selectAll();
for (Emp emp : selectAll) {
System.out.println(emp);
}
}
}
什么是服务器端渲染?
除了我们熟悉的JSP,还有Velocity、Freemarker、Thymeleaf等视图模板技术。虽然具体语法各不相同,但是它们都有一个共通的特点,就是在固定内容中可以穿插表达式等形式的动态内容。将视图模板中的动态内容转换为对应的Java代码并执行,然后使用计算得到的具体数据替换原来的动态部分。这样整个文件的动态内容就可以作为确定的响应结果返回给浏览器。在这种模式下,前端工程师将前端页面全部开发完成,交给后端程序员加入到项目中。此时不可避免的需要后端程序员根据需要对前端代码进行补充和调整。
然后还有一点就是 是什么是前后端分离?
前后端分离模式下,前端程序和后端程序使用JSON格式进行交互,所以项目启动时前端工程和后端工程师需要坐在一起开会,商量确定JSON格式的具体细节。然后分头开发。后端工程师在把后端的代码发布到测试服务器前,前端工程师无法调用后端程序拿到真实数据,所以使用Mock.js生成假数据。直到后端工程师开发完成,后端程序发布到了测试服务器上,前端工程师再从Mock.js切换到实际后端代码。
需要注意就是对于图片怎么处理的
我们传统或者小型项目,对于图片,不论是上传的还是 给前端展示的图片都是直接在服务器端的本地目录下面
但是其实实际中的前后端分离中,JSON是保存图片的地址,而图片是位于另外的服务器里面的,功能分离开。
然后是为什么JSP不好?
打开一个JSP文件就知道了,是下面这种鬼东西
但是如果使用Thymeleaf
你写的就是一个HTML文件,肯定可以直接打开,而且你也可以通过Thymeleaf 的标签指定值 如1处的标记,你直接通过浏览器打开HTML文件就是看到的2出的标记,通过访问你建立的Web 地址就可以看到1处的标记
下面是如何使用Thymeleaf了
首先在项目pom.xml里面添加依赖
org.springframework.boot
spring-boot-starter-thymeleaf
然后在application.yml 中输入
spring:
thymeleaf:
cache: false #开发的时候禁用缓存 注意false前面是有一个空格的
表达式语法(重点)
public class User {
String name;
int age;
User friend;// 对象类型属性
}
那么控制类里面的响应方法如下
@RequestMapping("/test2")
public String test2(Model model){
User user = new User();
user.setAge(21);
user.setName("Jackson");
user.setFriend(new User("李小龙", 30));
model.addAttribute("user", user);//直接存入对象对好了
return "hello2";
}
页面的标签写法如下
你好:请跟我来
参考网址 Thymeleaf从入门到吃灰 和 Model_ModelMap_Map