MyBatisPlus

MyBatisPlus: MyBatis-Plus 🚀 为简化开发而生 | MyBatis-Plus

Fluent MyBatis: fluent-mybatis: fluent-mybatis, mybatis语法增强框架, 综合了mybatis plus, danymic sql, jpa等框架特性和优点, 利用annotation processor生成代码

Flex MyBatis: MyBatis-Flex: MyBatis-Flex 一个优雅的 MyBatis 增强框架

Bean-searcher: bean-searcher: 🔥🔥🔥 专注高级查询的只读 ORM,天生支持联表,免 DTO/VO 转换,使一行代码实现复杂列表检索成为可能!

JOOQ:jOOQ: The easiest way to write SQL in Java 全称是Java Object Oriented Querying面向java对象查询

Ebean:Ebean ORM for Java & Kotlin

一、maven依赖:
<dependencys>
    <!-- 传递依赖mybatis-spring -->
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus</artifactId>
      <version>3.x.x</version>
    </dependency> 
​
    <!-- 传递依赖mybatis-plus,不要再导其他mybatis包 -->
    <!-- 报LogFactory包找不到,是mybatis版本需要3.5以上 -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.5</version>
    </dependency>
    
    <!-- springboot3.x必须引入新版本mybatis-plus -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
        <version>[3.5.4,3.5.5]</version>
    </dependency>
</dependencys>
二、yml配置:
mybatis-plus:
  #mapper-locations: classpath:/mapper/**
  type-aliases-package: com.cssl.pojo
  configuration:
    auto-mapping-behavior: full
    use-generated-keys: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: false   #默认true开启驼峰命名
  global-config:
    db-config:
      id-type: auto           #主键自增
      table-underline: false  #默认true表名前加_
      table-prefix: tbl_      #表名前缀
三、注解
//表名注解,不写那么类名就是表名
@TableName(value="表名")
//主键注解,如果主键名就是id才可以省略,否则根据主键修改删除查询报错
@TableId(value="列名",type = IdType.AUTO)
//字段注解(非主键),如果数据库没有配置exist=false
@TableField(exist = false)
//表字段逻辑处理注解(逻辑删除),也可以配置在yml
@TableLogic(value="逻辑未删除值",delval="逻辑删除值")
//序列主键策略 oracle
@KeySequence(value="序列名")
//排序,默认降序
@OrderBy(sort = 1)
@TableName("news_comment") //可以不写,默认true就是驼峰
@Data
public class NewsComment {
​
    @TableId(type = IdType.AUTO)
    private Integer cid;
    private Integer newsId;
    @TableField(exist = false)
    private NewsDetail newsDetail;
    private String content;
    private String cauthor;
    private Date ccreatedate;
    @TableLogic
    private int is_delete;
}

四、api接口

(自带方法不支持二级缓存,自己写的sql支持)

dao层:

//BaseMapper<T>:
public interface UsersMapper extends BaseMapper<Users>

service层:(事务自己加在业务层也不起作用,必须手动调用方法,除非事务加在控制层)

注意:3.0.5版之后业务层除了批量增删改外其他没有事务,因为单个增删改可以不用事务,业务涉及多张表增删改本就需要自己写方法加事务!

//IService<T>:
public interface UsersService extends IService<Users>
    
//ServiceImpl<Mapper,T>:
public class UsersServiceImpl extends ServiceImpl<UsersMapper,Users> 
    implements UsersService{
    //UsersMapper可以不用注入,直接使用 baseMapper
}

MP3.x常用方法: save:保存 saveBatch:批量保存 updateById:根据主键更新 updateBatchById:根据主键批量更新 removeById:根据主键删除 removeByIds:根据多个id删除

getById:根据主键查询 getOne:根据条件返回一个结果 list:查询所有,参数new QueryWrapper<T>() listByIds:根据多个id查询 listMaps:参数new QueryWrapper<T>(),返回List<Map>

page:分页查询,参数new Page<T>(1,10),new QueryWrapper<T>() pageMaps:参数new QueryWrapper<T>(),返回List<Map>

MP3.x升级日志: 升级 JDK 8 + 优化性能 Wrapper 支持 lambda 语法 模块化 MP 合理的分配各个包结构 重构注入方法,支持任意方法精简注入模式 全局配置下划线转换消灭注入 AS 语句 改造 Wrapper 更改为 QueryWrapper UpdateWrapper 重构 分页插件 消灭固定分页模型,支持 Mapper 直接返回 IPage 接口 新增 Rest Api 通用 Controller 层 实体 String 类型字段默认使用 LIKE 查询 SelectOne 默认 LIMIT 1 辅助支持 selectMaps 新增 bean map 互转工具类

Wrapper使用:

