mybatis官网 :https://mybatis.org/mybatis-3/zh/index.html
mybatis-plus官网:https://baomidou.com/
druid:https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98
druid-spring-boot-starter:https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
pageHelper: https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md
引入依赖可能就需要考虑版本对应关系
其中mybatis和springboot的版本关系可以在https://start.spring.io/选择myatis相关依赖确定,
druid的版本没有找到说明,找个最新的吧,
pageHelper的版本参考器官方示例,这个地址由版本对应关系:https://github.com/pagehelper/pagehelper-spring-boot
mybatis-plus的话,其启动器已经包含了mybatis,只需要考虑和springboot的关系即可,而这个似乎没有找到
我本地是spring boot 2.6.11 版本
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.2.15version>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.2.2version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.30version>
<scope>runtimescope>
dependency>
#数据源
spring:
datasource:
username: root
password: Jeol@1201
# allowMultiQueries表示支持执行;间隔的多个sql nullCatalogMeansCurrent=true返回指定库涉及的表
url: jdbc:mysql://kube.sry1201.cn:32306/test?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&tcpKeepAlive=true&autoReconnect=true&allowMultiQueries=true&nullCatalogMeansCurrent=true
driver-class-name: com.mysql.cj.jdbc.Driver
# 使用的连接池的类型
type: com.alibaba.druid.pool.DruidDataSource
# druid-spring-boot-starter 配置项 DruidAbstractDataSource中可以找到一些配置的默认值
druid:
# 初始化连接的个数
initial-size: 10
# 最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请。
min-idle: 10
# 最大连接数
max-active: 20
# 获取连接的最大等待时长
max-wait: 5000
# 连接空闲时间超过了多长时间,配合testWhileIdle使用
timeBetweenEvictionRunsMillis: 60000
# 检测连接时执行的sql
validationQuery: SELECT 1 FROM DUAL
#建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效
testWhileIdle: true
#申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
testOnBorrow: false
#归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testOnReturn: false
# 连接保持空闲而不被驱逐的最小时间 默认1800000
min-evictable-idle-time-millis: 600000
# 连接保持空闲而不被驱逐的最大时间 默认25200000
max-evictable-idle-time-millis: 900000
# 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
spring.datasource.druid.pool-prepared-statements=true
# 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=50
<resources>
<resource>
<directory>src/main/resourcesdirectory>
resource>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.xmlinclude>
includes>
resource>
resources>
xml放置在resources下
mybatis:
# 如果你的xml文件放在resouces目录下,你可以尝试这么配置,然后很显然,你需要以Mapper.xml结尾
mapper-locations: classpath*:**/*Mapper.xml
# 配置后xml返回的resultType中就不用写全限定类名,直接写类名就行,可以不配置
type-aliases-package: cn.sry1201.*.model
否则报错如下
Invalid bound statement (not found): cn.sry1201.demo2.mapper.UserMapper2.selectAll
# 自己配置监控统计拦截的filter
filter:
stat:
#开启慢sql日志
log-slow-sql: true
# 超过2s认为是慢sql
slow-sql-millis: 2000
# druid统计(状态监控),默认开启
enabled: true
db-type: mysql
# 日志监控,使用slf4j 进行日志输出
参考:https://blog.csdn.net/u012129558/article/details/124923444
<appender name = "slow-sql" class="ch.qos.logback.core.FileAppender">
<file>${logHome}/slow-sql/slow-sql.logfile>
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %p %t - %m%npattern>
<charset class="java.nio.charset.Charset">UTF-8charset>
encoder>
appender>
<logger name="com.alibaba.druid.filter.stat.StatFilter" level="ERROR" additivity="false">
<appender-ref ref="slow-sql" />
logger>
慢sql的认定时间调小一点就行了
配置
#数据源
spring:
datasource:
username: root
password: Jeol@1201
# allowMultiQueries表示支持执行;间隔的多个sql
url: jdbc:mysql://kube.sry1201.cn:32306/test?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&tcpKeepAlive=true&autoReconnect=true&allowMultiQueries=true
driver-class-name: com.mysql.cj.jdbc.Driver
# 使用的连接池的类型
type: com.alibaba.druid.pool.DruidDataSource
# druid-spring-boot-starter 配置项 DruidAbstractDataSource中可以找到一些配置的默认值
druid:
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,slf4j
# 自己配置监控统计拦截的filter
filter:
stat:
#开启慢sql日志
log-slow-sql: true
# 超过2s认为是慢sql
slow-sql-millis: 2000
# druid统计(状态监控),默认开启
enabled: true
db-type: mysql
# 日志监控,使用slf4j 进行日志输出
slf4j:
enabled: true
statement-log-error-enabled: true
statement-create-after-log-enabled: false
statement-close-after-log-enabled: false
result-set-open-after-log-enabled: false
result-set-close-after-log-enabled: false
########## 配置WebStatFilter,用于采集web关联监控的数据 ##########
web-stat-filter:
enabled: true # 启动 StatFilter
url-pattern: /* # 过滤所有url
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" # 排除一些不必要的url
session-stat-enable: true # 开启session统计功能
session-stat-max-count: 1000 # session的最大个数,默认100
########## 配置StatViewServlet(监控页面),用于展示Druid的统计信息 ##########
stat-view-servlet:
enabled: true # 启用StatViewServlet
# http://localhost:8004/druid
url-pattern: /druid/* # 访问内置监控页面的路径,内置监控页面的首页是/druid/index.html
reset-enable: false # 不允许清空统计数据,重新计算
login-username: root # 配置监控页面访问密码
login-password: 123
allow: 127.0.0.1 # 允许访问的地址,如果allow没有配置或者为空,则允许所有访问
deny: # 拒绝访问的地址,deny优先于allow,如果在deny列表中,就算在allow列表中,也会被拒绝
在线的话直接安装
离线下载界面 :https://plugins.jetbrains.com/
Mybatis-log-plugin : 可以打开一个专门记录sql执行日志的界面,而且是最终执行的sql
Free-idea-mybatis:支持从mapper接口跳转到mapper.xml文件,这个插件还集成了mybatis-generator-gui,不过我没用过
直接搜索商店的话似乎名称有点对应不上, 可以大致看看其中文描述,安装好了之后是这样的
官方:https://github.com/zouzg/mybatis-generator-gui/wiki/Usage-Guide
基于单个表,生成一些增删改查,批量,的xml示例,映射对象,接口等,主要是有一个前端的ui界面,操作方便,当然idea有些插件也有这个功能
问题,似乎不能连接我8.0的mysql数据库,直接在打包号的lib目录下换驱动,连接成功后显示的表不对劲
下载后,修改DbType,驱动类,连接属性nullCatalogMeansCurrent=true,驱动包名
public enum DbType {
MySQL("com.mysql.cj.jdbc.Driver", "jdbc:mysql://%s:%s/%s?useUnicode=true&useSSL=false&characterEncoding=%s&nullCatalogMeansCurrent=true", "mysql-connector-java-8.0.30.jar"),
删除其resouces -> lib目录下的5.0的mysql驱动,换成8.0的驱动
遵循官方文档操作,将app内的内容复制出来到单独的文件夹
git clone https://github.com/astarring/mybatis-generator-gui
cd mybatis-generator-gui
mvn jfx:jar
cd target/jfx/app/
编辑以个启动脚本start.bat放在复制出来的目录就可以了
:: java -jar mybatis-generator-gui.jar
start javaw -jar mybatis-generator-gui.jar
我一般习惯比在外部生成再复制进项目
这是一个支持分页查询的框架
版本随意了,我没找到对应的文档,这里直接使用最新版本,不过似乎都对应maven中央仓库上面的说明都是对应boot2.7.5版本,没治
com.github.pagehelper
pagehelper-spring-boot-starter
1.4.5
大致是我们执行PageHelper.startPage后的第一个查询sql会被分页,然后将查询sql转成PageInfo对象,即可获取分页信息。
@RequestMapping("/test1")
public PageInfo getAllUser(@RequestParam Integer pageNum,@RequestParam Integer pageSize){
//两个参数固定是,pageNum,pageSize,可以传入对象,或map,但是对象中属性必须包含pageNum,pageSize,map同理
PageHelper.startPage(pageNum,pageSize);
List<User> all = userMapper3.findAll();
PageInfo pageInfo = new PageInfo<>(all);
return pageInfo;
}
返回的数据如下
{
"total": 183,
"list": [
{
"id": 1,
"name": "毕淑儒",
"py": "BSR"
},
{
"id": 2,
"name": "蔡兴熙",
"py": "CXX"
},
{
"id": 3,
"name": "曾三杰",
"py": "ZSJ"
}
],
"pageNum": 1,
"pageSize": 3,
"size": 3,
"startRow": 1,
"endRow": 3,
"pages": 61,
"prePage": 0,
"nextPage": 2,
"isFirstPage": true,
"isLastPage": false,
"hasPreviousPage": false,
"hasNextPage": true,
"navigatePages": 8,
"navigatepageNums": [
1,
2,
3,
4,
5,
6,
7,
8
],
"navigateFirstPage": 1,
"navigateLastPage": 8
}
但是显然大部分数据否没什么用,我们实际使用中,可以在service业务代码中添加 PageHelper.startPage,然后在同一的返回结果类中定义方法统一处理查询sql返回的list对象,简略如下,然后大致就返回了前端需要的一下分页数据
public static <T> ResponseResult<T> pageSuccess(List<?> data) {
ResponseResult<T> responseResult = new ResponseResult<>();
PageInfo pageInfo = new PageInfo<>(data);
Map<String, Object> result = new HashMap<>(8);
result.put(PAGE_NUM, pageInfo.getPageNum());
result.put(PAGE_SIZE, pageInfo.getPageSize());
result.put(TOTAL_PAGE, pageInfo.getPages());
result.put(TOTAL, (int) pageInfo.getTotal());
result.put(LIST, pageInfo.getList());
responseResult.setCode(SUCCESS);
responseResult.setMessage(SUCCESS_MSG);
responseResult.setData((T) result);
responseResult.setSuccess(true);
return responseResult;
}
1、注意其分页只针对PageHelper.startPage之后执行的第一个查询sql
2、PageHelper默认是在执行的sql 尾部加上limit ,复杂的语句则select count(0) from (执行的查询) limit, 如果查询语句复杂,我们的limit用在某个查询的主表上再去关联其他表,显然效率会更高一点,所以还是需要会写手动的分页
@Configuration
public class PageHelperConfiguration {
/**
* 配置mybatis的分页插件PageHelperProperties
*/
@Bean
@Primary
public PageHelperProperties pageHelper() {
PageHelperProperties pageHelperProperties = new PageHelperProperties();
pageHelperProperties.setAutoRuntimeDialect(Boolean.TRUE);
//启用合理化时,如果pageNum <1 会查询第一页,如果pageNum > pages会查询最后一页
pageHelperProperties.setReasonable(Boolean.TRUE);
//默认值为false,当该参数设置为true时,如果pageSize=0或者RowBounds.limit=0就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是Page类型)
pageHelperProperties.setPageSizeZero(Boolean.TRUE);
// pageHelperProperties.setParams("count=countSql"); # 默认就是
return pageHelperProperties;
}
}
当然你也可以通过配置文件的方式配置,以pagehelper开头即可,具体请查看这个类的属性
@ConfigurationProperties(
prefix = "pagehelper"
)
public class PageHelperProperties extends Properties {
参考官方文档吧,大致我是用不上
大致是对于一下简单的sql,我们可以通过继承Mybatis Plus为我们提供的BaseMapper来进行实现,这样如果只是简单的增删改查,我们就不需要写xml和sql了,此外还提供分页插件,乐观锁插件,甚至还提供分布式数据库id的生成、字段值的自动填充,非法sql检查
当然对于复杂查询,也提供条件构造器来构建,不过我建议还是使用xml来构建复杂的sql
这里就演示一个简单的查询吧
特性:
引入了mybatis-plus-boot-starter之后,就不需要引入Mybatis相关依赖了
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.5.2version>
dependency>
具体可以执行那些操作,查看BaseMapper
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
如果实体类名称不是表名下划线转驼峰,需要通过注解单独指定表名
同时还支持 @TableField @TableId
@Setter
@Getter
@TableName("sys_user")
public class User {
private int id;
private String name;
private String py;
}
@Resource
private UserMapper userMapper;
//测试Mybatis@select注解
@RequestMapping("/test1")
public User getAllUser(){
User user = userMapper.selectById(1);
return user;
}
@Configuration
@MapperScan("cn.sry1201.*.mapper")
public class MybatisPlusConfig {
/**
* mybatis plus 分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
@RequestMapping("/test2")
public Page getAllUser2(){
Page<User> page = new Page<>(2, 3);
userMapper.selectPage(page, null);
System.out.println("当前页数据:"+page.getRecords());
System.out.println("总分页数量:"+page.getPages());
System.out.println("总记录数量:"+page.getTotal());
System.out.println("是否有下一页:"+page.hasNext());
System.out.println("是否有上一页:"+page.hasPrevious());
return page;
}
{
"records": [
{
"id": 4,
"name": "常元琴",
"py": "CYQ"
},
{
"id": 5,
"name": "陈栋芬",
"py": "CDF"
},
{
"id": 6,
"name": "陈宁婷",
"py": "CNZ"
}
],
"total": 183,
"size": 3,
"current": 2,
"orders": [],
"optimizeCountSql": true,
"searchCount": true,
"countId": null,
"maxLimit": null,
"pages": 61
}