Mybatis-Plus学习day02

Mybatis-Plus学习day02

1 、ActiveRecord

1.1 开启ActiveRecord之旅

ActiveRecord(简称AR)一直广受动态语言( PHP 、 Ruby 等)的喜爱,而 Java 作为准静态语言,对于
ActiveRecord 往往只能感叹其优雅,所以我们也在 AR 道路上进行了一定的探索,喜欢大家能够喜欢。

什么是ActiveRecord?
ActiveRecord也属于ORM(对象关系映射)层,由Rails最早提出,遵循标准的ORM模型:表映射到记录,记
录映射到对象,字段映射到对象属性。配合遵循的命名和配置惯例,能够很大程度的快速实现模型的操作,而
且简洁易懂。
ActiveRecord的主要思想是:
每一个数据库表对应创建一个类,类的每一个对象实例对应于数据库中表的一行记录;通常表的每个字段
在类中都有相应的Field;
ActiveRecord 同时负责把自己持久化,在ActiveRecord中封装了对数据库的访问,即CURD;;
ActiveRecord 是一种领域模型(Domain Model),封装了部分业务逻辑;

在这里插入图片描述

实体类继承Model类

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_user")
public class User extends Model<User> {
    
    
    @TableId(type = IdType.AUTO)
    private Long id;
    private String userName;
    private String password;
    private String name;
    private Integer age;
    private String email;

}

1.2根据逐渐查询

//根据主键查询
    @Test
    public void testAR_selectById(){
    
    
        User user = new User();
        user.setId(3L);
        User user1 = user.selectById();
        // user.selectById(13L);也可直接传入id
        System.out.println(user1);
    }

1.3新增数据

 @Test
    public void testAR_Insert(){
    
    
        User user = new User();
        user.setName("貂蝉");
        user.setAge(21);
        user.setPassword("123465");
        user.setUserName("diaochan");
        user.setEmail("[email protected]");
        boolean res = user.insert();
        System.out.println("result==>"+res);
    }

1.4更新数据

@Test
    public void testAR_updateById(){
    
    
        User user = new User();
        user.setId(20L);
        user.setAge(19);
        boolean result = user.updateById();
        System.out.println("result==>"+result);
    }

1.5删除记录

@Test
    public void testAR_delete(){
    
    
        User user = new User();
        user.setId(20L);
        boolean result = user.deleteById();
        System.out.println("result==>"+result);

    }

1.6根据条件进行查询

 //自定义查询条件.
    @Test
    public void testAR_Select(){
    
    
        User user = new User();
        QueryWrapper <User> wrapper = new QueryWrapper <>();
        wrapper.ge("age",18);
        List <User> users = user.selectList(wrapper);
        for (User user1 : users) {
    
    
            System.out.println(user1);
        }
    }

2.插件

2.1Mybatis-Plus插件机制

MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法
调用包括:

  1. Executor (update, query, flushStatements, 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等方法,还有其他接口的一些方法等。

总体概括为:

扫描二维码关注公众号,回复: 13198276 查看本文章
  • 拦截执行器的方法
  • 拦截参数的处理器
  • 拦截结果集的处理器
  • 拦截Sql语法构建的处理器

2.2执行分析插件

在MP中提供了对SQL执行的分析的插件,可用作阻断全表更新、删除的操作,注意:该插件仅适用于开发环境,不适用于生产环境。
SpringBoot配置:

@Bean
    public SqlExplainInterceptor mybatisPlusInterceptor(){
    
    
        SqlExplainInterceptor sqlExplainInterceptor = new SqlExplainInterceptor();
        List <ISqlParser> sqlParserList = new ArrayList <>();
        sqlParserList.add(new BlockAttackSqlParser());
        sqlExplainInterceptor.setSqlParserList(sqlParserList);
        return sqlExplainInterceptor;
    }

测试:

@Test
    public void testUpdate3()
    {
    
    
        User user = new User();
        user.setAge(20);
        boolean result = user.update(null);
        System.out.println(result);
    }

运行结果:

在这里插入图片描述

2.3乐观锁

OptimisticLockerInnerInterceptor

当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:

  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败

2.3.1.配置插件

1.第一步插件的配置:

spring xml方式:

<bean class="com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor" id="optimisticLockerInnerInterceptor"/>

<bean id="mybatisPlusInterceptor" class="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor">
    <property name="interceptors">
        <list>
            <ref bean="optimisticLockerInnerInterceptor"/>
        </list>
    </property>
</bean>

spring boot注解方式:

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    
    
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
    return interceptor;
}
2.在实体类的字段上加上@Version注解(当然数据库中也要有这个字段哦)
@Version
private Integer version;

说明:

  • 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
  • 整数类型下 newVersion = oldVersion + 1
  • newVersion 会回写到 entity
  • 仅支持 updateById(id)update(entity, wrapper) 方法
  • update(entity, wrapper) 方法下, wrapper 不能复用!!! 即wrapper不能和其他逻辑,如查询,删除等复用…

测试代码

//测试乐观锁
    @Test
    public void testUpdateVersion(){
    
    
        User user = new User();
        user.setId(2L);
        User userVersion = user.selectById();
        user.setAge(23);
        user.setVersion(userVersion.getVersion());
        boolean res = user.updateById();
        System.out.println("result==>"+res);

    }

3.自动填充功能

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

3.1、添加@TableField注解

@TableField (fill = FieldFill.INSERT) //插入数据时进行填充
private String password;

为password添加自动填充功能,在新增数据时有效。
FieldFill提供了多种模式选择:

public enum FieldFill {
    
    
  /**
  * 默认不处理
  */
  DEFAULT,
  /**
  * 插入时填充字段
  */
  INSERT,
  /**
  * 更新时填充字段
  */
  UPDATE,
  /**
  * 插入和更新时填充字段
  */
  INSERT_UPDATE
}

