在有Mybatis基础的情况下,再去接触Mybatis-plus,就容易的多
先就我现在使用情况讲讲,我眼中,它跟Mybatis啥区别吧。
作为Mybatis的升级版,它除了具备Mybatis本身就有的功能之外,还增加了通过lambda表达式操作数据库,以及逻辑删除标识等功能
1.引入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<optional>true</optional>
</dependency>
2.通过数据库中的表反向生成mapper,实体等
2.1在idea中建立数据库连接
2.2安装MybatisX-Generator插件
2.3选中表,右键通过MybatisX-Generator插件去生成实体,mapper,甚至service的接口实现类都能生出来
IDEA插件之mybatisx 插件使用教程_idea mybatis插件_IT小悟的博客-CSDN博客
下边能看到service也能生出来,生出来的service中也自动引入了mapper
3.service调用
3.1 生成的service长这样
自动继承了一个ServiceImpl,这个ServiceImpl是Mybatis-Plus提供的
@Service
public class SysDataSourceConfigServiceImpl extends ServiceImpl<SysDataSourceConfigMapper, SysDataSourceConfig>
implements SysDataSourceConfigService{
}
3.2 service中如何使用
Mybatis-plus给生成的service都提供了一个公共父类,就是上边的
ServiceImpl这里边有很多泛型方法,所以继承的时候指定mapper和entity之后,就可以直接调用一些现成的方法,不需要自己再去实现
我现在一般比较常用的是
getById(通过id查询)
saveOrUpdate(根据id是否存在去走新增方法或者保存方法)
updateById(但是mybatis在update的时候,不会更新空字段,如果有些情况你不希望这个字段被修改,直接在业务代码里把他置为空即可)
我把Mybatis-plus的class文件直接贴上来了
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.baomidou.mybatisplus.extension.service.impl;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
protected Log log = LogFactory.getLog(this.getClass());
@Autowired
protected M baseMapper;
protected Class<T> entityClass = this.currentModelClass();
protected Class<M> mapperClass = this.currentMapperClass();
public ServiceImpl() {
}
public M getBaseMapper() {
return this.baseMapper;
}
public Class<T> getEntityClass() {
return this.entityClass;
}
/** @deprecated */
@Deprecated
protected boolean retBool(Integer result) {
return SqlHelper.retBool(result);
}
protected Class<M> currentMapperClass() {
return ReflectionKit.getSuperClassGenericType(this.getClass(), ServiceImpl.class, 0);
}
protected Class<T> currentModelClass() {
return ReflectionKit.getSuperClassGenericType(this.getClass(), ServiceImpl.class, 1);
}
/** @deprecated */
@Deprecated
protected SqlSession sqlSessionBatch() {
return SqlHelper.sqlSessionBatch(this.entityClass);
}
/** @deprecated */
@Deprecated
protected void closeSqlSession(SqlSession sqlSession) {
SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(this.entityClass));
}
/** @deprecated */
@Deprecated
protected String sqlStatement(SqlMethod sqlMethod) {
return SqlHelper.table(this.entityClass).getSqlStatement(sqlMethod.getMethod());
}
@Transactional(
rollbackFor = {Exception.class}
)
public boolean saveBatch(Collection<T> entityList, int batchSize) {
String sqlStatement = this.getSqlStatement(SqlMethod.INSERT_ONE);
return this.executeBatch(entityList, batchSize, (sqlSession, entity) -> {
sqlSession.insert(sqlStatement, entity);
});
}
protected String getSqlStatement(SqlMethod sqlMethod) {
return SqlHelper.getSqlStatement(this.mapperClass, sqlMethod);
}
@Transactional(
rollbackFor = {Exception.class}
)
public boolean saveOrUpdate(T entity) {
if (null == entity) {
return false;
} else {
TableInfo tableInfo = TableInfoHelper.getTableInfo(this.entityClass);
Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!", new Object[0]);
String keyProperty = tableInfo.getKeyProperty();
Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!", new Object[0]);
Object idVal = tableInfo.getPropertyValue(entity, tableInfo.getKeyProperty());
return !StringUtils.checkValNull(idVal) && !Objects.isNull(this.getById((Serializable)idVal)) ? this.updateById(entity) : this.save(entity);
}
}
@Transactional(
rollbackFor = {Exception.class}
)
public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
TableInfo tableInfo = TableInfoHelper.getTableInfo(this.entityClass);
Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!", new Object[0]);
String keyProperty = tableInfo.getKeyProperty();
Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!", new Object[0]);
return SqlHelper.saveOrUpdateBatch(this.entityClass, this.mapperClass, this.log, entityList, batchSize, (sqlSession, entity) -> {
Object idVal = tableInfo.getPropertyValue(entity, keyProperty);
return StringUtils.checkValNull(idVal) || CollectionUtils.isEmpty(sqlSession.selectList(this.getSqlStatement(SqlMethod.SELECT_BY_ID), entity));
}, (sqlSession, entity) -> {
MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap();
param.put("et", entity);
sqlSession.update(this.getSqlStatement(SqlMethod.UPDATE_BY_ID), param);
});
}
@Transactional(
rollbackFor = {Exception.class}
)
public boolean updateBatchById(Collection<T> entityList, int batchSize) {
String sqlStatement = this.getSqlStatement(SqlMethod.UPDATE_BY_ID);
return this.executeBatch(entityList, batchSize, (sqlSession, entity) -> {
MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap();
param.put("et", entity);
sqlSession.update(sqlStatement, param);
});
}
public T getOne(Wrapper<T> queryWrapper, boolean throwEx) {
return throwEx ? this.baseMapper.selectOne(queryWrapper) : SqlHelper.getObject(this.log, this.baseMapper.selectList(queryWrapper));
}
public Map<String, Object> getMap(Wrapper<T> queryWrapper) {
return (Map)SqlHelper.getObject(this.log, this.baseMapper.selectMaps(queryWrapper));
}
public <V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper) {
return SqlHelper.getObject(this.log, this.listObjs(queryWrapper, mapper));
}
/** @deprecated */
@Deprecated
protected boolean executeBatch(Consumer<SqlSession> consumer) {
return SqlHelper.executeBatch(this.entityClass, this.log, consumer);
}
protected <E> boolean executeBatch(Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) {
return SqlHelper.executeBatch(this.entityClass, this.log, list, batchSize, consumer);
}
protected <E> boolean executeBatch(Collection<E> list, BiConsumer<SqlSession, E> consumer) {
return this.executeBatch(list, 1000, consumer);
}
}
上代码
4.Mapper使用
4.1 生成的Mapper长这样
@Mapper//这个我好像是自己加上去的
public interface SysGroupMapper extends BaseMapper<SysGroup> {
}
4.2 BaseMapper的使用
Mybatis-plus不光在ServiceImpl中通过泛型提供了很多基础的方法
也在BaseMapper中通过泛型,提供了很多方法
我一般用的比较多的
this.baseMapper.selectBatchIds(collect);this.baseMapper.selectList(new LambdaQueryWrapper<SysGroup>().in(SysGroup::getId, groupIds).select(SysGroup::getGroupName));
直接贴上Mybatis-plus自带的BaseMapper代码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.baomidou.mybatisplus.core.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
public interface BaseMapper<T> extends Mapper<T> {
int insert(T entity);
int deleteById(Serializable id);
int deleteById(T entity);
int deleteByMap(@Param("cm") Map<String, Object> columnMap);
int delete(@Param("ew") Wrapper<T> queryWrapper);
int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);
int updateById(@Param("et") T entity);
int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);
T selectById(Serializable id);
List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);
List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);
default T selectOne(@Param("ew") Wrapper<T> queryWrapper) {
List<T> ts = this.selectList(queryWrapper);
if (CollectionUtils.isNotEmpty(ts)) {
if (ts.size() != 1) {
throw ExceptionUtils.mpe("One record is expected, but the query result is multiple records", new Object[0]);
} else {
return ts.get(0);
}
} else {
return null;
}
}
Long selectCount(@Param("ew") Wrapper<T> queryWrapper);
List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);
List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);
List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);
<P extends IPage<T>> P selectPage(P page, @Param("ew") Wrapper<T> queryWrapper);
<P extends IPage<Map<String, Object>>> P selectMapsPage(P page, @Param("ew") Wrapper<T> queryWrapper);
}
贴一段代码
4.3正常使用mapper
5.lambda表达式
List<SysGroup> sysGroups = this.baseMapper.selectList(new LambdaQueryWrapper<SysGroup>().in(SysGroup::getId, groupIds).select(SysGroup::getGroupName));
sysUserGroupMapper.delete(new LambdaQueryWrapper<SysUserGroup>().eq(SysUserGroup::getUserName,username));
List<SysUser> list = sysUserService.list(new LambdaQueryWrapper<SysUser>().in(SysUser::getId, userIdList).select(SysUser::getUsername));
List<SysGroup> list = this.list(new LambdaQueryWrapper<SysGroup>().ne(id != null, SysGroup::getId, id).eq(SysGroup::getGroupName, groupName));
boolean result = this.update(new LambdaUpdateWrapper<SysMenu>()
.eq(SysMenu::getId, menuId)
.set(SysMenu::getVisible, status)
);