SpringBoot整合Mybatis-Plus

SpringBoot整合Mybatis-Plus

1、创建springboot工程

在这里插入图片描述
选择插件
在这里插入图片描述
添加mybatisplus 、lombok pom依赖

			<!--简略get、set方法-->
		        <dependency>
		            <groupId>org.projectlombok</groupId>
		            <artifactId>lombok</artifactId>
		            <version>1.18.10</version>
		        </dependency>
		        <!-- mybatis plus 代码生成器 -->
		        <dependency>
		            <groupId>com.baomidou</groupId>
		            <artifactId>mybatis-plus-boot-starter</artifactId>
		            <version>3.2.0</version>
		        </dependency>
		        

yml文件


server:
  port: 8081
  servlet:
    context-path: /

spring:
  datasource:
    #    驱动
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8
    password: root
    username: 123456
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
    serialization:
      write-dates-as-timestamps: false

#控制台打印sql
mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
    auto-mapping-behavior: full
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations: classpath*:mapper/**/*Mapper.xml
  global-config:
    # 逻辑删除配置
    db-config:
      # 删除前
      logic-not-delete-value: 1
      # 删除后
      logic-delete-value: 0

便携式对应的实体类

//使用lombok 简化getset方法
@Data
public class User extends Model {

    private static final long serialVersionUID = 1L;

    private String name;

    private Integer age;

    private Integer sex;

    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
}

编写操作实体类的Mapper类

直接继承BaseMapper,这是mybatis-plus封装好的类,封装了常用的crud的方法
可以省略xml的编写,也可以通过xml自定义sql

public interface UserMapper extends BaseMapper<User> {
    
}

在这里插入图片描述

测试。创建对应的service、controller,测试接口
在这里插入图片描述

在启动类上增加mapperscan标签指定mapper扫描路径
在这里插入图片描述

执行结果打印
在这里插入图片描述

mybatisPlus常用注解

【@TableName 】	作用于类上
    @TableName               用于定义表名
注:
    常用属性:
        value                用于定义表名

【@TableId】		作用于属性上
    @TableId                 用于定义表的主键
注:
    常用属性:
        value           用于定义主键字段名
        type            用于定义主键类型(主键策略 IdType)

   主键策略:
      IdType.AUTO          主键自增,系统分配,不需要手动输入
      IdType.NONE          未设置主键
      IdType.INPUT         需要自己输入 主键值。
      IdType.ASSIGN_ID     系统分配 ID,用于数值型数据(Long,对应 mysql 中 BIGINT 类型)。
      IdType.ASSIGN_UUID   系统分配 UUID,用于字符串型数据(String,对应 mysql 中 varchar(32) 类型)。

【@TableField】  	作用与属性上
    @TableField            用于定义表的非主键字段。
注:
    常用属性:
        value                用于定义非主键字段名
        exist                用于指明是否为数据表的字段, true 表示是,false 为不是。
        fill                 用于指定字段填充策略(FieldFill)。
        
    字段填充策略:(一般用于填充 创建时间、修改时间等字段)
        FieldFill.DEFAULT         默认不填充
        FieldFill.INSERT          插入时填充
        FieldFill.UPDATE          更新时填充
        FieldFill.INSERT_UPDATE   插入、更新时填充。

【@TableLogic】
    @TableLogic           用于定义表的字段进行逻辑删除(非物理删除)
注:
    常用属性:
        value            用于定义未删除时字段的值
        delval           用于定义删除时字段的值
        
【@Version】		作用于属性上
    @Version             用于字段实现乐观锁


/**
 * 用户测试类
 */

//指定数据库表名称 user_test1
@TableName(value = "user_test1")
public class UserTest {

    /**
     * 主键id 设置自增长策略
     */
    @TableId(value = "id",type = IdType.AUTO)
    private int id;

    /**
     * 用户名称
     */
    @TableField(value = "username")
    private String username;

    /**
     * 年龄
     */
    @TableField(value = "age")
    private int age;

    /**
     * 电话
     */
    @TableField(value = "tel")
    private int tel;

    /**
     * 创建时间
     */
    @TableField(value = "create_time")
    private Date create_time;

