Mybatis-plus

简介

Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

特性

  • 无侵入:Mybatis-Plus 在 Mybatis 的基础上进行扩展,只做增强不做改变,引入 Mybatis-Plus 不会对您现有的 Mybatis 构架产生任何影响,而且 MP 支持所有 Mybatis 原生的特性
  • 依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 预防Sql注入:内置 Sql 注入剥离器,有效预防Sql注入攻击
  • 通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题
  • 支持热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动
  • 支持ActiveRecord:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作
  • 支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用(P.S. 比 Mybatis 官方的 Generator 更加强大!)
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 支持关键词自动转义:支持数据库关键词(order、key......)自动转义,还可自定义关键词
  • 内置分页插件:基于 Mybatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作

架构原理

 下面就是springboot与MyBatis-Plus集成,spring和MyBatis-Plus(这个参考官网:http://mp.baomidou.com/)。

  • pom.xml引入
    <dependencies>
      <dependency>
          <groupId>com.baomidou</groupId>
          <artifactId>mybatis-plus-boot-starter</artifactId>
          <version>最新版本号</version>
      </dependency>
    </dependencies>
    <!-- 如果mapper.xml是放在src/main/java目录下,需配置以下-->
    <build>
      <resources>
          <resource>
              <directory>src/main/java</directory>
              <filtering>false</filtering>
              <includes>
                  <include>**/mapper/*.xml</include>
              </includes>
          </resource>
      </resources>
    </build>
  • application.yml配置文件

    
    mybatis-plus:
      # 如果是放在src/main/java目录下 classpath:/com/yourpackage/*/mapper/*Mapper.xml
      # 如果是放在resource目录 classpath:/mapper/*Mapper.xml
      mapper-locations: classpath:/mapper/*Mapper.xml
      #实体扫描,多个package用逗号或者分号分隔
      typeAliasesPackage: com.yourpackage.*.entity
      global-config:
        #主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
        id-type: 3
        #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
        field-strategy: 2
        #驼峰下划线转换
        db-column-underline: true
        #mp2.3+ 全局表前缀 mp_
        #table-prefix: mp_
        #刷新mapper 调试神器
        #refresh-mapper: true
        #数据库大写下划线转换
        #capital-mode: true
        # Sequence序列接口实现类配置
        key-generator: com.baomidou.mybatisplus.incrementer.OracleKeyGenerator
        #逻辑删除配置(下面3个配置)
        logic-delete-value: 1
        logic-not-delete-value: 0
        sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
        #自定义填充策略接口实现
        meta-object-handler: com.baomidou.springboot.MyMetaObjectHandler
      configuration:
        #配置返回数据库(column下划线命名&&返回java实体是驼峰命名),自动匹配无需as(没开启这个,SQL需要写as: select user_id as userId) 
        map-underscore-to-camel-case: true
        cache-enabled: false
        #配置JdbcTypeForNull, oracle数据库必须配置
        jdbc-type-for-null: 'null'

 

  • Java Configuration配置更多配置参考

    @Configuration
    @MapperScan("com.yourpackage.*.mapper*")
    public class MybatisPlusConfig {
       /*
        * 分页插件,自动识别数据库类型
        * 多租户,请参考官网【插件扩展】
        */
       @Bean
       public PaginationInterceptor paginationInterceptor() {
          return new PaginationInterceptor();
       }
    
       /*
        * oracle数据库配置JdbcTypeForNull
        * 参考:https://gitee.com/baomidou/mybatisplus-boot-starter/issues/IHS8X
        不需要这样配置了,参考 yml:
        mybatis-plus:
          confuguration
            dbc-type-for-null: 'null' 
       @Bean
       public ConfigurationCustomizer configurationCustomizer(){
           return new MybatisPlusCustomizers();
       }
    
       class MybatisPlusCustomizers implements ConfigurationCustomizer {
    
           @Override
           public void customize(org.apache.ibatis.session.Configuration configuration) {
               configuration.setJdbcTypeForNull(JdbcType.NULL);
           }
       }
       */
    }

