Mybatis-plus扩展

2023-05-16

这玩意类似于mp自带的basemapper

/*
 * Copyright (c) 2011-2020, baomidou (jobob@qq.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.baomidou.mybatisplus.extension.activerecord;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.TableInfoHelper;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;

import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionUtils;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * ActiveRecord 模式 CRUD
 * <p>
 * 必须存在对应的原始mapper并继承baseMapper并且可以使用的前提下
 * 才能使用此 AR 模式 !!!
 * </p>
 *
 * @param <T>
 * @author hubin
 * @since 2016-11-06
 */
public abstract class Model<T extends Model<?>> implements Serializable {

    private static final long serialVersionUID = 1L;

    private transient Log log = LogFactory.getLog(getClass());

    /**
     * 插入(字段选择插入)
     */
    public boolean insert() {
        SqlSession sqlSession = sqlSession();
        try {
            return SqlHelper.retBool(sqlSession.insert(sqlStatement(SqlMethod.INSERT_ONE), this));
        } finally {
            closeSqlSession(sqlSession);
        }
    }

    /**
     * 插入 OR 更新
     */
    public boolean insertOrUpdate() {
        return StringUtils.checkValNull(pkVal()) || Objects.isNull(selectById(pkVal())) ? insert() : updateById();
    }

    /**
     * 根据 ID 删除
     *
     * @param id 主键ID
     */
    public boolean deleteById(Serializable id) {
        SqlSession sqlSession = sqlSession();
        try {
            return SqlHelper.retBool(sqlSession.delete(sqlStatement(SqlMethod.DELETE_BY_ID), id));
        } finally {
            closeSqlSession(sqlSession);
        }
    }

    /**
     * 根据主键删除
     */
    public boolean deleteById() {
        Assert.isFalse(StringUtils.checkValNull(pkVal()), "deleteById primaryKey is null.");
        return deleteById(pkVal());
    }

    /**
     * 删除记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    public boolean delete(Wrapper<T> queryWrapper) {
        Map<String, Object> map = new HashMap<>(1);
        map.put(Constants.WRAPPER, queryWrapper);
        SqlSession sqlSession = sqlSession();
        try {
            return SqlHelper.retBool(sqlSession.delete(sqlStatement(SqlMethod.DELETE), map));
        } finally {
            closeSqlSession(sqlSession);
        }
    }

    /**
     * 更新(字段选择更新)
     */
    public boolean updateById() {
        Assert.isFalse(StringUtils.checkValNull(pkVal()), "updateById primaryKey is null.");
        // updateById
        Map<String, Object> map = new HashMap<>(1);
        map.put(Constants.ENTITY, this);
        SqlSession sqlSession = sqlSession();
        try {
            return SqlHelper.retBool(sqlSession.update(sqlStatement(SqlMethod.UPDATE_BY_ID), map));
        } finally {
            closeSqlSession(sqlSession);
        }
    }

    /**
     * 执行 SQL 更新
     *
     * @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
     */
    public boolean update(Wrapper<T> updateWrapper) {
        Map<String, Object> map = new HashMap<>(2);
        map.put(Constants.ENTITY, this);
        map.put(Constants.WRAPPER, updateWrapper);
        // update
        SqlSession sqlSession = sqlSession();
        try {
            return SqlHelper.retBool(sqlSession.update(sqlStatement(SqlMethod.UPDATE), map));
        } finally {
            closeSqlSession(sqlSession);
        }
    }

    /**
     * 查询所有
     */
    public List<T> selectAll() {
        SqlSession sqlSession = sqlSession();
        try {
            return sqlSession.selectList(sqlStatement(SqlMethod.SELECT_LIST));
        } finally {
            closeSqlSession(sqlSession);
        }
    }

    /**
     * 根据 ID 查询
     *
     * @param id 主键ID
     */
    public T selectById(Serializable id) {
        SqlSession sqlSession = sqlSession();
        try {
            return sqlSession.selectOne(sqlStatement(SqlMethod.SELECT_BY_ID), id);
        } finally {
            closeSqlSession(sqlSession);
        }
    }

    /**
     * 根据主键查询
     */
    public T selectById() {
        Assert.isFalse(StringUtils.checkValNull(pkVal()), "selectById primaryKey is null.");
        return selectById(pkVal());
    }

    /**
     * 查询总记录数
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */

    public List<T> selectList(Wrapper<T> queryWrapper) {
        Map<String, Object> map = new HashMap<>(1);
        map.put(Constants.WRAPPER, queryWrapper);
        SqlSession sqlSession = sqlSession();
        try {
            return sqlSession.selectList(sqlStatement(SqlMethod.SELECT_LIST), map);
        } finally {
            closeSqlSession(sqlSession);
        }
    }

    /**
     * 查询一条记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    public T selectOne(Wrapper<T> queryWrapper) {
        return SqlHelper.getObject(log, selectList(queryWrapper));
    }

    /**
     * 翻页查询
     *
     * @param page         翻页查询条件
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    public IPage<T> selectPage(IPage<T> page, Wrapper<T> queryWrapper) {
        Map<String, Object> map = new HashMap<>(2);
        map.put(Constants.WRAPPER, queryWrapper);
        map.put("page", page);
        SqlSession sqlSession = sqlSession();
        try {
            page.setRecords(sqlSession.selectList(sqlStatement(SqlMethod.SELECT_PAGE), map));
        } finally {
            closeSqlSession(sqlSession);
        }
        return page;
    }

    /**
     * 查询总数
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    public Integer selectCount(Wrapper<T> queryWrapper) {
        Map<String, Object> map = new HashMap<>(1);
        map.put(Constants.WRAPPER, queryWrapper);
        SqlSession sqlSession = sqlSession();
        try {
            return SqlHelper.retCount(sqlSession.<Integer>selectOne(sqlStatement(SqlMethod.SELECT_COUNT), map));
        } finally {
            closeSqlSession(sqlSession);
        }
    }

    /**
     * 执行 SQL
     */
    public SqlRunner sql() {
        return new SqlRunner(getClass());
    }

    /**
     * 获取Session 默认自动提交
     */
    protected SqlSession sqlSession() {
        return SqlHelper.sqlSession(getClass());
    }

    /**
     * 获取SqlStatement
     *
     * @param sqlMethod sqlMethod
     */
    protected String sqlStatement(SqlMethod sqlMethod) {
        return sqlStatement(sqlMethod.getMethod());
    }

    /**
     * 获取SqlStatement
     *
     * @param sqlMethod sqlMethod
     */
    protected String sqlStatement(String sqlMethod) {
        return SqlHelper.table(getClass()).getSqlStatement(sqlMethod);
    }

    /**
     * 主键值
     */
    protected Serializable pkVal() {
        return (Serializable) ReflectionKit.getMethodValue(this, TableInfoHelper.getTableInfo(getClass()).getKeyProperty());
    }

    /**
     * 释放sqlSession
     *
     * @param sqlSession session
     */
    protected void closeSqlSession(SqlSession sqlSession) {
        SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(getClass()));
    }
}

 

 

 

 

 

 使用mp与Oracle数据库组合

 mp的插件学习

3.1 mybatis 的插件机制
MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下, MyBatis 允许使用插件来拦截的方法
调用包括:
1. Executor (update, query, flflushStatements, commit, rollback, getTransaction, close, isClosed)
2. ParameterHandler (getParameterObject, setParameters)
3. ResultSetHandler (handleResultSets, handleOutputParameters)
4. StatementHandler (prepare, parameterize, batch, update, query)
我们看到了可以拦截 Executor 接口的部分方法,比如 update query commit rollback 等方法,还有其他接口的
一些方法等。
总体概括为:
1. 拦截执行器的方法
2. 拦截参数的处理
3. 拦截结果集的处理
4. 拦截 Sql 语法构建的处理

