1 JDBC+HikariDataSource
1.1 介绍
HikariDataSource 是目前市面上非常优秀的数据源,是springboot2默认数据源
1.2 应用实例
1.2.1 需求
演示SpringBoot如何通过JDBC+HikariDataSource完成对mysql操作
1.2.2 代码实现
(1)准备数据库初始数据
# 创建数据库
DROP DATABASE IF EXISTS spring_boot;
CREATE DATABASE spring_boot;
USE spring_boot;
# 创建家居表
CREATE TABLE furn(
`id` INT(11) PRIMARY KEY AUTO_INCREMENT,##id
`name` VARCHAR(64) NOT NULL,##家居名
`maker` VARCHAR(64) NOT NULL,##厂商
`price` DECIMAL(11,2) NOT NULL,##价格
`sales` INT(11) NOT NULL,##销量
`stock` INT(11) NOT NULL,##库存
`img_path` VARCHAR(256) NOT NULL ##照片路径
);
# 初始化家居数据
INSERT INTO furn(`id`,`name`,`maker`,`price`,`sales`,`stock`,`img_path`) VALUES
(NULL,'北欧风格小桌子','熊猫家居',180,666,7,'assets/images/product-image/1.jpg'),
(NULL,'简约风格小椅子','熊猫家居',180,666,7, 'assets/images/product-image/2.jpg'),
(NULL,'典雅风格小台灯','蚂蚁家居',180,666,7,'assets/images/product-image/3.jpg'),
(NULL,'温馨风格盆景架','蚂蚁家居',180,666,7,'assets/images/product-image/4.jpg');
SELECT * FROM furn;
准备对应实体类
package org.wwj.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Furn {
private Integer id;
private String name;
private BigDecimal price;
private Integer sales;
private Integer stock;
private String imgPath = "assets/images/product-image/1.jpg";
}
(2)进行数据库开发,在pom.xml 引入data-jdbc starter,该依赖中包含了JDBC和Hikari数据源
<!--引入data-jdbc starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
(3)Spring Boot 不知道项目要操作Mysql还是Oracle,需要在pom.xml 指定导入数据库驱动,并指定对应版本
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
(4)引入 test start
<!--如果要开发springboot测试类,需要引入 test starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
(5)在application.yml 配置操作数据源的信息
spring:
datasource: # 配置数据源
url: jdbc:mysql://localhost:3306/spring_boot?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
(6)在test目录下创建测试类 ApplicationTests.java 进行测试
package org.wwj.springboot;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.wwj.bean.Furn;
import javax.annotation.Resource;
import java.util.List;
@SpringBootTest
public class ApplicationTests {
@Resource
private JdbcTemplate jdbcTemplate;
@Test
public void contextLoads(){
RowMapper<Furn> rowMapper = new BeanPropertyRowMapper<>(Furn.class);
String sql = "SELECT * FROM furn";
List<Furn> furns = jdbcTemplate.query(sql, rowMapper);
for (Furn furn :furns) {
System.out.println(furn);
}
// 输出数据源类型
System.out.println(jdbcTemplate.getDataSource().getClass());
}
}
1.2.3 测试结果
2 整合 Druid 到SpringBoot
2.1 基本介绍
(1)官方文档:
中文手册:https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98
(2)Druid:性能优秀,Druid提供性能卓越的连接池功能外,还集成了SQL监控,黑名单拦截等功能,强大的监控特性,通过Druid提供的监控功能,可以清楚知道连接池和SQL的工作情况,所以根据项目需要,也要掌握Druid和SpringBoot整合
(3)整合 Druid 到SpringBoot有两种方式
- 自定义方式
- 引入starter方式
2.2 Durid基本使用
需求说明:将 Spring-Boot 的数据源切换成 Druid
代码实现:
(1)修改pom.xml,引入druid依赖
<!--引入druid依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.17</version>
</dependency>
(2)创建配置类 DruidDataSourceConfig.java,进行如下配置后,即可成功将数据源切换为Druid
package org.wwj.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DruidDataSourceConfig {
// 编写方法,注入DruidDataSource
@ConfigurationProperties("spring.datasource")
@Bean
public DruidDataSource dataSource(){
// 配置了@ConfigurationProperties("spring.datasource")
// 就可以读取到application.yml的配置
// 这样就不需要调用DruidDataSource对象的set方法给属性赋值,会自动关联
return new DruidDataSource();
}
}
问题:为什么我们注入自己的DataSource,默认的HiKariDatasource就失效了?
解读:在springboot底层会判断容器中是否有DataSource Bean,如果有就不注入默认的 HiKari
2.3 Durid监控功能-sql监控
2.3.1 SQL监控数据
修改配置类 DruidDataSourceConfig.java,增加druid监控功能
文档地址:常见问题 · alibaba/druid Wiki · GitHub
2.3.2 SQL监控数据-测试页面
(1)修改配置类 DruidDataSourceConfig.java,配置druid的监控页功能
//配置druid的监控页功能
@Bean
public ServletRegistrationBean statViewServlet() {
// 创建 StatViewServlet
StatViewServlet statViewServlet = new StatViewServlet();
ServletRegistrationBean<StatViewServlet> registrationBean =
new ServletRegistrationBean<>(statViewServlet, "/druid/*");
// 设置参数
HashMap<String, String> map = new HashMap<>();
// 设置用户名
map.put("loginUsername","wwj");
// 设置密码
map.put("loginPassword","123456");
registrationBean.setInitParameters(map);
return registrationBean;
}
这样就配置好了,启动项目,浏览器输入 localhost:9999/druid 即可进入监控页面
(2) 修改配置类 DruidDataSourceConfig.java 中的 dataSource()方法,添加sql监控功能
// 编写方法,注入DruidDataSource
@ConfigurationProperties("spring.datasource")
@Bean
public DruidDataSource dataSource() throws SQLException {
// 配置了@ConfigurationProperties("spring.datasource")
// 就可以读取到application.yml的配置
// 这样就不需要调用DruidDataSource对象的set方法给属性赋值,会自动关联
DruidDataSource druidDataSource = new DruidDataSource();
// 加入监控功能
druidDataSource.setFilters("stat");
return druidDataSource;
}
(3)创建 DruidSqlController.java,模拟操作DB的请求
package org.wwj.controller;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.wwj.bean.Furn;
import javax.annotation.Resource;
import java.util.List;
public class DruidSqlController {
@Resource
private JdbcTemplate jdbcTemplate;
@ResponseBody
@GetMapping("/sql")
public List<Furn> crudDB() {
String sql = "select * from furn";
RowMapper<Furn> furnRowMapper = new BeanPropertyRowMapper<>();
List<Furn> furns = jdbcTemplate.query(sql, furnRowMapper);
return furns;
}
}
(4)重新启动项目 ,浏览器输入 localhost:9999/sql 进行测试
sql监控页效果如下
sql监控列含义:
2.4 Durid监控功能-Web关联监控
2.4.1 Web关联监控配置-Web应用、URI监控
//配置WebStatFilter,用于采集web-jdbc关联的监控数据
@Bean
public FilterRegistrationBean webStatFilter(){
// 创建 WebStatFilter
WebStatFilter webStatFilter = new WebStatFilter();
FilterRegistrationBean<WebStatFilter> registrationBean =
new FilterRegistrationBean<>(webStatFilter);
// 对所有url进行监控
registrationBean.setUrlPatterns(Arrays.asList("/*"));
// 排除指定的url
Map map = new HashMap<>();
map.put("exclusions","*.js,*.gif,*.jpg,*.png");
registrationBean.setInitParameters(map);
return registrationBean;
}
2.4.2 web应用和URI监控页面
2.5 Durid监控功能-SQL防火墙
SQL防火墙防火强的配置很简单,只需要给filters参数增加一个值wall即可
修改配置类 DruidDataSourceConfig.java 中的 dataSource()方法,开启SQL防火墙
// 编写方法,注入DruidDataSource
@ConfigurationProperties("spring.datasource")
@Bean
public DruidDataSource dataSource() throws SQLException {
// 配置了@ConfigurationProperties("spring.datasource")
// 就可以读取到application.yml的配置
// 这样就不需要调用DruidDataSource对象的set方法给属性赋值,会自动关联
DruidDataSource druidDataSource = new DruidDataSource();
// 加入监控功能,加入sql防火墙
druidDataSource.setFilters("stat,wall");
return druidDataSource;
}
2.6 Durid监控功能-Session监控
Session监控无需配置,自动开启(需要登录才能看到,登录地址:localhost9999:/druid/login.html)
2.7 Druid Spring Boot Starter
2.7.1 基本介绍
前面使用的是自己引入druid+配置类方式整合Druid和监控,即自定义方式。Druid Spring Boot Starter 可以让程序员在Spring Boot项目中更加轻松集成Druid监控
文档地址:druid/druid-spring-boot-starter at master · alibaba/druid · GitHub
2.7.2 代码实现
(1)修改pom.xml 注销druid的依赖
(2)注销 DruidDataSourceConfig.java
(3)修改pom.xml,引入 Druid Spring Boot Starter
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>
(4)配置YML文件
spring:
datasource: # 配置数据源
url: jdbc:mysql://localhost:3306/spring_boot?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
# Druid的其他属性配置
druid:
stat-view-servlet:
# 配置druid的监控页功能
enabled: true
# 用户名
login-username: wwj
# 密码
login-password: 123456
reset-enable: false
# 配置web监控
web-stat-filter:
enabled: true
url-pattern: /*
exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'
filter:
stat: # 配置sql监控
# 打开慢SQL记录
slow-sql-millis: 1000
log-slow-sql: true
enabled: true
wall: # 配置sql防火墙
enabled: true
config:
# 把删除表操作拉入黑名单,即不允许执行删除表操作
drop-table-allow: false
# 不允许执行查询所有字段的sql
select-all-column-allow: false
# 也可以这样配置,stat: 监控统计、Slf4j:日志记录、waLL: 防御sqL注入
# filters: stat,wall,slf4j
# 初始化时建立物理连接的个数
initial-size: 5
# 连接池的最小空闲数量
min-idle: 5
# 连接池最大连接数量
max-active: 20
# 获取连接时最大等待时间,单位毫秒
max-wait: 60000
# 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
test-while-idle: true
# 既作为检测的间隔时间又作为testWhileIdel执行的依据
time-between-eviction-runs-millis: 60000
# 销毁线程时检测当前连接的最后活动时间和当前时间差大于该值时,关闭当前连接(配置连接在池中的最小生存时间)
min-evictable-idle-time-millis: 30000
# 用来检测数据库连接是否有效的sql 必须是一个查询语句(oracle中为 select 1 from dual)
validation-query: select 'x'
# 申请连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
test-on-borrow: false
# 归还连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
test-on-return: false
# 是否缓存preparedStatement, 也就是PSCache,PSCache对支持游标的数据库性能提升巨大,比如说oracle,在mysql下建议关闭。
pool-prepared-statements: false
# 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
max-pool-prepared-statement-per-connection-size: -1
# 合并多个DruidDataSource的监控数据
use-global-data-source-stat: true
配置完成!
3 整合 Mybatis 到SpringBoot
3.1 需求说明
将spring boot 和 mybatis 整合,查询出一条数据
3.2 综合案例
(1)在 pom.xml 文件中加入mybatis 依赖
<!--引入mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.1</version>
</dependency>
完整pom.xml文件如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.wwj</groupId>
<artifactId>springboot-mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- 导入 springboot 父工程 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
</parent>
<dependencies>
<!--引入Thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<!-- 导入 web 项目场景启动器,会自动导入和 web 开发相关依赖 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.1</version>
</dependency>
<!--引入lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--引入配置处理器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<!-- 引入data-jdbc starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!--引入数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<!--如果要开发springboot测试类,需要引入 test starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--引入druid-spring-boot-starter-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
(2)数据库准备代码
CREATE DATABASE`springboot_mybatis` ;
USE`springboot_mybatis` ;
CREATE TABLE`monster`(
`id` INT NOT NULL AUTO_INCREMENT,
`age` INT NOT NULL,
`birthday` DATE DEFAULT NULL,
`email` VARCHAR(255)DEFAULT NULL,
`gender` CHAR(1) DEFAULT NULL,
`name` VARCHAR(255)DEFAULT NULL,
`salary` DOUBLE NOT NULL,
PRIMARY KEY(`id`)
)CHARSET=utf8;
SELECT*FROM`monster`;
INSERT INTO monster VALUES(NULL,20,'2000-11-11','nmw@sohu.com','男','牛魔王',5000.88);
INSERT INTO monster VALUES(NULL,10,'2011-11-11','bgj@sohu.com','女','白骨精',8000.88);
SELECT * FROM `monster` WHERE `id` = 1
对应数据库表中的实体类 Monster.java 如下
package org.wwj.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.sql.Date;
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Monster {
private Integer id;
private Integer age;
// 这里注意一定要导入 java.sql.Date 包里的 Date
private Date birthday;
private String email;
private char gender;
private String name;
private Double salary;
}
(3)创建接口 MonsterMapper.java
在mapper接口使用@Mapper就会扫描,并将Mapper接口对象注入
也可以在主程序上添加@MapperScan(basePackage = {"包名"}),来扫描包下所有的mapper接口
package org.wwj.dao;
import org.apache.ibatis.annotations.Mapper;
import org.wwj.bean.Monster;
@Mapper
public interface MonsterMapper {
//根据id查询妖怪
Monster findMonsterById(Integer id);
}
(4) 在类路径(resources)下创建mapper目录,在该目录下创建 MonsterMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.wwj.dao.MonsterMapper">
<select id="findMonsterById" parameterType="Integer" resultType="Monster">
select * from `monster` where `id` = #{id}
</select>
</mapper>
(5)配置 YAML 文件
spring:
datasource: # 配置数据源
url: jdbc:mysql://localhost:3306/springboot_mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
server:
port: 9999
mybatis:
# 指定要扫描的 XxxMapper.xml 文件
mapper-locations: classpath:mapper/*.xml
# 通过config-location,可以指定mybatis-config.xml,就可以用传统的方式来配置mybatis
# config-location:
#也可以直接在application.yml进行配置
# 举例1,配置原来的 typeAliases
type-aliases-package: org.wwj.bean
# 举例2,配置mybatis自带的日志输出
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
(5)创建测试类进行测试
package org.wwj.dao;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.wwj.bean.Monster;
import javax.annotation.Resource;
@SpringBootTest
public class MonsterMapperTest {
@Resource
private MonsterMapper monsterMapper;
@Test
public void findMonsterByIdTest(){
Monster monster = monsterMapper.findMonsterById(1);
System.out.println(monster);
}
}
注意,需要创建springboot主程序,才能运行测试类
package org.wwj;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext ioc = SpringApplication.run(Application.class, args);
System.out.println("hello");
}
}
测试效果如下
3.3 注意事项和细节说明
如果看到 sql 打印的时间和数据库里面存储的时间不一样,这是因为时区问题。查看当前时区:SHOW VARIABLES LIKE '%time_zone%';
可通过两种方式解决:
第一种:永久修改时区问题
找到路径中的 my.ini 配置文件,并打开它
在该文件的[mysqld]字段下面添加一行:default-time-zone='+08:00',保存即可。下次再重启MySQL时,时区仍为东八区,不会还原。
第二种:在需要转换时间的类中添加注解 @JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”, timezone = “GMT+8”)
//GMT 就是格林尼治标准时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date birthday;
4 整合 Mybatis-plus 到SpringBoot
4.1 基本介绍
(1)官方文档地址:MyBatis-Plus 🚀 为简化开发而生
(2)MyBatis-Plus(简称MP) 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
(3)强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
4.2 整合 Mybatis-plus 实例
4.2.1 环境准备
(1)新建一个项目,导入依赖
将springboot 整合mybatis的依赖替换为整合mybatis-plus的起步依赖;
<!--引入mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
IDEA按照一个插件Maven Helper可以查看是否有依赖冲突。
(2)修改yaml配置文件
端口、数据库、mybatis-plus日志输出、驼峰映射、xml位置等
spring:
datasource: # 配置数据源
url: jdbc:mysql://localhost:3306/springboot_mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
server:
port: 9999
mybatis-plus:
# 扫描包
mapper-locations: mapper/*.xml
configuration:
# 配置日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true
# 别名设置
type-aliases-package: com.wwj.bean
(3)Monster实体类,绑定表名、主键名
package org.wwj.bean;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.sql.Date;
@NoArgsConstructor
@AllArgsConstructor
@Data
//指定表名,若一致可以不用指定
@TableName(value = "monster")
public class Monster {
//指定主键名、主键生产策略
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
//指定列名,若一致可以不用指定
@TableField(value = "age")
private Integer age;
// 这里注意一定要导入 java.sql.Date 包里的 Date
private Date birthday;
private String email;
private Character gender;
private String name;
private Double salary;
}
(4)MonsterMapper
只要继承BaseMapper<~>即可、其他方法和xml可以删掉。如果BaseMapper提供的方法不能满足业务需求时就可以自己定义
@Mapper
public interface MonsterMapper extends BaseMapper<Monster> {}
MonsterMapper继承BaseMapper<~>后就可以不用编写XML来实现了
(5)MonsterService
在mybatis-plus中,service 层接口继承 Iservice<~> 接口
public interface MonsterService extends IService<Monster> {}
service 实现类,需要继承 ServiceImpl<~>
/**
* 因为 ServiceImpl 类实现了 IService 接口
* MonsterService 接口又继承 IService 接口
* 这里 MonsterServiceImpl 继承了 ServiceImpl 就可以认为是实现了 MonsterService
*/
@Service
public class MonsterServiceImpl
extends ServiceImpl<MonsterMapper, Monster>
implements MonsterService{
}
(6)MonsterController
package org.wwj.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.wwj.bean.Monster;
import org.wwj.service.MonsterService;
import javax.annotation.Resource;
@Controller
public class MonsterController {
@Resource
private MonsterService monsterService;
//根据id返回对应的monster
@GetMapping("/monster")
@ResponseBody
public Monster getMonsterById(@RequestParam("id") Integer id){
return monsterService.getById(id);
}
}
4.2.2 使用
本文直接在测试类中注入IUserMapper、编写测试方法进行测试。service层、controller层就不写了
@Resource
private MonsterMapper monsterMapper;
可以看到,自己并没有新建方法,而userMapper可以调用BaseMapper提供的众多方法。
可以看到BaseMapper提供的方法需要的参数有字符串、实体类、map、条件构造器等。下文将使用一些用例来测试这些方法。为了增加观感、只展示如何使用、执行结果、SQL日志就不截图占用篇幅了。
4.2.2.1 基础增删改查
(1)新增一条Monster数据
@Test
public void insert(){
Monster monster =
new Monster(3, 14, new Date(323123), "nmw@hhh.com", '男', "牛魔王", 5000.88);
monsterMapper.insert(monster);
}
(2)根据条件删除Monster
根据ID删除
@Test
public void deleteById(){
monsterMapper.deleteById(3);
}
根据某列精准匹配删除
@Test
public void deleteByMap(){
Map<String, Object> map = new HashMap<>();
map.put("email", "nmw@hhh.com");
monsterMapper.deleteByMap(map);
}
(3)修改数据Monster信息
根据ID修改
@Test
public void updateById(){
Monster monster = new Monster();
monster.setId(2);
monster.setAge(15);
monster.setGender('男');
monsterMapper.updateById(monster);
}
(4)根据条件查询Monster
查询全部用户
@Test
public void findAllMonster(){
// 第一种方式
List<Monster> monsters1 = monsterMapper.selectByMap(null);
System.out.println(monsters1);
// 第二种方式
List<Monster> monsters2 = monsterMapper.selectList(null);
System.out.println(monsters2);
}
根据ID查询
@Test
public void findMonsterById(){
Monster monster = monsterMapper.selectById(1);
System.out.println(monster);
}
根据某列精确匹配
@Test
public void findMonsterByMap(){
HashMap<String, Object> map = new HashMap<>();
map.put("age", 15);
List<Monster> monsters = monsterMapper.selectByMap(map);
System.out.println(monsters);
}
4.2.2.2 批量操作
(1)批量新增
@Test
public void batchInsert(){
Monster monster1 = new Monster(
null, 14, new Date(13231230), "1nmw@hhh.com", '男', "牛魔王1", 15000.88);
Monster monster2 = new Monster(
null, 15, new Date(23231230), "2nmw@hhh.com", '男', "牛魔王2", 25000.88);
Monster monster3 = new Monster(
null, 16, new Date(33231230), "3nmw@hhh.com", '男', "牛魔王3", 35000.88);
ArrayList<Monster> list = new ArrayList<>();
list.add(monster1);
list.add(monster2);
list.add(monster3);
list.forEach(monster -> {
monsterMapper.insert(monster);
});
}
(2)批量删除
@Test
public void batchDelete(){
ArrayList<Integer> ids = new ArrayList<>();
ids.add(5);
ids.add(6);
ids.add(7);
monsterMapper.deleteBatchIds(ids);
}
(3)批量查询
@Test
public void batchSelect(){
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
List<Monster> monsters = monsterMapper.selectBatchIds(list);
}
4.2.2.3 查询条件构造器【QueryWrapper】使用
条件构造器就是通过链式编程的形式构造where后面的SQL可选项有
比如查询 age>=14 and name like "%牛魔王%"
@Test
public void selectListByQueryWrapper(){
QueryWrapper<Monster> queryWrapper = new QueryWrapper<>();
queryWrapper.ge("age", 14)
.like("name","牛魔王");
monsterMapper.selectList(queryWrapper);
}
但是存在许多硬编码。
4.2.2.4 修改条件构造器【UpdateWrapper】造器使用
也是通过链式编程的方式拼接修改条件;
比如,将怪物名字为牛魔王的年龄修改为20
@Test
public void updateByUpdateWrapper(){
UpdateWrapper<Monster> wrapper = new UpdateWrapper<>();
wrapper.eq("name","牛魔王")
.set("age", 20);
Monster monster = new Monster();
monsterMapper.update(monster, wrapper);
}
也是存在字段的硬编码
4.2.3 减少硬编码
【LambdaQueryWrapper】来减少硬编码、直接通过类获取属性的方式得到字段
比如查询名字有"牛"的所有妖怪
@Test
public void updateByLambdaQueryWrapper(){
LambdaQueryWrapper<Monster> wrapper = new LambdaQueryWrapper<>();
wrapper.like(Monster::getName,"牛");
List<Monster> monsters = monsterMapper.selectList(wrapper);
}
【LambdaUpdateWrapper】减少硬编码,将名字有"王"的所有妖怪性别改为'女'
@Test
public void updateByLambdaUpdateWrapper(){
LambdaUpdateWrapper<Monster> wrapper = new LambdaUpdateWrapper<>();
wrapper.set(Monster::getGender,'女')
.like(Monster::getName,"王");
Monster monster = new Monster();
monsterMapper.update(monster, wrapper);
}
4.3 注意事项和使用细节
(1)mybatis-plus 依赖中包含了 mybatis 和 springboot autoconfigure,无需额外引入
(2)为了开发方便,可以安装MyBatisX插件,参考文档
自动生成sql语句 :
自动生成代码效果如下