导入依赖
<!-- alibaba的druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.20</version>
</dependency>
<!-- alibaba的druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.20</version>
</dependency>
<!-- mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<!-- mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- mybatisplus 生成器 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.2</version>
</dependency>
<!-- Freemarker 引擎模板 -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
配置yaml文件
spring:
#配置数据源信息
datasource:
#配置数据源类型
type: com.alibaba.druid.pool.DruidDataSource
#配置连接数据库信息
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/appinfodb?useUnicode=yes&characterEncoding=utf-8&rewriteBatchedStatements=true&serverTimezone=GMT%2B8
username: root
password: zax
druid:
# 初始化大小,最小,最大
initial-size: 5
min-idle: 5
max-active: 30
# 配置获取连接等待超时的时间
max-wait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 300000
mvc:
# 开启put,delete请求
hiddenmethod:
filter:
enabled: true
#文件上传
# 最大支持文件大小
# 最大支持请求大小
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
thymeleaf:
cache: false
#邮件发送
mail:
password: fghwjhrzpnmnjied
host: smtp.qq.com
username: 1507550179@qq.com
default-encoding: UTF-8
redis:
#redis主机地址
host: 192.168.207.128
port: 6379
password:
#设置sql打印日志
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#配置类型别名所对应的包
type-aliases-package: com.zax.appmanage.entity
#配置扫描mapper映射文件的代码
mapper-locations: classpath:mapper/*.xml
常用注解
@Data
@ToString
//对应数据库表名
@TableName("user")
public class User {
//对应表中主键
@TableId("userName")
private String userName;
//对应表中字段
@TableField("password")
private String password;
}
@TableName :
- 描述:表名注解,标识实体类对应的表
- 使用位置:实体类
schema属性
shcema 属性用来指定模式名称。如果你使用的是 mysql 数据库,则指定数据库名称。如果你使用的是 oracle,则为 schema,例如:schema=”scott”,其中:scott 就是 oracle 中的 schema
@TableId :
- 描述:主键注解
- 使用位置:实体类主键字段
@TableField
新代码生成器
package com.kgc.appmanager.util;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
public class Generator {
public static void main(String[] args) {
// 数据库配置
FastAutoGenerator.create("jdbc:mysql://localhost:3306/appinfodb?useUnicode=yes&characterEncoding=utf-8&rewriteBatchedStatements=true&serverTimezone=GMT%2B8", "root", "zax")
//全局配置
.globalConfig(builder -> {
builder.author("zax") // 设置作者
// .enableSwagger() // 开启 swagger 模式
.disableOpenDir()// 禁止打开输出目录,默认值:true
.commentDate("yyyy-MM-dd HH:mm")// 注释日期,默认值: yyyy-MM-dd
.outputDir("E:\\idea\\untitled\\AppManager\\src\\main\\java"); // 指定输出目录
})
//包配置
.packageConfig(builder -> {
builder.parent("com.kgc") // 设置父包名,默认值:com.baomidou
.moduleName("appmanager") // 设置父包模块名,默认值:无
.entity("entity")// Entity 包名,默认值:entity
.service("service")// Service 包名,默认值:service
.serviceImpl("service.impl")// Service Impl 包名,默认值:service.impl
.mapper("mapper")// Mapper 包名,默认值:mapper
.xml("mapper.xml")// Mapper XML 包名,默认值:mapper.xml
// .pathInfo(Collections.singletonMap(OutputFile.xml, "E:\\idea\\untitled\\AppManager\\src\\main\\java")) // 路径配置信息
.controller("controller");// Controller 包名,默认值:controller
})
//策略配置
.strategyConfig(builder -> {
builder.addInclude() // 设置需要生成的表名,不写默认是数据库全表
// .addTablePrefix("ad_", "app_")// 设置过滤表前缀
.entityBuilder().disableSerialVersionUID()// 禁用生成 serialVersionUID,默认值:true
.enableChainModel()// 开启链式模型,默认值:false
.enableLombok()// 开启 lombok 模型,默认值:false
.enableTableFieldAnnotation()// 开启生成实体时生成字段注解,默认值:false
.enableActiveRecord()// 开启 ActiveRecord 模型,默认值:false
// .versionColumnName("version")// 乐观锁字段名(数据库)
// .logicDeleteColumnName("deleted")// 逻辑删除字段名(数据库)
// .addTableFills(new Column("create_time", FieldFill.INSERT))
// .addTableFills(new Column("update_time", FieldFill.INSERT_UPDATE))
.mapperBuilder().superClass(BaseMapper.class)// 设置父类
.enableMapperAnnotation()// 开启 @Mapper 注解,默认值:false
.enableBaseResultMap()// 启用 BaseResultMap 生成,默认值:false
.enableBaseColumnList()// 启用 BaseColumnList,默认值:false
// .enableRestStyle()// 开启生成@RestController 控制器,默认值:false
.controllerBuilder().enableHyphenStyle();// 开启驼峰转连字符,默认值:false
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用 Freemarker 引擎模板
.execute();
}
}
BaseMapper接口
mapper接口需要继承baseMapper
/**
* Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
* 这个 Mapper 支持 id 泛型*/
public interface BaseMapper<T> {
/**
* 插入一条记录
* @param entity
* 实体对象
* @return int
*/
Integer insert(T entity);
/**
* 根据 ID 删除
* @param id
* 主键ID
* @return int
*/
Integer deleteById(Serializable id);
/**
* 根据 columnMap 条件,删除记录
* @param columnMap
* 表字段 map 对象
* @return int
*/
Integer deleteByMap(@Param("cm") Map<String, Object> columnMap);
/**
* 根据 entity 条件,删除记录
* @param wrapper
* 实体对象封装操作类(可以为 null)
* @return int
*/
Integer delete(@Param("ew") Wrapper<T> wrapper);
/**
* 删除(根据ID 批量删除)
* @param idList
* 主键ID列表
* @return int
*/
Integer deleteBatchIds(List<? extends Serializable> idList);
/**
* 根据 ID 修改
* @param entity
* 实体对象
* @return int
*/
Integer updateById(T entity);
/**
* 根据 whereEntity 条件,更新记录
* @param entity
* 实体对象
* @param wrapper
* 实体对象封装操作类(可以为 null)
* @return
*/
Integer update(@Param("et") T entity, @Param("ew") Wrapper<T> wrapper);
/**
* 根据 ID 查询
* @param id
* 主键ID
* @return T
*/
T selectById(Serializable id);
/**
* 查询(根据ID 批量查询)
* @param idList
* 主键ID列表
* @return List<T>
*/
List<T> selectBatchIds(List<? extends Serializable> idList);
/**
* 查询(根据 columnMap 条件)
* @param columnMap
* 表字段 map 对象
* @return List<T>
*/
List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);
/**
* 根据 entity 条件,查询一条记录
* @param entity
* 实体对象
* @return T
*/
T selectOne(@Param("ew") T entity);
/**
* 根据 Wrapper 条件,查询总记录数
* @param wrapper
* 实体对象
* @return int
*/
Integer selectCount(@Param("ew") Wrapper<T> wrapper);
/**
* 根据 entity 条件,查询全部记录
* @param wrapper
* 实体对象封装操作类(可以为 null)
* @return List<T>
*/
List<T> selectList(@Param("ew") Wrapper<T> wrapper);
/**
* 根据 Wrapper 条件,查询全部记录
* @param wrapper
* 实体对象封装操作类(可以为 null)
* @return List<T>
*/
List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> wrapper);
/**
* 根据 Wrapper 条件,查询全部记录
* @param wrapper
* 实体对象封装操作类(可以为 null)
* @return List<Object>
*/
List<Object> selectObjs(@Param("ew") Wrapper<T> wrapper);
/**
* 用法:(new RowBounds(offset, limit), ew);
* 根据 entity 条件,查询全部记录(并翻页)
* @param rowBounds
* 分页查询条件(可以为 RowBounds.DEFAULT)
* @param wrapper
* 实体对象封装操作类(可以为 null)
* @return List<T>
*/
List<T> selectPage(RowBounds rowBounds, @Param("ew") Wrapper<T> wrapper);
/** -- 不常用,
* 根据 Wrapper 条件,查询全部记录(并翻页)
* @param rowBounds
* 分页查询条件(可以为 RowBounds.DEFAULT)
* @param wrapper
* 实体对象封装操作类
* @return List<Map<String, Object>>
*/
List<Map<String, Object>> selectMapsPage(RowBounds rowBounds, @Param("ew") Wrapper<T> wrapper);
}
IService接口
官方文档
分页page
// 无条件分页查询
IPage<T> page(IPage<T> page);
// 条件分页查询
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
// 无条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page);
// 条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);
条件sql用例
Wrapper条件构造器
查询条件构造器:
LambdaQueryWrapper<实体类> wrapper = new LambdaQueryWrapper<>();
实体类::get属性
修改条件构造器:LambdaUpdateWrapper
逻辑删除
逻辑删除是名义上的删除,就是对要要删除的数据打上一个删除标记,在逻辑上数据是被删除的,但数据本身依然存在,可通过修改删除标记来恢复数据。
只对自动注入的 sql 起效,自己在mapper.xml中写的sql不生效:
插入: 不作限制
查找: 追加 where 条件过滤掉已删除数据
更新: 追加 where 条件防止更新到已删除数据
删除: 转变为更新
实体类加@TableLog
分页插件
先创建一个配置值类
package com.zax.appmanage.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration//myBatisPlus分页配置
@MapperScan("com.zax.appmanage.mapper")
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return mybatisPlusInterceptor;
}
}
分页导航栏
//新建一个数组,用来存放分页导航栏
List<Integer> pages = new ArrayList<>();
//将当前页放入数组
pages.add(pageNum);//pageNum为当前页
for (int i = 1; i <= 3; i++) {//当数据里的数只有1-3个
//左边的元素
if (pageNum - i > 0) {
pages.add(0, pageNum - i);
}
//右边的元素
if (pageNum + i <= questions.getPages()) {// questions.getPages()从MybatisPlus分页插件中查出分页条数
pages.add(pageNum + i);
}
}
多表联查
@TableField(exist=false)
在实体类中表示此属性不是数据库中的字段,但在项目中必须使用
条件多表联查
https://blog.csdn.net/qq_43073558/article/details/120616959
这里需要注意:写完SQL语句后,需要在结尾加上${ew.customSqlSegment},查询参数,由mybatis plus自动拼装。
/**
* 获取自定义SQL 简化自定义XML复杂情况
* <p>使用方法</p>
* <p>`自定义sql` + ${ew.customSqlSegment}</p>
* <p>1.逻辑删除需要自己拼接条件 (之前自定义也同样)</p>
* <p>2.不支持wrapper中附带实体的情况 (wrapper自带实体会更麻烦)</p>
* <p>3.用法 ${ew.customSqlSegment} (不需要where标签包裹,切记!)</p>
* <p>4.ew是wrapper定义别名,可自行替换</p>
*/
//多表分页多条件查询
Page<User> selectAllByLike
(@Param("page")Page<User> page, //分页
@Param(Constants.WRAPPER) Wrapper<User> wrapper);//条件查询
//Constants.WRAPPER就是ew
//条件联查
<select id="selectAllByLike" resultType="com.zax.appmanage.entity.User">
select * from user,data_dictionary
where typeCode='USER_TYPE'
AND userType=valueId
<if test="ew != null">
<if test="ew.nonEmptyOfWhere">
AND
</if>
${ew.sqlSegment}
</if>
</select>
//条件查询
@Override
public Page<User> selectAllByLike(Integer pageNum, Integer pageSize, String userName, Integer userType,Integer myUserType
, LocalDateTime old, LocalDateTime yang) {
QueryWrapper<User> wrapper=new QueryWrapper<>();
//分页设置
Page<User> page = new Page<>(pageNum==null?1:pageNum,pageSize);
//条件设置
wrapper.like(StringUtils.isNotBlank(userName),"userName",userName)
.eq(userType!=null,"userType",userType)
.gt("userType",myUserType)//>
.ge(old!=null,"user.creationDate",old)//>=
.le(yang!=null,"user.creationDate",yang);//<=
// .orderByDesc("user.creationDate");
return userMapper.selectAllByLike(page, wrapper);
}