执行分析插件(可用作阻断全表更新、删除的误操作

 @Bean //SQL分析插件
    public SqlExplainInterceptor sqlExplainInterceptor(){

        SqlExplainInterceptor sqlExplainInterceptor = new SqlExplainInterceptor();

        List<ISqlParser> list = new ArrayList<>();
        list.add(new BlockAttackSqlParser()); //全表更新、删除的阻断器

        sqlExplainInterceptor.setSqlParserList(list);

        return sqlExplainInterceptor;

性能分析插件  (常用)

用于输出每条 SQL 语句及其执行时间,可以设置最大执行时间,超过时间会抛出异常。

(只适用于开发环境,生产环境不建议使用),作用范围是所有的sql语句

    <plugins>
        <!-- 性能分析插件 -->
        <plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor">
            <!--最大的执行时间,单位为毫秒-->
            <property name="maxTime" value="100"/>
            <!--对输出的SQL做格式化,默认为false-->
            <property name="format" value="true"/>
        </plugin>

 乐观锁插件(当要更新一条记录的时候,希望这条记录没有被别人更新)

 

<!--乐观锁插件-->
<plugin interceptor="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"/>

 第一步:在表中添加一列 version 并设置初始值为1

 第二步:给user实体对象添加version注释

    @Version //乐观锁的版本字段
    private Integer version;

Test

    /**
     * 测试乐观锁,主要是要加上一个version版本信息
     */
    @Test
    public void testUpdateVersion(){
        User user = new User();
        user.setId(2L);// 查询条件

        User userVersion = user.selectById();

        user.setAge(23); // 更新的数据
        user.setVersion(userVersion.getVersion()); // 当前的版本信息

        boolean result = user.updateById();
        System.out.println("result => " + result);
    }

sql注入器(basemapper中原有的API不满足,需要我们扩充)

如何扩展一个自定义的方法

编写 MyBaseMapper
package cn.itcast.mp.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import java.util.List;

public interface MyBaseMapper<T> extends BaseMapper<T> {

    List<T> findAll();

    // 在这里扩展其他的方法

}

编写User Mapper
package cn.itcast.mp.mapper;

import cn.itcast.mp.pojo.User;

//自己格外定义一个MyBaseMapper,
// 从此以后UserMapper不用继承BaseMapper了 只需要继承MyBaseMapper,
//实现了统一扩展
public interface UserMapper extends MyBaseMapper<User> {

    User findById(Long id);



}

如果直接继承AbstractSqlInjector的话,原有的BaseMapper中的方法将失效,所以我们选择继承DefaultSqlInjector 进行扩展。

package cn.itcast.mp.injectors;

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;

import java.util.ArrayList;
import java.util.List;

public class MySqlInjector extends DefaultSqlInjector {

    @Override
    public List<AbstractMethod> getMethodList() {
        List<AbstractMethod> list = new ArrayList<>();

        // 获取父类中的集合
        list.addAll(super.getMethodList());

        // 再扩充自定义的方法
        list.add(new FindAll());

        return list;
    }
}

编写FindAll

package cn.itcast.mp.injectors;

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;

public class FindAll extends AbstractMethod {

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {

        String sql = "select * from " + tableInfo.getTableName();
        SqlSource sqlSource = languageDriver.createSqlSource(configuration,sql, modelClass);

        return this.addSelectMappedStatement(mapperClass, "findAll", sqlSource, modelClass, tableInfo);
    }
}
注册到 Spring 容器
    /**
     * 注入自定义的SQL注入器
     * @return
     */
    @Bean
    public MySqlInjector mySqlInjector(){
        return new MySqlInjector();
    }

测试
@Test
    public void testFindAll(){
        List<User> users = this.userMapper.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }

mp自动填充功能

有些时候我们可能会有这样的需求,插入或者更新数据时,希望有些字段可以自动填充数据,比如密码、 version 等。在MP 中提供了这样的功能,可以实现自动填充。

// 插入数据时进行填充
    @TableField(select = false, fill = FieldFill.INSERT) //查询时不返回该字段的值
    private String password;
    private String name;
    private Integer age;

@TableField功能

/*
 * Copyright (c) 2011-2020, baomidou (jobob@qq.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.baomidou.mybatisplus.annotation;

import java.lang.annotation.*;


/**
 * 表字段标识
 *
 * @author hubin sjy tantan
 * @since 2016-09-09
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface TableField {

    /**
     * 字段值(驼峰命名方式,该值可无)
     */
    String value() default "";

    /**
     * 当该Field为类对象时, 可使用#{对象.属性}来映射到数据表.
     * <p>支持:@TableField(el = "role, jdbcType=BIGINT)</p>
     * <p>支持:@TableField(el = "role, typeHandler=com.baomidou.springcloud.typehandler.PhoneTypeHandler")</p>
     */
    String el() default "";

    /**
     * 是否为数据库表字段
     * <p>默认 true 存在,false 不存在</p>
     */
    boolean exist() default true;

    /**
     * 字段 where 实体查询比较条件
     * <p>默认 `=` 等值</p>
     */
    String condition() default "";

    /**
     * 字段 update set 部分注入, 该注解优于 el 注解使用
     * <p>例如:@TableField(.. , update="%s+1") 其中 %s 会填充为字段</p>
     * <p>输出 SQL 为:update 表 set 字段=字段+1 where ...</p>
     * <p>例如:@TableField(.. , update="now()") 使用数据库时间</p>
     * <p>输出 SQL 为:update 表 set 字段=now() where ...</p>
     */
    String update() default "";

    /**
     * 字段验证策略
     * <p>默认追随全局配置</p>
     */
    FieldStrategy strategy() default FieldStrategy.DEFAULT;

    /**
     * 字段自动填充策略
     */
    FieldFill fill() default FieldFill.DEFAULT;

    /**
     * 是否进行 select 查询
     * <p>大字段可设置为 false 不加入 select 查询范围</p>
     */
    boolean select() default true;

    /**
     * 是否保持使用全局的 Format 的值
     * <p> 只生效于 既设置了全局的 Format 也设置了上面 {@link #value()} 的值 </p>
     * <li> 如果是 false , 全局的 Format 不生效 </li>
     *
     * @since 3.1.1
     */
    boolean keepGlobalFormat() default false;
}
/*
 * Copyright (c) 2011-2020, baomidou (jobob@qq.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.baomidou.mybatisplus.annotation;

/**
 * 字段填充策略枚举类
 *
 * <p>
 * 判断注入的 insert 和 update 的 sql 脚本是否在对应情况下忽略掉字段的 if 标签生成
 * <if test="...">......</if>
 * 判断优先级比 {@link FieldStrategy} 高
 * </p>
 *
 * @author hubin
 * @since 2017-06-27
 */
public enum FieldFill {
    /**
     * 默认不处理
     */
    DEFAULT,
    /**
     * 插入时填充字段
     */
    INSERT,
    /**
     * 更新时填充字段
     */
    UPDATE,
    /**
     * 插入和更新时填充字段
     */
    INSERT_UPDATE
}

我们重定义了接口并重写了方法,以后只要执行basemapperAPI中的插入和更新操作,无需调用方法,程序会自动判断

package cn.itcast.mp.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    /**
        * 插入数据时填充
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        // 先获取到password的值,再进行判断,如果为空,就进行填充,如果不为空,就不做处理
        Object password = getFieldValByName("password", metaObject);
        if(null == password){
           setFieldValByName("password", "888888", metaObject);
        }
    }

    /**
     * 更新数据时填充
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {

    }
}
    @Test
    public void testInsert() {
        User user = new User();
        user.setMail("zhugeliang@itcast.cn");
        user.setAge(25);
        user.setUserName("zhugeliang");
        user.setName("诸葛亮");
//        user.setPassword("123456");
        user.setAddress("广州");

        int result = this.userMapper.insert(user); //result数据库受影响的行数
        System.out.println("result => " + result);

        //获取自增长后的id值, 自增长后的id值会回填到user对象中
        System.out.println("id => " + user.getId());
    }

逻辑删除

开发系统时,有时候在实现功能时,删除操作需要实现逻辑删除,所谓逻辑删除就是将数据标记为删除,而并非真正 的物理删除(非DELETE 操作), 查询时需要携带状态条件,确保被标记的数据不被查询到 。这样做的目的就是避免数据被真正的删除。

(如用户删除自己的订单数据,但实际上数据库中的订单数据还是存在的)

 

 

    @TableLogic // 逻辑删除字段 ,1-删除,0-未删除
    private Integer deleted;

 application.properties

# 删除状态的值为:1
mybatis-plus.global-config.db-config.logic-delete-value=1
# 未删除状态的值为:0
mybatis-plus.global-config.db-config.logic-not-delete-value=0

通用枚举

用来表示固定的,特有的一些类型,比如说性别(男女),学历(初中,高中,大学)

解决了繁琐的配置,让 mybatis 优雅的使用枚举属性!

 定义枚举

package cn.itcast.mp.enums;

import com.baomidou.mybatisplus.core.enums.IEnum;

public enum SexEnum implements IEnum<Integer> {

    MAN(1,"男"),
    WOMAN(2,"女");

    private int value;
    private String desc;

    SexEnum(int value, String desc) {
        this.value = value;
        this.desc = desc;
    }

    @Override
    public Integer getValue() {
        return this.value;
    }

    @Override
    public String toString() {
        return this.desc;
    }
}

配置

application.properties

# 枚举包扫描
mybatis-plus.type-enums-package=cn.itcast.mp.enums

修改实体

user

private SexEnum sex; //性别,枚举类型

测试

    @Test
    public void testInsert(){
        User user = new User();
        user.setUserName("diaochan");
        user.setPassword("123456");
        user.setAge(20);
        user.setName("貂蝉");
        user.setMail("diaochan@itcast.cn");
        user.setVersion(1);
        user.setSex(SexEnum.WOMAN); //设置性别为女性使用的是枚举

        // 调用AR的insert方法进行插入数据
        boolean insert = user.insert();
        System.out.println("result => " + insert);
    }

 此外,枚举在条件查询中也是有效的

 @Test
    public void testSelectBySex(){
        User user = new User();

        QueryWrapper<User> wrapper  = new QueryWrapper<>();
        wrapper.ge("sex", SexEnum.WOMAN); //查询性别为女的数据

        List<User> users = user.selectList(wrapper);
        for (User user1 : users) {
            System.out.println(user1);
        }
    }

代码生成器

AutoGenerator MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity Mapper Mapper 、XML、 Service Controller 等各个模块的代码,极大的提升了开发效率。

效果图

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>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
    </parent>

    <groupId>cn.itcast.mp</groupId>
    <artifactId>itcast-mp-generator</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--mybatis-plus的springboot支持-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

MysqlGenerator.java

package cn.itcast.mp.generator;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

/**
 * <p>
 * mysql 代码生成器演示例子
 * </p>
 */
public class MysqlGenerator {

    /**
     * <p>
     * 读取控制台内容
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + ":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }

    /**
     * RUN THIS
     */
    public static void main(String[] args) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("itcast");
        gc.setOpen(false);
        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&useSSL=false&characterEncoding=utf8");
        // dsc.setSchemaName("public");
        dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("1234");
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName(scanner("模块名"));
        pc.setParent("cn.itcast.mp.generator");
        mpg.setPackageInfo(pc);

        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };
        List<FileOutConfig> focList = new ArrayList<>();
        focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                return projectPath + "/itcast-mp-generator/src/main/resources/mapper/" + pc.getModuleName()
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);
        mpg.setTemplate(new TemplateConfig().setXml(null));

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
//        strategy.setSuperEntityClass("com.baomidou.mybatisplus.samples.generator.common.BaseEntity");
        strategy.setEntityLombokModel(true);
