MyBatis-plus入门
介绍
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
主页: https://mp.baomidou.com/
引入 MyBatis-Plus
之后请不要再次引入 MyBatis
以及 MyBatis-Spring
,以避免因版本差异导致的问题。
特性:
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer2005、SQLServer 等多种数据库
- 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- 支持 XML 热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动
- 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
- 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 支持关键词自动转义:支持数据库关键词(order、key…)自动转义,还可自定义关键词
- 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
- 内置 Sql 注入剥离器:支持 Sql 注入剥离,有效预防 Sql 注入攻击
代码生成器
创建工程引入依赖
<?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">
<parent>
<artifactId>myBatisPlusDemo</artifactId>
<groupId>com.itheima</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>myBatisPlus-generator</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!--就不需要手动引入mybatis -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<!--mybatisplus 代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.31</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.51</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
</dependency>
<!--slf4j-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>
</project>
拷贝Generator类,并修改内容
package com.itheima;
public class Generator {
/**
* <p>
* MySQL 生成演示
* </p>
*/
//获取 项目绝对路径
private static String canonicalPath = "";
public static void main(String[] args) {
//获取项目路径
try {
canonicalPath = new File("").getCanonicalPath();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("canonicalPath="+canonicalPath);
String filePath = canonicalPath+"\\myBatisPlus-generator\\src\\main\\";
AutoGenerator mpg = new AutoGenerator();
// 选择 freemarker 引擎,默认 Veloctiy
//mpg.setTemplateEngine(new FreemarkerTemplateEngine());
// 全局配置
GlobalConfig gc = new GlobalConfig();
gc.setAuthor("HM");
gc.setOutputDir(filePath+"java");//代码生成路径
gc.setFileOverride(true);// 是否覆盖同名文件,默认是false
gc.setActiveRecord(true);// 不需要ActiveRecord特性的请改为false
gc.setEnableCache(false);// XML 二级缓存
gc.setBaseResultMap(true);// XML ResultMap
gc.setBaseColumnList(false);// XML columList
gc.setOpen(false);//生成后打开文件夹
/* 自定义文件命名,注意 %s 会自动填充表实体属性! */
gc.setMapperName("%sMapper");
gc.setXmlName("%sMapper");
gc.setServiceName("%sService");
gc.setServiceImplName("%sServiceImpl");
// gc.setControllerName("%sAction");
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setDbType(DbType.MYSQL);
dsc.setTypeConvert(new MySqlTypeConvert() {
// 自定义数据库表字段类型转换【可选】
@Override
public IColumnType processTypeConvert(GlobalConfig gc, String fieldType) {
System.out.println("转换类型:" + fieldType);
// 注意!!processTypeConvert 存在默认类型转换,如果不是你要的效果请自定义返回、非如下直接返回。
//默认会把日期类型 转为LocalDateTime ,在查询的时候会报错,这里改为Date
String t = fieldType.toLowerCase();
if(t.contains("date") || t.contains("time") || t.contains("year")){
return DbColumnType.DATE;
}else{
return super.processTypeConvert(gc,fieldType);
}
}
});
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
dsc.setUrl("jdbc:mysql:///mytest?useUnicode=true&characterEncoding=utf8");
mpg.setDataSource(dsc);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
//strategy.setCapitalMode(true);// 全局大写命名 ORACLE 注意
//strategy.setTablePrefix("tb_");// 此处可以修改为您的表前缀
strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true);//【实体】是否为lombok模型(默认 false)
//strategy.setInclude(new String[] { "user" }); // 需要生成的表
// strategy.setExclude(new String[]{"test"}); // 排除生成的表
// 自定义实体父类
// strategy.setSuperEntityClass("com.baomidou.demo.TestEntity");
// 自定义实体,公共字段
// strategy.setSuperEntityColumns(new String[] { "test_id", "age" });
// 自定义 mapper 父类
// strategy.setSuperMapperClass("com.baomidou.demo.TestMapper");
// 自定义 service 父类
// strategy.setSuperServiceClass("com.baomidou.demo.TestService");
// 自定义 service 实现类父类
// strategy.setSuperServiceImplClass("com.baomidou.demo.TestServiceImpl");
// 自定义 controller 父类
// strategy.setSuperControllerClass("com.baomidou.demo.TestController");
// 【实体】是否生成字段常量(默认 false)
// public static final String ID = "test_id";
// strategy.setEntityColumnConstant(true);
// 【实体】是否为构建者模型(默认 false)
// public User setName(String name) {this.name = name; return this;}
// strategy.setEntityBuilderModel(true);
mpg.setStrategy(strategy);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setParent("com.itheima");// 自定义包路径
pc.setController("controller");// 这里是控制器包名,默认 web
pc.setMapper("mapper");// 设置Mapper包名,默认mapper
pc.setService("service");// 设置Service包名,默认service
pc.setEntity("pojo");// 设置Entity包名,默认entity,继承的父类 已序列化
//pc.setXml("mapper.xml");// 设置Mapper XML包名,默认mapper.xml
mpg.setPackageInfo(pc);
// 注入自定义配置,可以在 VM 中使用 cfg.abc 设置的值
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
this.setMap(map);
}
};
// 调整 xml 生成目录演示
List<FileOutConfig> focList = new ArrayList<>();
focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return filePath+"\\resources\\mapper\\xml\\" + tableInfo.getEntityName() + "Mapper.xml";
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
// 注入自定义配置,可以在 VM 中使用 cfg.abc 【可无】
// InjectionConfig cfg = new InjectionConfig() {
// @Override
// public void initMap() {
// Map<String, Object> map = new HashMap<String, Object>();
// map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
// this.setMap(map);
// }
// };
//
// // 自定义 xxList.jsp 生成
// List<FileOutConfig> focList = new ArrayList<>();
// focList.add(new FileOutConfig("/template/list.jsp.vm") {
// @Override
// public String outputFile(TableInfo tableInfo) {
// // 自定义输入文件名称
// return "D://my_" + tableInfo.getEntityName() + ".jsp";
// }
// });
// cfg.setFileOutConfigList(focList);
// mpg.setCfg(cfg);
//
// // 调整 xml 生成目录演示
// focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
// @Override
// public String outputFile(TableInfo tableInfo) {
// return "/develop/code/xml/" + tableInfo.getEntityName() + ".xml";
// }
// });
// cfg.setFileOutConfigList(focList);
// mpg.setCfg(cfg);
//
// // 关闭默认 xml 生成,调整生成 至 根目录
// TemplateConfig tc = new TemplateConfig();
// tc.setXml(null);
// mpg.setTemplate(tc);
// 自定义模板配置,可以 copy 源码 mybatis-plus/src/main/resources/templates 下面内容修改,
// 放置自己项目的 src/main/resources/templates 目录下, 默认名称一下可以不配置,也可以自定义模板名称
// TemplateConfig tc = new TemplateConfig();
// tc.setController("...");
// tc.setEntity("...");
// tc.setMapper("...");
// tc.setXml("...");
// tc.setService("...");
// tc.setServiceImpl("...");
// 如上任何一个模块如果设置 空 OR Null 将不生成该模块。
// mpg.setTemplate(tc);
// 执行生成
mpg.execute();
// 打印注入设置【可无】
// System.err.println(mpg.getCfg().getMap().get("abc"));
}
}
运行Generator,得到生成的代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DTAiB649-1585532253954)(代码生成后的结构.png)]
代码如下
实体类
package com.itheima.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author HM
* @since 2019-06-22
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class User extends Model<User> {
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private String userName;
private String password;
private String name;
private Integer age;
/**
* 1男性,2女性
*/
private Integer gender;
private Date birthday;
private Date created;
private Date updated;
/**
* 备注
*/
private String note;
@Override
protected Serializable pkVal() {
return this.id;
}
}
@TableName 注解表名
@TableId 【主键注解】
属性 | 类型 | 必须指定 | 默认值 | 描述 |
---|---|---|---|---|
value | String | 否 | “” | 主键字段名 |
type | Enum | 否 | IdType.NONE | 主键类型 |
type的内容有如下可选
值 | 描述 |
---|---|
AUTO | 数据库自增 |
INPUT | 自行输入 |
ID_WORKER | 分布式全局唯一ID 长整型类型 |
UUID | 32位UUID字符串 |
NONE | 无状态 |
ID_WORKER_STR | 分布式全局唯一ID 字符串类型 |
@TableField 【非主键字段注解】
其中 exist 是否为数据库表字段 常用
属性 | 类型 | 必须指定 | 默认值 | 描述 |
---|---|---|---|---|
value | String | 否 | “” | 字段名 |
el | String | 否 | “” | 映射为原生 #{ ... } 逻辑,相当于写在 xml 里的 #{ ... } 部分 |
exist | boolean | 否 | true | 是否为数据库表字段 |
condition | String | 否 | “” | 字段 where 实体查询比较条件,有值设置则按设置的值为准,没有则为默认全局的 %s=#{%s} ,参考 |
update | String | 否 | “” | 字段 update set 部分注入, 例如:update="%s+1":表示更新时会set version=version+1(该属性优先级高于 el 属性) |
strategy | Enum | 否 | FieldStrategy.DEFAULT | 字段验证策略 |
fill | Enum | 否 | FieldFill.DEFAULT | 字段自动填充策略 |
select | boolean | 否 | true | 是否进行 select 查询 |
keepGlobalFormat | boolean | 否 | false | 是否保持使用全局的 format 进行处理(@since 3.1.1) |
FieldStrategy
值 | 描述 |
---|---|
IGNORED | 忽略判断 |
NOT_NULL | 非NULL判断 |
NOT_EMPTY | 非空判断(只对字符串类型字段,其他类型字段依然为非NULL判断) |
DEFAULT | 追随全局配置 |
FieldFill
值 | 描述 |
---|---|
DEFAULT | 默认不处理 |
INSERT | 插入时填充字段 |
UPDATE | 更新时填充字段 |
INSERT_UPDATE | 插入和更新时填充字段 |
@Version 乐观锁注解
@EnumValue 通枚举类注解(注解在枚举字段上)
Mapper.java
生成的Mapper 中什么内容也没有,但是继承了BaseMapper
public interface UserMapper extends BaseMapper<User> {
}
Mapper.xml
生成的Mapper.xml中也是空的
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.UserMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.itheima.pojo.User">
<id column="id" property="id" />
<result column="user_name" property="userName" />
<result column="password" property="password" />
<result column="name" property="name" />
<result column="age" property="age" />
<result column="gender" property="gender" />
<result column="birthday" property="birthday" />
<result column="created" property="created" />
<result column="updated" property="updated" />
<result column="note" property="note" />
</resultMap>
</mapper>
Service
//接口继承 IService<T>
public interface UserService extends IService<User> {
}
//实现类继承 ServiceImpl<TbBrandMapper, TbBrand>
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
注意:通用 CRUD 封装BaseMapper接口,为 Mybatis-Plus
启动时自动解析实体表关系映射转换为 Mybatis
内部对象注入容器。
所以简单的CRUD,我们就不需要写了,直接注入service,调用就好了。
BaseMapper中默认提供的方法有:
public interface BaseMapper<T> extends Mapper<T> {
int insert(T var1);
int deleteById(Serializable var1);
int deleteByMap(@Param("cm") Map<String, Object> var1);
int delete(@Param("ew") Wrapper<T> var1);
int deleteBatchIds(@Param("coll") Collection<? extends Serializable> var1);
int updateById(@Param("et") T var1);
int update(@Param("et") T var1, @Param("ew") Wrapper<T> var2);
T selectById(Serializable var1);
List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> var1);
List<T> selectByMap(@Param("cm") Map<String, Object> var1);
T selectOne(@Param("ew") Wrapper<T> var1);
Integer selectCount(@Param("ew") Wrapper<T> var1);
List<T> selectList(@Param("ew") Wrapper<T> var1);
List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> var1);
List<Object> selectObjs(@Param("ew") Wrapper<T> var1);
IPage<T> selectPage(IPage<T> var1, @Param("ew") Wrapper<T> var2);
IPage<Map<String, Object>> selectMapsPage(IPage<T> var1, @Param("ew") Wrapper<T> var2);
}
SSM方式入门
创建工程,引入依赖
注意:MyBatis的包由MyBatisPlus依赖引入,不需要单独引入
pom文件内容:
<?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">
<parent>
<artifactId>myBatisPlusDemo</artifactId>
<groupId>com.itheima</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ssm-myBatisplus-demo</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!--就不需要手动引入mybatis -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<!--mybatisplus 代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.31</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.51</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
</dependency>
<!--slf4j-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
编写配置文件
JDBC.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///mytest?characterEncoding=UTF-8
jdbc.name=root
jdbc.password=123456
SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--控制台显示sql语句-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<plugins>
<plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor">
<property name="dialectType" value="mysql"/>
</plugin>
</plugins>
</configuration>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 加载配置文件 -->
<context:property-placeholder location="classpath*:*.properties" />
<context:component-scan base-package="com.itheima"/>
<!--spring配置数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.name}" />
<property name="password" value="${jdbc.password}" />
<property name="driverClassName" value="${jdbc.driver}" />
<property name="maxActive" value="10" />
<property name="minIdle" value="5" />
</bean>
<!--通过spring得到sessionFactory,通过如下配置configuration.xml文件已经不需要了-->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!--扫描pojo包,对应数据库 限定名来指定这些POJO-->
<property name="typeAliasesPackage" value="com.itheima.pojo" />
<!-- 加载mybatis的全局配置文件 -->
<property name="configLocation" value="classpath:SqlMapConfig.xml" />
<!-- 自动扫描Mapping.xml文件-->
<property name="mapperLocations" value="classpath*:mapper/xml/*.xml"/>
</bean>
<!-- DAO接口所在包名,Spring会自动查找其下的类 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.itheima.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
<!--事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--注解式事务-->
<tx:annotation-driven />
</beans>
拷贝已经生成的类
实体类,Mapper、*Mapper.xml,service 类,考入SSM工程
测试
创建测试类和测试方法
package com.itheima.test;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.pojo.User;
import com.itheima.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class TestDb {
@Autowired
private UserService userService;
@Test
public void testFindAll() {
List<User> list = userService.list();
for (User user : list) {
System.out.println(user);
}
}
@Test
public void testFindOne() {
User user = userService.getById(1L);
System.out.println(user);
}
@Test
public void testUpdate() {
//根据id更新
User user = new User();
user.setId(3L);
user.setName("修改后的阿紫");
userService.updateById(user);
//根据条件更新
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
//设置更新内容 这里要写字段的名字
updateWrapper.set("age", 1);
//设置更新条件 这里要写字段的名字
updateWrapper.like("gender", 1);
userService.update();
}
@Test
public void testInsert() {
User user = new User();
user.setName("阿青");
user.setAge(20);
user.setUserName("小青青");
user.setNote("本来是条蛇");
userService.save(user);
}
@Test
public void testPage() {
Page<User> page = new Page<>(2, 3);
//这里要写字段的名字
page.setDesc("id");
IPage<User> userIPage = userService.page(page);
System.out.println(userIPage);
for (User user : userIPage.getRecords()) {
System.out.println(user);
}
}
@Test
public void testQueryCondition() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
//这里要写字段的名字
wrapper.likeRight("name", "亮");
// wrapper.eq("gender",0);
// wrapper.ge("age",20);
List<User> userList = userService.list(wrapper);
for (User user : userList) {
System.out.println(user);
}
}
@Test
public void testDelete() {
//根据主键id删除
boolean b = userService.removeById(9L);
//根据条件删除
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//这里要写字段的名字
queryWrapper.like("name", "亮");
userService.remove(queryWrapper);
System.out.println(b);
}
}
SpringBoot方式
创建工程引入依赖
pom.xml 父依赖 已经在写在父工程的pom文件中了
<?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">
<parent>
<artifactId>myBatisPlusDemo</artifactId>
<groupId>com.itheima</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springboot-myBatisplus-demo</artifactId>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.1</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
<!-- druid阿里巴巴数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.31</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
</project>
编写配置文件
application.yml
spring:
application:
name: plus-test
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql:///mytest?characterEncoding=UTF-8
username: root
password: 123456
type: com.alibaba.druid.pool.DruidDataSource
#myBatis-plus
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath*:mapper/**Mapper.xml
type-aliases-package: com.itheima.mapper
编写启动类
package com.itheima;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.itheima.mapper")
public class SpringBootRunner {
public static void main(String[] args) {
SpringApplication.run(SpringBootRunner.class,args);
}
}
编写MybatisPlus分页配置
package com.itheima.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
/***
* plus 的性能优化
* @return
*/
@Bean
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
/*<!-- SQL 执行性能分析,开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长 -->*/
performanceInterceptor.setMaxTime(1000);
/*<!--SQL是否格式化 默认false-->*/
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
/**
* @Description : mybatis-plus分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
拷贝代码
实体类,Mapper、*Mapper.xml,service 类,考入工程
测试
package com.itheima.test;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.SpringBootRunner;
import com.itheima.pojo.User;
import com.itheima.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = SpringBootRunner.class)
public class TestBoot {
@Autowired
private UserService userService;
@Test
public void testFindAll() {
List<User> list = userService.list();
for (User user : list) {
System.out.println(user);
}
}
@Test
public void testFindOne() {
User user = userService.getById(1L);
System.out.println(user);
}
@Test
public void testUpdate() {
//根据id更新
User user = new User();
user.setId(3L);
user.setName("修改后的阿紫");
userService.updateById(user);
//根据条件更新
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
//设置更新内容 这里要写字段的名字
updateWrapper.set("age", 1);
//设置更新条件 这里要写字段的名字
updateWrapper.like("gender", 1);
userService.update();
}
@Test
public void testInsert() {
User user = new User();
user.setName("阿青");
user.setAge(20);
user.setUserName("小青青");
user.setNote("本来是条蛇");
userService.save(user);
}
@Test
public void testPage() {
Page<User> page = new Page<>(2, 3);
//这里要写字段的名字
page.setDesc("id");
IPage<User> userIPage = userService.page(page);
System.out.println(userIPage);
for (User user : userIPage.getRecords()) {
System.out.println(user);
}
}
@Test
public void testQueryCondition() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
//这里要写字段的名字
wrapper.likeRight("name", "亮");
// wrapper.eq("gender",0);
// wrapper.ge("age",20);
List<User> userList = userService.list(wrapper);
for (User user : userList) {
System.out.println(user);
}
}
@Test
public void testDelete() {
//根据主键id删除
boolean b = userService.removeById(9L);
//根据条件删除
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//这里要写字段的名字
queryWrapper.like("name", "亮");
userService.remove(queryWrapper);
System.out.println(b);
}
}
条件构造器
上面介绍的方法都是简单的CRUD,如果是条件操作该怎么办呢
条件操作需要使用条件构造器
AbstractWrapper
构造器的父类。包含各种类型条件操作,如:
and、or、exists、eq 、 gt、lt、between、like、isNull、in、groupBy、having、orderByAsc
QueryWrapper
用来进行构造查询条件,AbstractWrapper的子类
UpdateWrapper
用来进行构造更新操作的值和条件,AbstractWrapper的子类
注意,传输Wrapper不被支持
不支持以及不赞成在 RPC 调用中把 Wrapper 进行传输。
/**
* 根据多条件查询
*/
@Test
public void testQueryCondition(){
System.out.println("=====条件查询======");
//添加条件 first_char like ? and id = ?
QueryWrapper<TbBrand> tbBrandQueryWrapper = new QueryWrapper<>();
tbBrandQueryWrapper.like("first_char","F");
tbBrandQueryWrapper.eq("id",31L);
List<TbBrand> list1 = brandService.list(tbBrandQueryWrapper);
for (TbBrand record : list1) {
System.out.println(record);
}
}
分页操作
如果仔细看引入的依赖,会发现没有引入和分页相关的包。
原因是MyBatisPlus自身带有分页插件
配置
但是需要进行配置,以SSM为例,我们创建一个myBatis.xml,别忘了在application.xml文件中引入
这里面的PaginationInterceptor 就是用来帮助我们分页的
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--控制台显示sql语句-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<plugins>
<plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor">
<property name="dialectType" value="mysql"/>
</plugin>
</plugins>
</configuration>
SpringBoot 需要创建一个config类
package com.itheima.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
/***
* plus 的性能优化
* @return
*/
@Bean
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
/*<!-- SQL 执行性能分析,开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长 -->*/
performanceInterceptor.setMaxTime(1000);
/*<!--SQL是否格式化 默认false-->*/
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
/**
* @Description : mybatis-plus分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}