    /**
     * 最后修改时间
     */
    @TableField(value = "update_time")
    private Date update_time;

    /**
     * 版本号(用于乐观锁,默认为1)
     * @return
     */
    //@Version
    @TableField(value = "version")
    private int version;
}

原文链接:https://blog.csdn.net/q736317048/article/details/110284582

BaseMapper 接口中封装了一系列 CRUD 常用操作,可以直接使用,而不用自定义 xml 与 sql 语句进行 CRUD 操作(当然根据实际开发需要,自定义 sql 还是有必要的)。

BaseMapper方法简介


【添加数据:(增)】
    int insert(T entity);              // 插入一条记录
注:
    T         表示任意实体类型
    entity    表示实体对象

【删除数据:(删)】
    int deleteById(Serializable id);    // 根据主键 ID 删除
    int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);  // 根据 map 定义字段的条件删除
    int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper); // 根据实体类定义的 条件删除对象
    int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); // 进行批量删除
注:
    id        表示 主键 ID
    columnMap 表示表字段的 map 对象
    wrapper   表示实体对象封装操作类,可以为 null。
    idList    表示 主键 ID 集合(列表、数组),不能为 null 或 empty

【修改数据:(改)】
    int updateById(@Param(Constants.ENTITY) T entity); // 根据 ID 修改实体对象。
    int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper); // 根据 updateWrapper 条件修改实体对象
注:
    update 中的 entity 为 set 条件,可以为 null。
    updateWrapper 表示实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)

【查询数据:(查)】
    T selectById(Serializable id); // 根据 主键 ID 查询数据
    List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); // 进行批量查询
    List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); // 根据表字段条件查询
    T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 根据实体类封装对象 查询一条记录
    
    Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查询记录的总条数
    
    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查询所有记录(返回 entity 集合)
    
    List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查询所有记录(返回 map 集合)
    
    List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查询所有记录(但只保存第一个字段的值)
    
    <E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查询所有记录(返回 entity 集合),分页
    
    <E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查询所有记录(返回 map 集合),分页
注:
    queryWrapper 表示实体对象封装操作类(可以为 null)
    page 表示分页查询条件

Service层接口介绍:

IService 内部进一步封装了 BaseMapper 接口的方法(当然也提供了更详细的方法)。
使用时,可以通过 生成的 mapper 类进行 CRUD 操作,也可以通过 生成的 service 的实现类进行 CRUD 操作。(当然,自定义代码执行也可,不选择继承IService)

【添加数据:(增)】
    default boolean save(T entity); // 调用 BaseMapper 的 insert 方法,用于添加一条数据。
    boolean saveBatch(Collection<T> entityList, int batchSize); // 批量插入数据
注:
    entityList 表示实体对象集合 
    batchSize 表示一次批量插入的数据量,默认为 1000

【添加或修改数据:(增或改)】
    boolean saveOrUpdate(T entity); // id 若存在,则修改, id 不存在则新增数据
   default boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper); // 先根据条件尝试更新,然后再执行 saveOrUpdate 操作
   boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize); // 批量插入并修改数据 

【删除数据:(删)】
    default boolean removeById(Serializable id); // 调用 BaseMapper 的 deleteById 方法,根据 id 删除数据。
    default boolean removeByMap(Map<String, Object> columnMap); // 调用 BaseMapper 的 deleteByMap 方法,根据 map 定义字段的条件删除
    default boolean remove(Wrapper<T> queryWrapper); // 调用 BaseMapper 的 delete 方法,根据实体类定义的 条件删除对象。
    default boolean removeByIds(Collection<? extends Serializable> idList); // 用 BaseMapper 的 deleteBatchIds 方法, 进行批量删除。
    
【修改数据:(改)】
    default boolean updateById(T entity); // 调用 BaseMapper 的 updateById 方法,根据 ID 选择修改。
    default boolean update(T entity, Wrapper<T> updateWrapper); // 调用 BaseMapper 的 update 方法,根据 updateWrapper 条件修改实体对象。
    boolean updateBatchById(Collection<T> entityList, int batchSize); // 批量更新数据

