sql 语句
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’);
实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String username;
private Integer age;
private String address;
}
3.1、整合步骤
- 添加依赖
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.2.0
mysql
mysql-connector-java
runtime
这里的 mybatis 启动器的版本 springboot 并没有指定,我们需要自己设置版本号,如何查看自己应该引入什么版本呢?
github: https://github.com/mybatis/spring-boot-starter/
- 配置数据库信息
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
properties 写法如下:
#加载驱动
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#数据库连接路径
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
#数据库用户名
spring.datasource.username=root
#数据库密码
spring.datasource.password=123456
数据源类型选择配置,如果需要使用其他数据源,还需要进行额外配置,这里选择阿里巴巴的 Druid 数据源,需要在 pom.xml 配置文件中添加 Druid 数据源的依赖启动器,代码如下所示:
com.alibaba
druid-spring-boot-starter
1.2.1
上述引入的依赖 druid-spring-boot-starter,同样是阿里巴巴为了迎合 Spring boot 项目而适配的 Druid 数据源启动器,当在 pom.xml 文件中引入该启动器后,不需要进行其他额外配置,Spring boot 项目会自动识别配置 Druid 数据源。
需要注意的是,上述配置的 Druid 数据源启动器内部已经初始化了一些运行参数(例如:initialSize,maxActive等),如果开发过程中需要修改第三方 Druid 的运行参数,则必须在全局配置文件中继修改,代码如下所示:
#添加并配置第三方数据源
#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文件(也可以使用插件一键生成)
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{
// 省略接口方法
}
- 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.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
- 我们写一个查询查询用户接口测试一下
数据库语句如下
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
- 接着写 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;
}
}
总结
本文从基础到高级再到实战,由浅入深,把MySQL讲的清清楚楚,明明白白,这应该是我目前为止看到过最好的有关MySQL的学习笔记了,我相信如果你把这份笔记认真看完后,无论是工作中碰到的问题还是被面试官问到的问题都能迎刃而解!
MySQL50道高频面试题整理:
*/
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;
}
}
总结
本文从基础到高级再到实战,由浅入深,把MySQL讲的清清楚楚,明明白白,这应该是我目前为止看到过最好的有关MySQL的学习笔记了,我相信如果你把这份笔记认真看完后,无论是工作中碰到的问题还是被面试官问到的问题都能迎刃而解!
MySQL50道高频面试题整理:
[外链图片转存中…(img-kzb8l6Oz-1725085010454)]