#添加并配置第三方数据源
#1.设置数据源类型
spring.databsource.type = com.alibaba.druid.pool.DruidDataSource
#2.设置初始化连接数
spring.databsource.druid.initial-size = 20
#3.设置最小空闲数量
spring.databsource.druid.max-active = 100
#4.设置最大连接量
spring.databsource.druid.max-active = 100
- 配置 mybatis 相关配置
在项目中编写的 XML 映射文件,Spring Boot并无从知晓,所以无法扫描到该自定义编写的 XML 映射文件,需要在全局配置文件 application.yml / application.properties 中添加 Mybatis映射文件的路径,同时也可以添加实体类的别名设置。
- 这是yaml写法
mybatis:
mapper-locations: classpath:mapper/*Mapper.xml # mapper映射文件路径
type-aliases-package: com.sangeng.domain # 配置哪个包下的类有默认的别名
- 这是 properties 写法
#mybatis取别名
mybatis.type-aliases-package=com.sangeng.domain
#扫描映射文件
mybatis.mapper-locations=classpath*:mapper/*Mapper.xml
- 编写 Mapper 接口
注意在接口上加上 @Mapper
和 @Repository
注解
@Repository
@Mapper
public interface UserMapper {
public List findAll();
}
- 编写mapper接口对应的xml文件(也可以使用插件一键生成)
<?xml version="1.0" encoding="UTF-8" ?>
select * from user
- 测试
@SpringBootTest(classes = HelloApplication.class)
public class SpringMyTest {
@Autowired
UserMapper userMapper;
@Test
public void tesMapper(){
System.out.println(userMapper.findAll());
}
}
3.2、加载Mapper接口方式
SpringBoot 整合 MyBatis 加载 Mapper 接口的方式有两种,一是在对应的接口类上添加 @Mapper
注解,二是在 Spring Boot 启动器类上添加 @MapperScan("xxx")
注解(推荐使用此方式)
3.2.1、@Mapper注解
在对应的接口类上添加 @Mapper
注解,如果编写的 Mapper 接口过多时,需要重复为每一个 Mapper 接口文件添加 @Mapper
注解,代码如下所示:
- UserMapper接口
@Mapper
public interface UserMapper{
// 省略接口方法
}
2. RoleMapper接口
@Mapper
public interface RoleMapper{
// 省略接口方法
}
3.2.3、@MapperScan注解
为了避免 @Mapper
注解重复添加的麻烦,可以直接在 Spring Boot 启动器类上 添加@MapperScan("xxx")
注解。不需要再为每一个 Mapper 接口添加 @Mapper
注解。
@MapperScan("xxx")
注解的作用和@Mapper
注解类似,但是它必须制定需要扫描的具体包名,例如 @MapperScan(“com.xxx.dao”)- 扫描多个包时可以使用英文逗号分隔,例如: @MapperScan(“com.xxx.mapper”)
@SpringBootApplication
// 扫描mapper接口所在的包
@MapperScan(basePackages = “com.kuang.dao”)
public class SpringbootBdqnApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootBdqnApplication.class, args);
}
}
4、web开发
4.1、静态资源访问
由于SpringBoot的项目是打成jar包的所以没有之前web项目的那些web资源目录(webapps)。那么我们的静态资源要放到哪里呢?
从SpringBoot官方文档中我们可以知道,我们可以把静态资源放到 resources/static
(或者resources/public
或者resources/resources
或者 resources/META-INF/resources
) 中即可。
static目录
- 该目录存放静态资源,可放置 css、js、图片、html 等静态资源
- 该目录可以直接访问
templates目录
- 该目录下存放网页模板,如 thymeleaf 等模板
- 该目录是安全的,外界不可直接访问,类似web项目中的WEB-INF文件夹
静态资源放完后
- 例如我们想访问文件:resources/static/index.html 只需要在访问时资源路径写成/index.html即可。
- 例如我们想访问文件:resources/static/pages/login.html 访问的资源路径写成: /pages/login.html
4.1.1、修改静态资源访问路径
SpringBoot默认的静态资源路径匹配为 /**
。如果想要修改可以通过 spring.mvc.static-pathpattern
这个配置进行修改。
例如想让访问静态资源的url必须前缀有/res。例如/res/index.html 才能访问到static目录中的。我们可以修改如下:
在application.yml中
spring:
mvc:
static-path-pattern: /res/** #修改静态资源访问路径
4.1.2、修改静态资源存放目录
我们可以修改 spring.web.resources.static-locations 这个配置来修改静态资源的存放目录。
例如:
spring:
web:
resources:
static-location:
- classpath: /sgstatic/ # 这也作为我们的静态资源存放目录 resources/sgstatic
- classpath: /static/ # 这是我们的静态资源存放目录 resources/static
这样我们就也可以直接访问 resources/sgstatic 目录下的静态资源了,也可以直接访问 resources/static 目录下的静态资源。
注意,static-location 是一个数组,我们可以写一个,也可以写多个静态资源存放目录
4.1.3、网站图标
- 与其他静态资源一样,Spring Boot在配置的静态内容位置中查找 favicon.ico。
- 如果存在这样的文件,它将自动用作应用程序的favicon。
- 关闭 SpringBoot 默认图标
#关闭默认图标
spring.mvc.favicon.enabled=false
- 自己放一个图标在静态资源目录 resources 下
- 清除浏览器缓存!刷新网页,发现图标已经变成自己的了!
4.2、模拟前后端分离式开发
我们开启两个 SpringBoot 工程,来模拟我们的前后端分离式开发
- 一个是存放静态目录的 springboot_static,端口是80
- 一个是我们的 springboot_web,端口是81
我们在 springboot_web 工程进行开发
- 首先导入依赖和继承 spring-boot-starter-parent 这个父工程
org.springframework.boot
spring-boot-starter-parent
2.5.4
org.springframework.boot
spring-boot-starter-web
mysql
mysql-connector-java
runtime
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.2.0
org.projectlombok
lombok
2. 我们写一个查询查询用户接口测试一下
数据库语句如下
DROP TABLE IF EXISTS user;
CREATE TABLE user (
id INT(11) NOT NULL AUTO_INCREMENT,
username VARCHAR(50) DEFAULT NULL,
age INT(11) DEFAULT NULL,
address VARCHAR(50) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
/*Data for the table user */
INSERT INTO user(id,username,age,address) VALUES (2,‘pdd’,25,‘上海’),
(3,‘UZI’,19,‘上海11’),(4,‘RF’,19,NULL),(6,‘三更’,14,‘请问2’),(8,‘test1’,11,‘cc’),
(9,‘test2’,12,‘cc2’);
application.yml 中配置如下
server:
port: 81
spring:
datasource:
url: jdbc:mysql://localhost:3306/springboot?characterEncoding=utf-8&serverTimezone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:mapper/*Mapper.xml # mapper映射文件路径
type-aliases-package: com.sangeng.domain # 配置哪个包下的类有默认的别名
实体类如下
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id;
private String username;
private Integer age;
private String address;
}
- 首先写 dao 层接口,并用插件生成对应的 Mapper.xml 文件
@Mapper
@Repository
public interface UserMapper {
List findAll();
}
<?xml version="1.0" encoding="UTF-8" ?>
select * from user
4. 接着写 service 层接口和其实现类,并在实现类中注入 dao
@Service
public interface UserService {
List findAll();
}
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public List findAll() {
return userMapper.findAll();
}
}
- 最后编写 controller 层,并在 controller 层中注入 service
@RestController
@RequestMapping(“/user”)
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(“/findAll”)
public List findAll(){
// 调用 service 查询数据,进行返回
return userService.findAll();
}
}
- 启动测试
我们查到的结果是 List 集合,List 集合会转换为 json 放入到响应体当中,但是我们如果是根据 id 查询,那么只会查出一个用户,是对象格式。我们要保证一个项目中所有接口返回的数据格式的统一。这样无论是前端还是移动端开发获取到我们的数据后都能更方便的进行统一处理。我们这里是将所有的数据格式统一为 json 格式。
所以我们定义一下结果封装类 ResponseResult,由于格式统一是公用的,所以我们可以在 com.sangeng 下创建一个公共 common 包,在包下创建结果封装类 ResponseResult
// 加上此注解,如果某个属性的值不为NULL,才会将其转化为Json格式
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseResult {
/**
• 状态码
*/
private Integer code;
/**
• 提示信息,如果有错误时,前端可以获取该字段进行提示
*/
private String msg;
/**
• 查询到的结果数据(不同接口查询的类型不一样,所以我们可以设为泛型)
*/
private T data;
// 三个参数的有参构造(查询操作需要返回查询的数据data)
public ResponseResult(Integer code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
// 两个参数的有参构造(状态码和提示信息)
public ResponseResult(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
// 两个参数的有参构造(状态码和数据)
public ResponseResult(Integer code, T data) {
this.code = code;
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 T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
我们修改我们的查询用户 controller 层代码,让其返回的是我们封装好的 ResponseResult 格式,而不是 List 集合
@RestController
@RequestMapping(“/user”)
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(“/findAll”)
public ResponseResult findAll(){
// 调用 service 查询数据,进行返回
List users = userService.findAll();
return new ResponseResult(200,users);
}
}
再次启动测试
4.3、跨域请求
- 什么是跨域?
浏览器出于安全的考虑,使用 XMLHttpRequest 对象发起 HTTP 请求时必须遵守同源策略,否则就是跨域的 HTTP 请求,默认情况下是被禁止的。同源策略要求源相同才能进行正常通信,即协议、域名、端口号都完全一样。
参考博客:Ajax前后端交互利器详解(二)
例如我们想要渲染一个表格里面的数据,前端请求后端的数据,然后将后端传输过来的数据渲染到前端表格页面上。
- 前端页面中我们使用 axios 发起请求,请求后台接口,前端页面请求代码如下:
那我们如何解决上述问题呢?
- CORS 解决跨域
CORS 是一个 W3C 标准,全称是 “跨域资源共享”,允许浏览器向跨源服务器发出 XMLHttpRequest 请求,从而克服了 Ajax 只能同源使用的限制。
它通过服务器增加一个特殊的 Header[Access-Control-Allow-Origin]
来告诉客户端跨域的限制,如果浏览器支持 CORS,并且判断 Origin 通过的话,就会允许 XMLHttpRequest 发起跨域请求。
4.4、SpringBoot使用CORS解决跨域
在Web开发中,经常会遇到跨域开发的问题,常用的跨域解决方案有 JSNOP、IFRAME、CORS等。CORS(Cross-OriginResource Sharing 跨域资源共享),当一个请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。
CORS(Cross-OriginResource Sharing 跨域资源共享),是一个W3C标准,它允许浏览器向跨域服务器发生Ajax请求,打破了Ajax只能访问本站内的资源限制。
在Spring4.2开始,SpringMVC支持开箱即用的CORS。在SpringBoot应用程序中使用带有 @CrossOrigin
注解,该注解可标记在控制器的类上或具体的某个方法上实现跨域请求,也可以通过自定义方法注册Bean来定义全局的CORS配置。
4.4.1、加注解@CrossOrigin
- 使用
@CrossOrigin
,给 controller 层的方法加上此注解
这个注解可以加在类上,也可以加在方法上
- 加在类上,指明这个类中的所有方法都可以进行跨域请求
- 加在方法上,指明这个方法可以进行跨域请求
@RestController
@RequestMapping(“/user”)
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(“/findAll”)
@CrossOrigin
public ResponseResult findAll(){
// 调用 service 查询数据,进行返回
List users = userService.findAll();
return new ResponseResult(200,users);
}
}
这样我们再次使用前端页面请求后台接口,发现请求成功
4.4.2、使用WebMvcConfigurer的addCorsMappings方法配置CorsInterceptor
上述方法使用注解加在类上或者方法上虽然看起来方便,但是如果我们有很多的 controller 方法,那么就需要加很多个注解,所以其实并不方便。
- 我们创建一个包,包下创建类,让类实现 WebMvcConfigurer 接口,并重写 addCorsMappings 方法,如下:
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 设置允许跨域的路径
registry.addMapping(“/**”)
// 设置允许跨域请求的域名
.allowedOriginPatterns(“*”)
// 是否允许cookie
.allowCredentials(true)
// 设置允许的请求方式
.allowedMethods(“GET”,“POST”,“DELETE”,“PUT”)
// 跨域允许时间
.maxAge(3600);
}
}
这样我们再次使用前端页面请求后台接口,发现请求成功。
这样我们就解决了跨域请求,我们就可以真正让前面页面请求后台数据来渲染我们的表格数据了.
我们先来看请求成功之后箭头函数返回的 res 对象里面的内容,我们可以在浏览器中打断点调试
当然我们也可以在控制台打印 res 对象
这样我们就可以拿到前端页面请求返回的后台数据对象 res,而 res 里面又有我们的数据,我们可以通过遍历来拿到数据,然后放在前端页面表格里面
学号 姓名 年龄 地址 {{user.id}} {{user.username}} {{user.age}} {{user.address}}
学号 姓名 年龄 地址 {{user.id}} {{user.username}} {{user.age}} {{user.address}}