//        strategy.setSuperControllerClass("com.baomidou.mybatisplus.samples.generator.common.BaseController");
        strategy.setInclude(scanner("表名"));
        strategy.setSuperEntityColumns("id");
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        // 选择 freemarker 引擎需要指定如下加,注意 pom 依赖必须有!
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mybatis-plus扩展 的相关文章

随机推荐

  • Ubuntu 20.04系统 安装显卡驱动RTX3080

    网络上很多 xff0c 试过很多前人的经验 xff0c 多多少少都有些奇怪问题特别是对于我这样的新手 我记录下 xff0c 仅代表我个人安装成功的经验 说明 xff0c 我是台式机安装Ubuntu 怎么安装完系统就不谈了 xff0c 主要说
  • SerDes---CDR技术

    1 为什么需要CDR 时钟数据恢复主要完成两个工作 xff0c 一个是时钟恢复 xff0c 一个是数据重定时 xff0c 也就是数据的恢复 时钟恢复主要是从接收到的 NRZ xff08 非归零码 xff09 码中将嵌入在数据中的时钟信息提取
  • Failed to start bean ‘documentationPluginsBootstrapper‘

    最近写项目发现导入Swagger2依赖会报错Failed to start bean documentationPluginsBootstrapper 这个错误是由Springfox的一个bug引起 xff0c 解决这个问题的方式有多种 x
  • mac,centos 安装Connector/Python

    mac 官网下载 xff0c 双击 centos https dev mysql com doc connector python en connector python installation source html sudo yum
  • 5个可保存的在线代码片段平台推荐-变成自己的代码词典库

    文章目录 1 谷歌等现代浏览器自带的代码片段2 github gitee gitcode等在线托管平台的gist列表3 各大在线IDE平台4 掘金代码片段5 在线笔记 1 谷歌等现代浏览器自带的代码片段 路径 xff1a 浏览器开发者工具
  • 前置声明与C++头文件互相包含导致的error: 'xxx' does not name a type问题

    在一个源文件中 xff0c 要声明或定义一个类的指针时 xff0c 必须在使用前声明或定义该类 xff0c 因此下面的代码会报错 xff1a span class hljs class span class hljs keyword cla
  • C语言中1<<n是什么意思

    1 lt lt 2 1的二进制为 0000 0001 左移2位 0000 0100 如果再转成10进制就是4
  • 位运算——左移和右移

    lt lt 左移 1 运算规则 xff1a 按二进制形式把所有的数字向左移动对应的位数 xff0c 高位移出 舍弃 xff0c 低位的 空位补零 2 语法格式 xff1a 需要移位的数字 lt lt 移位的次数 例如 xff1a 3 lt
  • 【Python】爬取TapTap原神评论并生成词云分析

    序言 本来是想爬B站的 xff0c 但是B站游戏区的评论好像是动态方式加载 xff0c 分析了一通没搞懂怎么爬 xff0c 所以转到了TapTap xff0c TapTap评论页通过URL来定位 xff0c 非常容易拼接URL去获取想要的页
  • ubuntu下http代理设置

    方法一 这是一种临时的手段 xff0c 如果您仅仅是暂时需要通过http 代理使用apt get xff0c 您可以使用这种方式 在使用apt get 之前 xff0c 在终端中输入以下命令 xff08 根据您的实际情况替换yourprox
  • ARM汇编(基于树莓派3B)3

    第七章 Linux操作系统服务 在第1章 入门 中 xff0c 我们需要能够退出程序并显示字符串 我们使用Raspbian Linux来执行此操作 xff0c 直接调用操作系统服务 在所有高级编程语言中 xff0c 都有一个运行时库 xff
  • VS修改平台工具集

    MSB8020 无法找到 Visual Studio 2010 的生成工具 平台工具集 61 v100 若要使用 v100 生成工具进行生成 xff0c 请安装 Visual Studio 2010 生成工具 或者 xff0c 可以升级到当
  • Web安全领域的探索之远程文件包含漏洞(LFI)

    文件包含渗透 File Inclusion 文件包含漏洞 xff1a 即File Inclusion xff0c 意思是文件包含 xff08 漏洞 xff09 xff0c 是指当服务器开启allow url include选项时 xff0c
  • EFI与MBR启动的区别

    EFI与MBR启动的区别 大硬盘和WIN8系统 xff0c 让我们从传统的BIOS 43 MBR模式升级到UEFI 43 GPT模式 xff0c 现在购买的主流电脑 xff0c 都是预装WIN8系统 xff0c 为了更好的支持2TB硬盘 x
  • mac install MySQL-python

    mac python mysqldb EnvironmentError mysql config not found save brew install mysql 先安装mysql 最后 pip install MySQL Python
  • 每天一个linux命令2---curl命令

    常用参数详解 参数描述 I head只显示传输文档 xff0c 经常用于测试连接本身 o output把输出写到该文件中 xff0c 必须输入保存文件名 O remote name把输出写到该文件中 xff0c 保留远程文件的文件名 F f
  • Linux CentOS7配置iptables端口映射将客户端与另一台主机内的虚拟机服务连接

    这是一篇配置用户主机端口访问Linux服务器内KVM虚拟机的记录文章 各位看官朋友有没有遇到过这种访问情况 自己有一台笔记本电脑A xff0c 还有一台主机B 自己把主机B刷成了linux服务器系统 xff0c 并且在服务器内安装创建了一台
  • Linux内核netfilter子系统ulogd项目性能调优记录

    使用ULOGD打SYSLOG到SYSLOG NG xff0c 当NFLOG拿到的数据包在6K左右时 xff0c CPU有两个核心占了15 左右使用修改过的ULOGD直接打TCP xff0c CPU只有一个核心占15 左右 xff08 修改版
  • LINUX如何设置numlock键开机状态

    第一步 xff1a 安装numlockx xff0c 输入命令 xff1a sudo yum install numlockx 第二步 xff1a 用 vim 打开 etc lightdm lightdm conf文件 xff0c 如果文件
  • Mybatis-plus扩展

    这玩意类似于mp自带的basemapper Copyright c 2011 2020 baomidou jobob 64 qq com lt p gt Licensed under the Apache License Version 2