QueryWrapper<T>与UpdateWrapper<T>共有方法 方法名 说明 allEq 基于 map 内容等于= eq 等于 = ne 不等于 <> gt 大于 > ge 大于等于 >= lt 小于 < le 小于等于 <= between BETWEEN 条件语句 notBetween NOT BETWEEN 条件语句 like LIKE '%值%'' notLike NOT LIKE '%值%' likeLeft LIKE '%值' likeRight LIKE '值%'


isNull NULL 值查询 isNotNull NOT NULL 值查询 in IN 查询 notIn NOT IN 查询 inSql IN 查询(sql注入式) notInSql NOT IN 查询(sql注入式) groupBy 分组 GROUP BY orderByAsc ASC 排序 ORDER BY orderByDesc DESC 排序 ORDER BY orderBy 排序 ORDER BY having HAVING 关键词(sql注入式)


or or 拼接 apply 拼接自定义内容(sql注入式) last 拼接在最后(sql注入式) exists EXISTS 条件语句(sql注入式) notExists NOT EXISTS 条件语句(sql注入式)


and(Function) AND (嵌套内容,条件默认and) or(Function) OR (嵌套内容)

//or拼接 id=1 or username like ...
new QueryWrapper<User>()
    .ge("id",map.get("id"))
    .or()
    .likeLeft("username",map.get("username"))
//or嵌套 id=1 or id<9 and username like ...
new QueryWrapper<User>()
    .ge("id",map.get("id"))
    .or((qw) -> {
        qw.lt("id",9)
    }).likeLeft("username",map.get("username"))
   
//自定义修改    
//return service.update(new UpdateWrapper<Emp>().set("ename","aaa").eq("empno",5));
 // 根据 whereWrapper 条件,更新记录
return service.update(emp,new QueryWrapper<Emp>().eq("sal",5000));

nested(Function) (嵌套内容)

QueryWrapper<T>特有方法: 方法名 说明 select SQL查询字段内容,例如:id,name,age(重复设置以最后一次为准)

UpdateWrapper<T>特有方法: 方法名 说明 set SQL SET 字段(一个字段使用一次)

//使用lambda表达式
//建议使用 Wrappers.lambdaQuery
//屏蔽底层的具体实现,未来会有变化上层代码无需过多的调整
LambdaQueryWrapper<T> wp = Wrappers.lambdaQuery();
wp.eq(Classes::getCname,"");
wp.eq(boolean,Classes::getCname,""); //true添加条件否则不添加
分页查询:(Java配置)
@Configuration
public class MybatisPlus {
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor page = new PaginationInterceptor();       
		// 合理化
		// page.setOverflow(true);	
        page.setCountSqlParser(new JsqlParserCountOptimize(true));
        return page;
    }
}

新版本3.4+:(插件主体)

@Configuration
public class MybatisPlusConfig  {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

    /**
  	  * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置
  	  * MybatisConfiguration#useDeprecatedExecutor = false
  	  * 避免缓存出现问题(该属性会在3.5.x后移除,不需要该方法了)
  	*/
    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return configuration -> configuration.setUseDeprecatedExecutor(false);
    }

}

IPage<T> selectPage(IPage<T> page, Wrapper<T> queryWrapper);   以上面的方法为例,入参一个IPage<T>接口的子类(可以使用mp自带的一个叫Page<T>的子类), 返回一个IPage<T>,其实这个返回的分页类==入参的分页类, 如果你需要自定义一个分页方法只需要注意一点:入参第一位放置你使用的IPage<T>子类 如:

IPage<NewsDetail> page = service.page(
	new Page<NewsDetail>(1,3,false),		//分页,false表示不查count()
	new QueryWrapper<NewsDetail>()
    .like("title","山东").orderByDesc("id")	//条件+排序
);
自定义方法分页:

(如果配置了ResultMap返回对象关联查询单个对象报错使用@TableField(exist = false),建议直接使用Map<String,Object>)

//dao接口:
public IPage<Map<String,Object>> selectAll(IPage page);

//service:
public IPage<Map<String,Object>> findAll(int index,int size){
        Page<Map<String,Object>> page = new Page<>(index,size);
        return ncMapper.selectAll(page);
}

自定义SQL分页同时也可以加条件:(有版本分页开缓存报数组下标越界必须配置ConfigurationCustomizer,使用PageHelper没问题)

/**
  * 带自定义条件和分页的dao方法
  * 必须使用ew注入条件到SQL
  * 版本 >= 3.0.7
  */
public List<Emp> select(IPage<Emp> page, @Param("ew") QueryWrapper qw);

xml:

<resultMap id="EmpMap" type="com.cssl.pojo.Emp">
    <id property="empno" column="empno" jdbcType="INTEGER"/>
    <association property="dept"/>
</resultMap>

<select id="select" resultMap="EmpMap">
    select * from emp e left join dept d
			on e.dept_no=d.deptno =
</select>

