MybatisPlus框架并不是取代原本的mybatis,而是对Mybatis做了一层封装提供了更简洁的数据层访问方式,但是MybatisPlus并没有对原本mybatis的使用方式造成影响。MP主要优势有两点:提供了默认的API进行数据层的访问,在我们不去写任何sql的情况下就可以对数据库进行基本的CRUD。提供了内置的代码生成器可以快捷生成实体类、数据层接口、映射xml。
mp的依赖中已经默认引入了mybatis的依赖,就不需要再额外导入mybatis的依赖。
com.baomidou
mybatis-plus-boot-starter
3.4.0
这里的配置和单独使用mybatis没有区别,仍然要配置数据源,mybatis映射文件地址等等。
server:
port: 80
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 123456
mybatis:
mapper-locations: classpath:/mapper/*Mapper.xml
type-aliases-package: com.test.entity
在新建数据层接口时继承一个叫BaseMapper的父类,同时传入泛型(当前这个数据层操作那个实体类就传那个泛型)
BaseMapper中提供了一系列CRUD的方法,而这些方法,MP已经帮我们进行了实现,要注意MP在执行sql时,是根据属性名称生成的SQL语句。所以我们需要保证实体类属性名称必须和数据库表的字段名称一致。
public interface UserMapper extends BaseMapper {
}
int insert(T entity); //传入实体对象实现新增
int deleteById(Serializable id);//根据ID删除
int deleteByMap(@Param("cm") Map columnMap);//根据键值对删除数据,键值对中的每一对键值都会作为删除的条件来使用
int delete(@Param("ew") Wrapper wrapper);//根据条件删除 使用MP提供的条件封装API封装条件
int deleteBatchIds(@Param("coll") Collection extends Serializable> idList);//根据ID集合删除数据
int updateById(@Param("et") T entity);//根据传入的实体更新(根据主键更新其他所有数据),会将实体中的非空数据更新到数据库,但是0会更新到数据库
int update(@Param("et") T entity, @Param("ew") Wrapper updateWrapper);//根据传入的实体和Wrapper进行更新,entity中保存的是更新的数据,updateWrapper存放的是更新的条件和需要更新的字段
T selectById(Serializable id);
List selectBatchIds(@Param("coll") Collection extends Serializable> idList);
List selectByMap(@Param("cm") Map columnMap);
T selectOne(@Param("ew") Wrapper queryWrapper);
Integer selectCount(@Param("ew") Wrapper queryWrapper);
List selectList(@Param("ew") Wrapper queryWrapper);
List
关于Wrapper类的使用:
在使用mybatis generator生成的代码中,每个类都有一个对应的example类,用于封装条件,mybatis plus提供了一个Wrapper类,用于封装各种条件。
下面我们就Wrapper中的常用条件的封装方式给出示例:
要封装条件首先需要实例化一个Wrapper类,Wrapper类分为两种,QueryWrapper和UpdateWrapper,UpdateWrapper比QueryWrapper多了set条件的设置,可以用于动态更新字段。实例化Wrapper类时需要指定泛型。例如:
需要追加条件时,通过Wrapper提供的API来完成:
eq:eq用于添加相等的条件。
eq(R column, Object val):参数一为字段名称,参数二为值
eq(boolean condition, R column, Object val):参数一为boolean值,表示是否需要添加该条件到sql
ne:ne用于添加不相等的条件。
ne(R column, Object val):参数一为字段名称,参数二为值
ne(boolean condition, R column, Object val):参数一为boolean值,表示是否需要添加该条件到sql
gt:gt用于添加大于的条件
gt(R column, Object val)
gt(boolean condition, R column, Object val)
ge:ge用于添加大于等于的条件
ge(R column, Object val)
ge(boolean condition, R column, Object val)
lt:lt用于添加小于的条件
lt(R column, Object val)
lt(boolean condition, R column, Object val)
le:le用于添加小于等于的条件
le(R column, Object val)
le(boolean condition, R column, Object val)
between:between用于添加在两者之间的条件
between(R column, Object val1, Object val2)
between(boolean condition, R column, Object val1, Object val2)
notBetween:notBetween用于添加不在两者之间的条件
notBetween(R column, Object val1, Object val2)
notBetween(boolean condition, R column, Object val1, Object val2)
like:like用于添加模糊查询的条件
like(R column, Object val)
like(boolean condition, R column, Object val)
notLike:notlike用于添加not like 条件
notLike(R column, Object val)
notLike(boolean condition, R column, Object val)
likeLeft:leftLike用于添加左侧模糊匹配的条件
likeLeft(R column, Object val)
likeLeft(boolean condition, R column, Object val)
likeRight:likeRight用于添加右侧模糊匹配的条件
likeRight(R column, Object val)
likeRight(boolean condition, R column, Object val)
or:or用于追加or条件
or():主动调用则下一个条件会使用or来拼接
or(boolean condition)
orderBy:排序
orderBy(boolean condition, boolean isAsc, R... columns)
select:用于设置查询的字段列表
select(String... sqlSelect)
加载MybatisPlus的分页插件,通过配置类来加载
//加载分页插件拦截器
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
前端传条件数据封装为实体以及页码和每页显示行数,将这些数据一起传到业务层,业务的方法返回值需要定义为Page类型(MybatisPlus提供的Page类型)
@Override
public Page selectPage(User user, int pageNum, int pageSize) {}
在业务方法中实例化一个Page对象,定义泛型为实体类型,在构造函数中传入页码和每页显示行数
Page userPage = new Page<>(pageNum,pageSize);
根据前端传递的条件参数,拼接动态查询条件
QueryWrapper wrapper = new QueryWrapper<>();
if(user.getNickname()!=null&&!"".equals(user.getNickname())){
wrapper.like("nickname",user.getNickname());
}
if(user.getAccount()!=null&&!"".equals(user.getAccount())){
wrapper.like("account",user.getAccount());
}
调用Mapper的API:selectPage(Page page,Wrapper wrapper);得到的返回值为Page对象,需要说明的是该Page对象就是我们之前所创建的Page对象。所有的数据(分页数据,业务数据)都保存在了这个Page对象中。返回该对象到控制层。
@Override
public Page selectPage(User user, int pageNum, int pageSize) {
Page userPage = new Page<>(pageNum,pageSize);
QueryWrapper wrapper = new QueryWrapper<>();
if(user.getNickname()!=null&&!"".equals(user.getNickname())){
wrapper.like("nickname",user.getNickname());
}
if(user.getAccount()!=null&&!"".equals(user.getAccount())){
wrapper.like("account",user.getAccount());
}
userMapper.selectPage(userPage, wrapper);
return userPage;
}
在控制层中将Page中的数据封装为一个自定义个Page对象(保存分页数据),取出其中的集合数据,一起封装为JSONresult,响应给前端。
@GetMapping
public JSONResult selectPage(User user,int pageNum,int pageSize)throws Exception{
IPage page = userService.selectPage(user, pageNum, pageSize);
List list = page.getRecords();
Page page1 = new Page();
page1.setCount(page.getTotal());
page1.setTotal(page.getPages());
page1.setCurrent(page.getCurrent());
page1.setSize(page.getSize());
return new JSONResult("1001","",page1,list);
}
引入依赖
org.apache.velocity
velocity-engine-core
2.2
com.baomidou
mybatis-plus-generator
3.4.0
通过代码实现逆向工程:
public class CodeGenerator {
public static void main(String[] args) {
String projectPath="D:\\springboot-demo\\src\\main\\";
AutoGenerator ag = new AutoGenerator();
//1. 全局配置
GlobalConfig config = new GlobalConfig();
config.setAuthor("wuyanzu") //作者
.setOutputDir(projectPath+"java") //生成路径
.setFileOverride(true)//是否文件覆盖,如果多次
.setIdType(IdType.AUTO) //主键策略
.setServiceName("%sService") //设置生成的service接口名首字母不用I开头
.setBaseResultMap(true)//映射文件中生成默认的baseMap
.setBaseColumnList(true);//映射文件中生成默认的基础列名sql
//2. 数据源配置
DataSourceConfig dsConfig = new DataSourceConfig();
dsConfig.setDbType(DbType.MYSQL)
.setUrl("jdbc:mysql://localhost:3306/test")
.setDriverName("com.mysql.jdbc.Driver")
.setUsername("root")
.setPassword("123456");
//3.策略配置
StrategyConfig stConfig = new StrategyConfig();
stConfig.setCapitalMode(true) // 全局大写命名
.setNaming(NamingStrategy.underline_to_camel) //下划线转驼峰
.setInclude(new String[]{"t_student","teacher"});//生成的表,参数为数组
//4.包名策略
PackageConfig pkConfig = new PackageConfig();
pkConfig.setParent("com.test")//父包名
.setController("controller")
.setEntity("entity")
.setService("service")
.setMapper("mapper");
//5.生成xml的配置
List focList = new ArrayList<>();
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
}
};
String templatePath = "/templates/mapper.xml.vm";
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return projectPath+"\\resources\\mapper\\"+ tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
cfg.setFileOutConfigList(focList);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
//不生成如下类型模板
templateConfig.setXml(null);
ag.setTemplate(templateConfig);
//6.整合配置
ag.setGlobalConfig(config)
.setDataSource(dsConfig)
.setStrategy(stConfig)
.setPackageInfo(pkConfig)
.setCfg(cfg)
.setTemplateEngine(new VelocityTemplateEngine());
ag.execute();
}
}