【查找数据:(查)】
    default T getById(Serializable id); // 调用 BaseMapper 的 selectById 方法,根据 主键 ID 返回数据。
    default List<T> listByIds(Collection<? extends Serializable> idList); // 调用 BaseMapper 的 selectBatchIds 方法,批量查询数据。
    default List<T> listByMap(Map<String, Object> columnMap); // 调用 BaseMapper 的 selectByMap 方法,根据表字段条件查询
    default T getOne(Wrapper<T> queryWrapper); // 返回一条记录(实体类保存)。
    Map<String, Object> getMap(Wrapper<T> queryWrapper); // 返回一条记录(map 保存)。
    default int count(Wrapper<T> queryWrapper); // 根据条件返回 记录数。
    default List<T> list(); // 返回所有数据。
    default List<T> list(Wrapper<T> queryWrapper); // 调用 BaseMapper 的 selectList 方法,查询所有记录(返回 entity 集合)。
    default List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper); // 调用 BaseMapper 的 selectMaps 方法,查询所有记录(返回 map 集合)。
    default List<Object> listObjs(); // 返回全部记录,但只返回第一个字段的值。
    default <E extends IPage<T>> E page(E page, Wrapper<T> queryWrapper); // 调用 BaseMapper 的 selectPage 方法,分页查询
    default <E extends IPage<Map<String, Object>>> E pageMaps(E page, Wrapper<T> queryWrapper); // 调用 BaseMapper 的 selectMapsPage 方法,分页查询
注:
    get 用于返回一条记录。
    list 用于返回多条记录。
    count 用于返回记录总数。
    page 用于分页查询。
    
【链式调用:】
    default QueryChainWrapper<T> query(); // 普通链式查询
    default LambdaQueryChainWrapper<T> lambdaQuery(); // 支持 Lambda 表达式的修改
    default UpdateChainWrapper<T> update(); // 普通链式修改
    default LambdaUpdateChainWrapper<T> lambdaUpdate(); // 支持 Lambda 表达式的修改
注:
    query 表示查询
    update 表示修改
    Lambda 表示内部支持 Lambda 写法。
形如:
    query().eq("column", value).one();
    lambdaQuery().eq(Entity::getId, value).list();
    update().eq("column", value).remove();
    lambdaUpdate().eq(Entity::getId, value).update(entity);

条件构造器(Wrapper,定义where条件)

简介: 上面介绍的 接口方法的参数中,会出现各种 wrapper,比如 queryWrapper、updateWrapper 等。wrapper 的作用就是用于定义各种各样的查询条件(where)。

Wrapper  条件构造抽象类
    -- AbstractWrapper 查询条件封装,用于生成 sql 中的 where 语句。
        -- QueryWrapper Entity 对象封装操作类,用于查询。
        -- UpdateWrapper Update 条件封装操作类,用于更新。
    -- AbstractLambdaWrapper 使用 Lambda 表达式封装 wrapper
        -- LambdaQueryWrapper 使用 Lambda 语法封装条件,用于查询。
        -- LambdaUpdateWrapper 使用 Lambda 语法封装条件,用于更新
【通用条件:】
【比较大小: ( =, <>, >, >=, <, <= )】
    eq(R column, Object val); // 等价于 =,例: eq("name", "老王") ---> name = '老王'
    ne(R column, Object val); // 等价于 <>,例: ne("name", "老王") ---> name <> '老王'
    gt(R column, Object val); // 等价于 >,例: gt("name", "老王") ---> name > '老王'
    ge(R column, Object val); // 等价于 >=,例: ge("name", "老王") ---> name >= '老王'
    lt(R column, Object val); // 等价于 <,例: lt("name", "老王") ---> name < '老王'
    le(R column, Object val); // 等价于 <=,例: le("name", "老王") ---> name <= '老王'
    