配置:

@EnableTransactionManagement
@Configuration
public class ConfigurationPlugin {
	/**
	 * 分页插件
	 * @return
	 */
	@Bean
	public PaginationInterceptor create(){
		return new PaginationInterceptor();
	}
	
	/**
	 * 拦截删除全表的操作--setStopProceed这个要设置成true,
		SQL 执行分析拦截器【 目前只支持 MYSQL-5.6.3 以上版本 】,
		作用是分析 处理 DELETE UPDATE 语句, 防止小白或者恶意 delete update 全表操作!
	 * @return
	 */
	@Bean
	public SqlExplainInterceptor createSqlExplainInterceptor(){
		SqlExplainInterceptor interceptor = new SqlExplainInterceptor();
		interceptor.setStopProceed(true);
		return interceptor;
	}
	/**
	 * 性能分析插件
	 * @return
	 */
	//@Profile({"dev","test","pr"})
	@Bean
	public PerformanceInterceptor createPerformanceInterceptor(){
		PerformanceInterceptor interceptor = new PerformanceInterceptor();
		interceptor.setMaxTime(100);
		interceptor.setFormat(true);
		return interceptor;
	}
	/**
	 * 乐观锁插件,这个也要在数据库添加一个字段来当version版本记录,
        也需要在属性里上面添加一个注解@version
	 * @return
	 */
	@Bean
	public OptimisticLockerInterceptor  createOptimisticLockerInterceptor(){
		return new OptimisticLockerInterceptor ();
	}

	/**
	 * 这个是自己添加方法
	 * @return
	 */
	@Bean
	public MySqlInjector createMySqlInjector(){
		return new MySqlInjector();
	}
	/**
	 * 公共字段自动填充
	 * @return
	 */
	@Bean
	public MyMetaObjectHandler createMyMetaObjectHandler(){
		return new MyMetaObjectHandler();
	}
	


}
/**
*下面是我自定义的--公共字段自动填充的方案
*/
public class MyMetaObjectHandler extends MetaObjectHandler{

	@Override
	public void insertFill(MetaObject metaObject) {
		System.out.println("在插入是如果name的值为空时,可以插入值");
		Object name = getFieldValByName("lastName", metaObject);
		System.out.println(name);
		if(name==null){
			setFieldValByName("lastName", "wangbin", metaObject);
		}
	}

	@Override
	public void updateFill(MetaObject metaObject) {
		
		
	}

}

/**
  *下面试自己的方法--写的自动注入sql的方式
  */
public interface DeptMapper extends BaseMapper<Dept>{
	
	int deleteAll();

}
public class MySqlInjector extends AutoSqlInjector {

	@Override
	public void inject(Configuration configuration, MapperBuilderAssistant builderAssistant, Class<?> mapperClass,
			Class<?> modelClass, TableInfo table) {
		//注入的SQL语句
		String sql = "delete from " +table.getTableName();
		//注入的方法名   一定要与EmployeeMapper接口中的方法名一致
		String method = "deleteAll" ;
		
		//构造SqlSource对象
		SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
		
		//构造一个删除的MappedStatement
		this.addDeleteMappedStatement(mapperClass, method, sqlSource);
	}
		
}

核心功能:

1、代码生成器可以参考官网http://mp.baomidou.com/#/generate-code