update(T entity, Wrapper<T> updateWrapper)使用:   只需要注意,入参第一位是需要update的实体类,updateWrapper里的实体类是用于生成where条件

column-underline: true   实体类使用了驼峰命名将自动映射下划线表字段:如createDate->create_date MP不是用*,都将使用下划线去查询

五、反向工程:

(使用Idea插件Free Mybatis ToolMyBatisX插件也可以反向)

<dependency>			
	<groupId>org.springframework.boot</groupId>			
	<artifactId>spring-boot-starter-freemarker</artifactId>	
</dependency>

<!-- https://mvnrepository.com/artifact/freemarker/freemarker -->
<!-- 直接导该库有异常? -->
<dependency>
    <groupId>freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.9</version>
</dependency>

<dependency>			
	<groupId>com.baomidou</groupId>			
	<artifactId>mybatis-plus-generator</artifactId>			
	<version>3.5.x</version>		
</dependency>

Java代码:

//MyBatisPlus3.5.1之前
public static void main(String[] args) {
	AutoGenerator mpg = new AutoGenerator();
    // 选择 freemarker 引擎,默认 Velocity
    mpg.setTemplateEngine(new FreemarkerTemplateEngine());

    // 全局配置
    GlobalConfig gc = new GlobalConfig();
    gc.setAuthor("startym");
    gc.setOutputDir("D:/app/workspaces/LG27C/demo/src/main/java");
    /*gc.setFileOverride(true);   // 是否覆盖同名文件,默认是false
    gc.setActiveRecord(true);  // 不需要ActiveRecord特性的请改为false
    gc.setEnableCache(true);   // XML 二级缓存 默认是false
    gc.setBaseResultMap(true); // XML ResultMap 默认是false
    gc.setBaseColumnList(true);// XML columList 默认是false*/

    mpg.setGlobalConfig(gc);

    // 数据源配置
    DataSourceConfig dsc = new DataSourceConfig();
    dsc.setDbType(DbType.MYSQL);
    dsc.setDriverName("com.mysql.cj.jdbc.Driver");
    dsc.setUsername("root");
    dsc.setPassword("root");
    dsc.setUrl("jdbc:mysql://localhost:3306/mybatis?useUnicode=true&serverTimezone=UTC&characterEncoding=utf8");
    mpg.setDataSource(dsc);

    // 策略配置
    StrategyConfig strategy = new StrategyConfig();
    //strategy.setTablePrefix(new String[] { "buy_" });// 此处可以修改为您的表前缀
    strategy.setNaming(NamingStrategy.no_change);// 表名生成策略
    strategy.setInclude(new String[] { "dept","emp" }); // 需要生成的表
    strategy.setEntityLombokModel(true);
    mpg.setStrategy(strategy);

    // 包配置
    PackageConfig pc = new PackageConfig();
    pc.setParent("com.cssl.gen");
    // pc.setModuleName("test");
    mpg.setPackageInfo(pc);

    // 执行生成
    mpg.execute();
}


//MyBatisPlus3.5.1之后
public static void main(String[] args) {
        FastAutoGenerator.create("jdbc:mysql://localhost:3306/test?useUnicode=true&serverTimezone=UTC&characterEncoding=utf8",
                        "root", "root")
                .globalConfig(builder -> {
                    builder.author("startym") // 设置作者
                            .enableSwagger() // 开启 swagger 模式
                            .fileOverride() // 覆盖已生成文件
                            .outputDir("D:\\app\\workspaces\\java209\\mp\\src\\main\\java"); // 指定输出目录
                })
                .packageConfig(builder -> {
                    builder.parent("com.cssl") // 设置父包名
                            .moduleName("generator") // 设置父包模块名
                            .pathInfo(Collections.singletonMap(OutputFile.xml, "D:\\app\\workspaces\\java209\\mp\\src\\main\\resources\\xml")); // 设置mapperXml生成路径
                })
                .strategyConfig(builder -> {
                    builder.addInclude("users","classes");
                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .execute();

    }

}

插件用法:

六、性能分析插件:

(3.2开始移除了,使用第三方p6spy)

依赖:

<dependency>
  <groupId>p6spy</groupId>
  <artifactId>p6spy</artifactId>
  <version>3.9.1</version>
</dependency>

yml:

spring:
  datasource:
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:p6spy:mysql:///test?serverTimezone=GMT
    username: root
    password: root

spy.properties 配置:

#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2
/**
  * 3.2以前自带性能分析
  * 3.2开始移除该接口,使用p6spy,不需要写该Bean
  */
@Bean
@Profile({"dev","test"})// 设置 dev test 环境开启
public PerformanceInterceptor performanceInterceptor() {
	PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
	performanceInterceptor.setMaxTime(100);//ms,超过此处设置的ms则sql不执行
	performanceInterceptor.setFormat(true);
	return performanceInterceptor;
}

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值