【范围:(between、not between、in、not in)】
   between(R column, Object val1, Object val2); // 等价于 between a and b, 例: 			between("age", 18, 30) ---> age between 18 and 30
   notBetween(R column, Object val1, Object val2); // 等价于 not between a and b, 例: 	notBetween("age", 18, 30) ---> age not between 18 and 30
   in(R column, Object... values); // 等价于 字段 IN (v0, v1, ...),例: in("age",{1,2,3}) ---> age in (1,2,3)
   notIn(R column, Object... values); // 等价于 字段 NOT IN (v0, v1, ...), 例: notIn("age",{1,2,3}) ---> age not in (1,2,3)
   inSql(R column, Object... values); // 等价于 字段 IN (sql 语句), 例: inSql("id", "select id from table where id < 3") ---> id in (select id from table where id < 3)
   notInSql(R column, Object... values); // 等价于 字段 NOT IN (sql 语句)
   
【模糊匹配:(like)】
    like(R column, Object val); // 等价于 LIKE '%值%',例: like("name", "王") ---> name like '%王%'
    notLike(R column, Object val); // 等价于 NOT LIKE '%值%',例: notLike("name", "王") ---> name not like '%王%'
    likeLeft(R column, Object val); // 等价于 LIKE '%值',例: likeLeft("name", "王") ---> name like '%王'
    likeRight(R column, Object val); // 等价于 LIKE '值%',例: likeRight("name", "王") ---> name like '王%'
    
【空值比较:(isNull、isNotNull)】
    isNull(R column); // 等价于 IS NULL,例: isNull("name") ---> name is null
    isNotNull(R column); // 等价于 IS NOT NULL,例: isNotNull("name") ---> name is not null

【分组、排序:(group、having、order)】
    groupBy(R... columns); // 等价于 GROUP BY 字段, ..., 例: groupBy("id", "name") ---> group by id,name
    orderByAsc(R... columns); // 等价于 ORDER BY 字段, ... ASC, 例: orderByAsc("id", "name") ---> order by id ASC,name ASC
    orderByDesc(R... columns); // 等价于 ORDER BY 字段, ... DESC, 例: orderByDesc("id", "name") ---> order by id DESC,name DESC
    having(String sqlHaving, Object... params); // 等价于 HAVING ( sql语句 ), 例: having("sum(age) > {0}", 11) ---> having sum(age) > 11

【拼接、嵌套 sql:(or、and、nested、apply)】
   or(); // 等价于 a or b, 例:eq("id",1).or().eq("name","老王") ---> id = 1 or name = '老王'
   or(Consumer<Param> consumer); // 等价于 or(a or/and b),or 嵌套。例: or(i -> i.eq("name", "李白").ne("status", "活着")) ---> or (name = '李白' and status <> '活着')
   and(Consumer<Param> consumer); // 等价于 and(a or/and b),and 嵌套。例: and(i -> i.eq("name", "李白").ne("status", "活着")) ---> and (name = '李白' and status <> '活着')
   nested(Consumer<Param> consumer); // 等价于 (a or/and b),普通嵌套。例: nested(i -> i.eq("name", "李白").ne("status", "活着")) ---> (name = '李白' and status <> '活着')
   apply(String applySql, Object... params); // 拼接sql(若不使用 params 参数,可能存在 sql 注入),例: apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2008-08-08") ---> date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")
   last(String lastSql); // 无视优化规则直接拼接到 sql 的最后,可能存若在 sql 注入。
   exists(String existsSql); // 拼接 exists 语句。例: exists("select id from table where age = 1") ---> exists (select id from table where age = 1)
   
【QueryWrapper 条件:】
    select(String... sqlSelect); // 用于定义需要返回的字段。例: select("id", "name", "age") ---> select id, name, age
    select(Predicate<TableFieldInfo> predicate); // Lambda 表达式,过滤需要的字段。
    lambda(); // 返回一个 LambdaQueryWrapper
    
【UpdateWrapper 条件:】
    set(String column, Object val); // 用于设置 set 字段值。例: set("name", null) ---> set name = null
    etSql(String sql); // 用于设置 set 字段值。例: setSql("name = '老李头'") ---> set name = '老李头'
    lambda(); // 返回一个 LambdaUpdateWrapper 

测试查询条件
与自定义sql的区别