下面是我写的代码示例:

	/**
	 * 代码生成    示例代码
	 */
	@Test
	public void  testGenerator() {
		//1. 全局配置
		GlobalConfig config = new GlobalConfig();
		config.setActiveRecord(true) // 是否支持AR模式
			  .setAuthor("wang") // 作者
			  .setOutputDir("E:\\bauduyunpan\\shang\\尚硅谷MyBatisPlus视频教程\\MyBatisPlus\\代码\\mp03\\src\\main\\java") // 生成路径
			  .setFileOverride(true)  // 文件覆盖
			  .setIdType(IdType.AUTO) // 主键策略
			  .setServiceName("%sService")  // 设置生成的service接口的名字的首字母是否为I
			  					   // IEmployeeService
 			  .setBaseResultMap(true)
 			  .setBaseColumnList(true);
		
		//2. 数据源配置
		DataSourceConfig  dsConfig  = new DataSourceConfig();
		dsConfig.setDbType(DbType.MYSQL)  // 设置数据库类型
				.setDriverName("com.mysql.jdbc.Driver")
				.setUrl("jdbc:mysql://localhost:3306/mp")
				.setUsername("root")
				.setPassword("root");
		 
		//3. 策略配置
		StrategyConfig stConfig = new StrategyConfig();
		stConfig.setCapitalMode(true) //全局大写命名
				.setDbColumnUnderline(true)  // 指定表名 字段名是否使用下划线
				.setNaming(NamingStrategy.underline_to_camel) // 数据库表映射到实体的命名策略
				.setTablePrefix("tbl_")
				.setInclude("tbl_employee");  // 生成的表
		
		//4. 包名策略配置 
		PackageConfig pkConfig = new PackageConfig();
		pkConfig.setParent("com.jrj.mp")
				.setMapper("mapper")
				.setService("service")
				.setController("controller")
				.setEntity("beans")
				.setXml("mapper");
		
		//5. 整合配置
		AutoGenerator  ag = new AutoGenerator();
		
		ag.setGlobalConfig(config)
		  .setDataSource(dsConfig)
		  .setStrategy(stConfig)
		  .setPackageInfo(pkConfig);
		
		//6. 执行
		ag.execute();
	}

2、通用的CURD

简单介绍

TODO

实体无注解化设置,表字段如下规则,主键叫 id 可无注解大写小如下规则。

1、驼峰命名 【 无需处理 】

2、全局配置: 下划线命名 dbColumnUnderline 设置 true , 大写 isCapitalMode 设置 true

注解说明

表名注解 @TableName

  • com.baomidou.mybatisplus.annotations.TableName
描述
value表名( 默认空 )
resultMapxml 字段映射 resultMap ID

主键注解 @TableId

  • com.baomidou.mybatisplus.annotations.TableId
描述
value字段值(驼峰命名方式,该值可无)
type主键 ID 策略类型( 默认 INPUT ,全局开启的是 ID_WORKER )

暂不支持组合主键

字段注解 @TableField

  • com.baomidou.mybatisplus.annotations.TableField
描述
value字段值(驼峰命名方式,该值可无)
update预处理 set 字段自定义注入
condition预处理 WHERE 实体条件自定义运算规则
el详看注释说明
exist是否为数据库表字段( 默认 true 存在,false 不存在 )
strategy字段验证 ( 默认 非 null 判断,查看 com.baomidou.mybatisplus.enums.FieldStrategy )
fill字段填充标记 ( FieldFill, 配合自动填充使用 )
  • TableField 注解新增属性 update 预处理 set 字段自定义注入
    例如:@TableField(.. , update="%s+1") 其中 %s 会填充为字段
    输出 SQL 为:update 表 set 字段=字段+1 where ...
    例如:@TableField(.. , update="now()") 使用数据库时间
    输出 SQL 为:update 表 set 字段=now() where ...
  • TableField 注解新增属性 condition 预处理 WHERE 实体条件自定义运算规则

    @TableField(condition = SqlCondition.LIKE)
    private String name;
    输出 SQL 为:select 表 where name LIKE CONCAT('%',值,'%')
  • 字段填充策略 FieldFill

描述
DEFAULT默认不处理
INSERT插入填充字段
UPDATE更新填充字段
INSERT_UPDATE插入和更新填充字段