3.2、编写MyMetaObjectHandler

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    
    
    @Override
    public void insertFill(MetaObject metaObject) {
    
    //编写自动填充条件.
        Object password = getFieldValByName("password", metaObject);
        if(password==null){
    
    //如果字段为空,则进行自动填充
            setFieldValByName("password", "123456", metaObject);
        }
        
    }

    @Override
    public void updateFill(MetaObject metaObject) {
    
    

    }
}

4.逻辑删除

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

4.1、修改表结构

为tb_user表增加deleted字段,用于表示数据是否被删除,1代表删除,0代表未删除。

同时,也修改User实体,增加deleted属性并且添加@TableLogic注解:

@TableLogic
private Integer deleted;

4.2、配置

mybatis-plus:
  mapper-locations: classpath*:mapper/*.xml
  type-aliases-package: com.rg.boot.bean
  global-config:
    db-config:
      logic-delete-value: 1 #删除状态的值 1
      logic-not-delete-value: 0 #未删除状态的值 0

4.3测试

@Test
    public void testDelete(){
    
    
        // UPDATE tb_user SET deleted=1 WHERE id=? AND deleted=0
        int result = userMapper.deleteById(2L);
        System.out.println("result==>"+result);
    }


 @Test
    public void SELECT id,user_name,password,name,age,email,version,deleted FROM tb_user WHERE id=? AND deleted=0(){
    
    
        //SELECT id,user_name,password,name,age,email,version,deleted FROM tb_user WHERE id=? AND deleted=0
        User user = userMapper.selectById(2L);
        System.out.println(user);
    }

5.通用枚举

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

5.1、修改表结构

为表增加sex列,默认值为1

在这里插入图片描述

5.2、定义枚举

public enum  SexEnum implements IEnum<Integer> {
    
    

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

    private int value;
    private String desc;
    @Override
    public Integer getValue() {
    
    
        return this.value;
    }
    SexEnum(int value,String desc){
    
    
        this.value=value;
        this.desc=desc;
    }

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

5.3、配置

mybatis-plus:
  type-enums-package: com.rg.boot.enums #枚举包扫描

5.4、修改实体

private SexEnum sex;

5.5、测试


@Test
    public void testAR_Insert(){
    
    
        User user = new User();
        user.setName("小乔");
        user.setAge(21);
        user.setPassword("123465");
        user.setUserName("xiaoqiao");
        user.setEmail("[email protected]");
        user.setVersion(1);
        user.setSex(SexEnum.WOMAN);
        // INSERT INTO tb_user ( user_name, password, name, age, email, version, sex ) VALUES ( ?, ?, ?, ?, ?, ?, ? )
        boolean res = user.insert();
        //结果数据库该条数据,sex属性值为2
        System.out.println("result==>"+res);
    }

######################################测试查询###########################################

@Test
    public void testAR_selectById(){
    
    
        User user = new User();
        user.setId(3L);
        User user1 = user.selectById();
        //User(id=3, userName=wangwu, password=123456, name=王五, age=28, [email protected], version=1, deleted=0, sex=男)
        System.out.println(user1);
    }

6.代码生成器

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

测试代码:

public class generator {
    
    
    /**
     * <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.isNotBlank(ipt)) {
    
    
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }

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

        // 2.全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("rg1910");
        gc.setOpen(false);
        // 实体属性 Swagger2 注解
        //gc.setSwagger2(true);
        mpg.setGlobalConfig(gc);

        // 3.数据源配置
        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("186259");
        mpg.setDataSource(dsc);

        // 4.包配置
        PackageConfig pc = new PackageConfig();

                pc.setController("controller")
                .setEntity("bean")
                .setMapper("mapper")
                .setService("service")
                .setModuleName("")
                .setServiceImpl("service.impl")
                .setXml("mapper.xml");

        pc.setModuleName(scanner("模块名"));
        pc.setParent("com.rg.boot.generator"); //生成代码的位置
        mpg.setPackageInfo(pc);

        // 5.自定义配置
        InjectionConfig cfg = new InjectionConfig() {
    
    
            @Override
            public void initMap() {
    
    
                // to do nothing
            }
        };
        List <FileOutConfig> focList = new ArrayList <>();
        focList.add(new FileOutConfig() {
    
    
            @Override
            public String outputFile(TableInfo tableInfo) {
    
    
                //自定义文件名称(自定义模块的resources的位置.)
                return projectPath + "/mybatis-plus-springboot-simple/src/main/resources/mapper/" + pc.getModuleName()
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);
        mpg.setTemplate(new TemplateConfig().setXml(null));

        // 6.策略配置
        StrategyConfig strategy = new StrategyConfig();
        // 数据库表映射到实体的命名策略
        strategy.setNaming(NamingStrategy.underline_to_camel);
        // 数据库表字段映射到实体的命名策略
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        // 开启lombok 模型
        strategy.setEntityLombokModel(true);
        // restful api风格控制器
        strategy.setRestControllerStyle(true);
//        strategy.setSuperControllerClass("com.baomidou.mybatisplus.samples.generator.common.BaseController");
        strategy.setInclude(scanner("表名"));
        strategy.setSuperEntityColumns("id");
        // url中驼峰转连字符
        strategy.setControllerMappingHyphenStyle(true);
         生成实体时去掉表前缀
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        // 添加模板引擎
        //mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }
}

执行结果:

在这里插入图片描述

在这里插入图片描述

7.MybatisX 快速开发插件

MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。
安装方法:打开 IDEA,进入 File -> Settings -> Plugins -> Browse Repositories,输入 mybatisx 搜索并安装。
功能:

猜你喜欢

转载自blog.csdn.net/LXYDSF/article/details/120684432