//模糊查询用户姓名
    @Override
    public List<User> likeListUser(String name) {

        //创建一个queryWrapper对象
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
        //构造一个查询条件
        queryWrapper.select("name","age","sex","id")
                .like("name",name)
                .ne("age",10);

        List<User> users = userMapper.selectList(queryWrapper);
        return users;
    }

分页插件使用

使用bean标签注入spring容器

/**
 * 配置分页插件
 *
 */
@Configuration
public class MybatisPlusConfig {
    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}

service层自定义接口,编写分页代码

@Override
    public List<User> pagelist(int current, int size) {

//创建分页对象
        Page<User> page = new Page<User>(current,size);

//可以定义查询条件
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
//调用mapper提供的分页查询方法,返回的数据封装在page对象records中,或者返回值的records中
        IPage<User> userIPage = userMapper.selectPage(page, null);

        // Step3:获取分页数据
        System.out.println(page.getCurrent()); // 获取当前页
        System.out.println(page.getTotal()); // 获取总记录数
        System.out.println(page.getSize()); // 获取每页的条数 默认10
        System.out.println(page.getRecords()); // 获取每页数据的集合
        System.out.println(page.getPages()); // 获取总页数
        System.out.println(page.hasNext()); // 是否存在下一页
        System.out.println(page.hasPrevious()); // 是否存在上一页

        return userIPage.getRecords();
    }

测试

/**
     * 分页显示用户信息
     */

    @GetMapping("pagelist")
    public List<User> pagelist(@RequestParam("current") int current,@RequestParam("size") int size) {

        List<User> userTestList = userService.pagelist(current, size);

        return  userTestList;
    }

自动填充数据

添加、修改数据时,每次都会使用相同的方式进行填充。比如 数据的创建时间、修改时间等。
Mybatis-plus 支持自动填充这些字段的数据。

给大家的数据表中有创建时间和修改时间字段

//TableField定义非主键字段,fill填充类型  插入时填充时间
    @TableField(value = "intime", fill = FieldFill.INSERT)
    private Date intime;

    //插入和修改时都填充
    @TableField(value = "uptime", fill = FieldFill.INSERT_UPDATE)
    private Date uptime;