序列主键策略 注解 @KeySequence

  • com.baomidou.mybatisplus.annotations.KeySequence
描述
value序列名
clazzid的类型

乐观锁标记注解 @Version

  • com.baomidou.mybatisplus.annotations.Version
  •  

排除非表字段、查看文档常见问题部分!

3、条件构造器

实体包装器,用于处理 sql 拼接,排序,实体参数查询等!

补充说明: 使用的是数据库字段,不是Java属性!

实体包装器 EntityWrapper 继承 Wrapper

简单示例

  • 翻页查询
public Page<T> selectPage(Page<T> page, EntityWrapper<T> entityWrapper) {
  if (null != entityWrapper) {
      entityWrapper.orderBy(page.getOrderByField(), page.isAsc());
  }
  page.setRecords(baseMapper.selectPage(page, entityWrapper));
  return page;
}
  • 拼接 sql 方式 一
@Test
public void testTSQL11() {
    /*
     * 实体带查询使用方法  输出看结果
     */
    EntityWrapper<User> ew = new EntityWrapper<User>();
    ew.setEntity(new User(1));
    ew.where("user_name={0}", "'zhangsan'").and("id=1")
            .orNew("user_status={0}", "0").or("status=1")
            .notLike("user_nickname", "notvalue")
            .andNew("new=xx").like("hhh", "ddd")
            .andNew("pwd=11").isNotNull("n1,n2").isNull("n3")
            .groupBy("x1").groupBy("x2,x3")
            .having("x1=11").having("x3=433")
            .orderBy("dd").orderBy("d1,d2");
    System.out.println(ew.getSqlSegment());
}
  • 拼接 sql 方式 二
int buyCount = selectCount(Condition.create()
                .setSqlSelect("sum(quantity)")
                .isNull("order_id")
                .eq("user_id", 1)
                .eq("type", 1)
                .in("status", new Integer[]{0, 1})
                .eq("product_id", 1)
                .between("created_time", startDate, currentDate)
                .eq("weal", 1));
  • 自定义 SQL 方法如何使用 Wrapper

mapper java 接口方法

List<User> selectMyPage(RowBounds rowBounds, @Param("ew") Wrapper<T> wrapper);

mapper xml 定义

<select id="selectMyPage" resultType="User">
  SELECT * FROM user 
  <where>
  ${ew.sqlSegment}
  </where>
</select>

关于 ${ew.sqlSegment} 使用了 $ 不要误以为就会被 sql 注入,请放心使用 mp 内部对 wrapper 进行了字符转义处理!

条件参数说明

查询方式说明
setSqlSelect设置 SELECT 查询字段
whereWHERE 语句,拼接 + WHERE 条件
andAND 语句,拼接 + AND 字段=值
andNewAND 语句,拼接 + AND (字段=值)
orOR 语句,拼接 + OR 字段=值
orNewOR 语句,拼接 + OR (字段=值)
eq等于=
allEq基于 map 内容等于=
ne不等于<>
gt大于>
ge大于等于>=
lt小于<
le小于等于<=
like模糊查询 LIKE
notLike模糊查询 NOT LIKE
inIN 查询
notInNOT IN 查询
isNullNULL 值查询
isNotNullIS NOT NULL
groupBy分组 GROUP BY
havingHAVING 关键词
orderBy排序 ORDER BY
orderAscASC 排序 ORDER BY
orderDescDESC 排序 ORDER BY
existsEXISTS 条件语句
notExistsNOT EXISTS 条件语句
betweenBETWEEN 条件语句
notBetweenNOT BETWEEN 条件语句
addFilter自由拼接 SQL
last拼接在最后,例如:last("LIMIT 1")

注意! xxNew 都是另起 ( ... ) 括号包裹。

 

下面是我写的一些代码:

https://github.com/zhangyuxiangwang/springboot2.git

4、插件扩展参考官网:

http://mp.baomidou.com/#/page-plugin

 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值