自定义类,实现 MetaObjectHandler 接口,并重写方法

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    /**
     * 自定义填充内容,根据属性名去填充数据
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "intime", Date.class, new Date());
    }

    private void strictInsertFill(MetaObject metaObject, String create_time, Class<Date> dateClass, Date date) {
        setInsertFieldValByName(create_time,date,metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "uptime", Date.class, new Date());
    }

    private void strictUpdateFill(MetaObject metaObject, String update_time, Class<Date> dateClass, Date date) {
        setFieldValByName(update_time,date,metaObject, FieldFill.INSERT_UPDATE);
        }
}
//添加自动填充
    @Override
    public int saveUser(User user) {

        int i = userMapper.insert(user);
        return i;
    }

    //修改自动填充
    @Override
    public int updateUser(User user) {


        int i = userMapper.updateById(user);
        return i;
    }
 //添加自动填充数据
    @PostMapping("/saveUser")
    public String saveUser(@RequestBody User user){
        String re = "success";
        int i = userService.saveUser(user);
        if (i == 0){
            re = "error";
        }
        return re;
    }

    //修改填充数据
    @PostMapping("/updateUser")
    public String updateUser(@RequestBody User user){
        String re = "success";
        int i = userService.updateUser(user);
        if (i == 0){
            re = "error";
        }
        return re;
    }

逻辑删除

删除数据,可以通过物理删除,也可以通过逻辑删除。
  物理删除指的是直接将数据从数据库中删除,不保留。
  逻辑删除指的是修改数据的某个字段,使其表示为已删除状态,而非删除数据,保留该数据在数据库中,但是 查询时不显示该数据(查询时过滤掉该数据)。

给数据表增加一个字段:delete_flag,用于表示该数据是否被逻辑删除。

//逻辑删除字段  0未删除  1已删除 0为初始字段
    @TableLogic(value = "0", delval = "1")
    @TableField(value="delete_flag", fill = FieldFill.INSERT)
    private int deleteFlag;
//删除
    @Override
    public int deleteUser(int id) {
        int i = userMapper.deleteById(id);
        return i;
    }

执行sql:UPDATE user SET delete_flag=1 WHERE id=? AND delete_flag=0
可以看到数据库中数据并没有消失,而是delete_flag字段改成了0。其实再执行sql时是执行了修改语句
在这里插入图片描述
执行查询语句后发现,确实不存在delete_flag=1的那条数据了,因为我们在属性上定义的逻辑删除注解delval的值,可根据数据库设计定义具体值

物理删除

去除 TableLogic 注解 ,会进行物理删除
可以看到执行的sql语句是delete,而且再次查询时也不会带上delete_flag的条件

乐观锁实现

通过version机制实现
实现思路:
1.取出数据时,获取当前version
2.更新时,带上这个version
3.执行更新时,set version = newVersion where version = oldVersion
4.如果version不对,就更新失败

//版本号(用于乐观锁,默认为1)
    @Version
    @TableField(fill = FieldFill.INSERT)
    private int version;
//自动填充工具类中增加
@Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "version", Integer.class, 1);
    }

附录:

一份详尽的yml配置文件(关于数据源的配置比较详尽):

server:
  port: 8085
  servlet:
    context-path: /test


spring:
  #redis集群
  redis:
    host: 127.0.0.1
    port: 6379
    timeout: 20000
    #    集群环境打开下面注释,单机不需要打开
    #    cluster:
    #      集群信息
    #      nodes: xxx.xxx.xxx.xxx:xxxx,xxx.xxx.xxx.xxx:xxxx,xxx.xxx.xxx.xxx:xxxx
    #      #默认值是5 一般当此值设置过大时,容易报:Too many Cluster redirections
    #      maxRedirects: 3
    password: lyja
    application:
      name: test
    jedis:
      pool:
        max-active: 8
        min-idle: 0
        max-idle: 8
        max-wait: -1
    database: 0

  autoconfigure:
    exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
  datasource:
    dynamic:
      #设置默认的数据源或者数据源组,默认值即为master
      primary: master
      strict: false
      datasource:
        master:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://127.0.0.1:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false
          username: root
          password: lyja
    # 数据源配置
    druid:
      # druid连接池监控
      stat-view-servlet:
        enabled: true
        url-pattern: /druid/*
        login-username: admin
        login-password: admin
        # 初始化时建立物理连接的个数
        initial-size: 5
        # 最大连接池数量
        max-active: 30
        # 最小连接池数量
        min-idle: 5
        # 获取连接时最大等待时间,单位毫秒
        max-wait: 60000
        # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
        time-between-eviction-runs-millis: 60000
        # 连接保持空闲而不被驱逐的最小时间
        min-evictable-idle-time-millis: 300000
        # 用来检测连接是否有效的sql,要求是一个查询语句
        validation-query: select count(*) from dual
        # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
        test-while-idle: true
        # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
        test-on-borrow: false
        # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
        test-on-return: false
        # 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
        pool-prepared-statements: false
        # 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。
        max-pool-prepared-statement-per-connection-size: 50
        # 配置监控统计拦截的filters,去掉后监控界面sql无法统计
        filters: stat,wall
        # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
        connection-properties:
          druid.stat.mergeSql: true
          druid.stat.slowSqlMillis: 500
        # 合并多个DruidDataSource的监控数据
        use-global-data-source-stat: true
        filter:
          stat:
            log-slow-sql: true
            slow-sql-millis: 1000
            merge-sql: true
          wall:
            config:
              multi-statement-allow: true
  servlet:
    multipart:
      # 开启 multipart 上传功能
      enabled: true
      # 文件写入磁盘的阈值
      file-size-threshold: 2KB
      # 最大文件大小
      max-file-size: 200MB
      # 最大请求大小
      max-request-size: 215MB

mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
    auto-mapping-behavior: full
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations: classpath*:mapper/**/*Mapper.xml
  global-config:
    # 逻辑删除配置
    db-config:
      # 删除前
      logic-not-delete-value: 1
      # 删除后
      logic-delete-value: 0
logging:
  level:
    root: info
    com.example: debug
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值