在项目很多基本的操作时,编码费时费力,所以想简化基本的增删改查,让开发更加高效,这个插件里面封装好了我们需要用到的很多sql语句,不过这个插件是通过我们去调用它封装的各种方法来实现sql语句的效果。对于单表查询不需要写SQL语句,这样就不用像mybatis那样每次写一个接口就要写一条sql语句。这样大大减少了我们的工作量。只需要写特殊的sql
tk.mybatis
mapper-spring-boot-starter
1.1.1
tk.mybatis
mapper
3.4.0
org.mybatis
mybatis
3.4.2
com.google.guava
guava
27.0.1-jre
2.添加一个UserInfo实体类
3.通用业务层实现,编写项目ServiceImple时需要继承该BaseService,以及其本身自己定义的IService实现基本的增删改查
public abstract class BaseService implements IBaseService {
/**
* The Logger.
*/
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* The Mapper.
*/
@Autowired
protected Mapper mapper;
/**
* Gets mapper.
*
* @return the mapper
*/
public Mapper getMapper() {
return mapper;
}
/**
* Select list.
*
* @param record the record
* @return the list
*/
@Override
public List select(T record) {
return mapper.select(record);
}
/**
* Select by key t.
*
* @param key the key
* @return the t
*/
@Override
public T selectByKey(Object key) {
return mapper.selectByPrimaryKey(key);
}
/**
* Select all list.
*
* @return the list
*/
@Override
public List selectAll() {
return mapper.selectAll();
}
/**
* Select one t.
*
* @param record the record
* @return the t
*/
@Override
public T selectOne(T record) {
return mapper.selectOne(record);
}
/**
* Select count int.
*
* @param record the record
* @return the int
*/
@Override
public int selectCount(T record) {
return mapper.selectCount(record);
}
/**
* Select by example list.
*
* @param example the example
* @return the list
*/
@Override
public List selectByExample(Object example) {
return mapper.selectByExample(example);
}
/**
* Save int.
*
* @param record the record
* @return the int
*/
@Override
public int save(T record) {
return mapper.insertSelective(record);
}
/**
* Batch save int.
*
* @param list the list
* @return the int
*/
@Override
public int batchSave(List list) {
int result = 0;
for (T record : list) {
int count = mapper.insertSelective(record);
result += count;
}
return result;
}
/**
* Update int.
*
* @param entity the entity
* @return the int
*/
@Override
public int update(T entity) {
return mapper.updateByPrimaryKeySelective(entity);
}
/**
* Delete int.
*
* @param record the record
* @return the int
*/
@Override
public int delete(T record) {
return mapper.delete(record);
}
/**
* Delete by key int.
*
* @param key the key
* @return the int
*/
@Override
public int deleteByKey(Object key) {
return mapper.deleteByPrimaryKey(key);
}
/**
* Batch delete int.
*
* @param list the list
* @return the int
*/
@Override
public int batchDelete(List list) {
int result = 0;
for (T record : list) {
int count = mapper.delete(record);
if (count < 1) {
logger.error("删除数据失败");
throw new SystemException("990108");
}
result += count;
}
return result;
}
/**
* Select count by example int.
*
* @param example the example
* @return the int
*/
@Override
public int selectCountByExample(Object example) {
return mapper.selectCountByExample(example);
}
/**
* Update by example int.
*
* @param record the record
* @param example the example
* @return the int
*/
@Override
public int updateByExample(T record, Object example) {
return mapper.updateByExampleSelective(record, example);
}
/**
* Delete by example int.
*
* @param example the example
* @return the int
*/
@Override
public int deleteByExample(Object example) {
return mapper.deleteByPrimaryKey(example);
}
/**
* Select by row bounds list.
*
* @param record the record
* @param rowBounds the row bounds
* @return the list
*/
@Override
public List selectByRowBounds(T record, RowBounds rowBounds) {
return mapper.selectByRowBounds(record, rowBounds);
}
/**
* Select by example and row bounds list.
*
* @param example the example
* @param rowBounds the row bounds
* @return the list
*/
@Override
public List selectByExampleAndRowBounds(Object example, RowBounds rowBounds) {
return mapper.selectByExampleAndRowBounds(example, rowBounds);
}
}
4.通用接口(编写项目Iservice时需要继承该IBaseService实现基本的增删改查)
public interface IBaseService {
/**
* 根据实体中的属性值进行查询, 查询条件使用等号 @param record the record
*
* @param record the record
* @return the list
*/
List select(T record);
/**
* 根据主键字段进行查询, 方法参数必须包含完整的主键属性, 查询条件使用等号 @param key the key
*
* @param key the key
* @return the t
*/
T selectByKey(Object key);
/**
* 查询全部结果, select(null)方法能达到同样的效果 @return the list
*
* @return the list
*/
List selectAll();
/**
* 根据实体中的属性进行查询, 只能有一个返回值, 有多个结果是抛出异常, 查询条件使用等号 @param record the record
*
* @param record the record
* @return the t
*/
T selectOne(T record);
/**
* 根据实体中的属性查询总数, 查询条件使用等号 @param record the record
*
* @param record the record
* @return the int
*/
int selectCount(T record);
/**
* 保存一个实体, null的属性不会保存, 会使用数据库默认值 @param record the record
*
* @param record the record
* @return the int
*/
int save(T record);
/**
* 批量保存 @param list the list
*
* @param list the list
* @return the int
*/
@Transactional(rollbackFor = Exception.class)
int batchSave(List list);
/**
* 根据主键更新属性不为null的值 @param entity the entity
*
* @param entity the entity
* @return the int
*/
int update(T entity);
/**
* 根据实体属性作为条件进行删除, 查询条件使用等号 @param record the record
*
* @param record the record
* @return the int
*/
int delete(T record);
/**
* 批量删除 @param list the list
*
* @param list the list
* @return the int
*/
@Transactional(rollbackFor = Exception.class)
int batchDelete(List list);
/**
* 根据主键字段进行删除, 方法参数必须包含完整的主键属性 @param key the key
*
* @param key the key
* @return the int
*/
int deleteByKey(Object key);
/**
* 这个查询支持通过Example类指定查询列, 通过selectProperties方法指定查询列 @param example the example
*
* @param example the example
* @return the list
*/
List selectByExample(Object example);
/**
* 根据Example条件进行查询总数 @param example the example
*
* @param example the example
* @return the int
*/
int selectCountByExample(Object example);
/**
* 根据Example条件更新实体record包含的不是null的属性值 @param record the record
*
* @param record the record
* @param example the example
* @return the int
*/
int updateByExample(@Param("record") T record, @Param("example") Object example);
/**
* 根据Example条件删除数据 @param example the example
*
* @param example the example
* @return the int
*/
int deleteByExample(Object example);
/**
* 根据实体属性和RowBounds进行分页查询 @param record the record
*
* @param record the record
* @param rowBounds the row bounds
* @return the list
*/
List selectByRowBounds(T record, RowBounds rowBounds);
/**
* 根据example条件和RowBounds进行分页查询 @param example the example
*
* @param example the example
* @param rowBounds the row bounds
* @return the list
*/
List selectByExampleAndRowBounds(Object example, RowBounds rowBounds);
}
5.最基本的Mapper ,编写项目Mapper时继承该Mapper实现基本的增删改查
public interface BaseMapper extends Mapper, MySqlMapper {
}
6.使用方式
这样就实现了基本功能API,基本的增删改查都可以使用啦
附:基于反射的通用模糊查询
/**
* 通用模糊查询
* 只支持本身类型属性模糊查询,字典label目前不支持
*
* @param keyValue 模糊查询的值
* @param examplClass 实体对象的字节码对象
* @param propertyList 需查询的属性(没有就默认查询全部)
* @return List 查询结果
* @author
* @date
*/
@Override
public List keyValueByExample(String keyValue, Class examplClass, List propertyList) {
if (examplClass == null) {
throw new RuntimeException("Class can't be null");
}
if (StringUtils.isBlank(keyValue)) {
throw new RuntimeException("keyValue property to search can't be null");
}
keyValue = "%" + keyValue + "%";
boolean needCheckPropertyList = (propertyList != null && propertyList.size() > 0);
// create Example Criteria
Example example = new Example(examplClass);
Example.Criteria criteria;
// get Class Field
List fields = getFieldList(examplClass);
for (Field field : fields) {
field.setAccessible(true);
// Field tyep: int / java.lang.String / java.lang.Integer / java.lang.Doubbo / java.math.BigDecimal
// int[][] /int / float /doubbo
String canonicalNameType = field.getType().getCanonicalName();
// wether array Enum Synthetic continue
if (field.isEnumConstant() || field.isSynthetic() || canonicalNameType.contains("[]")) {
continue;
}
//Field Name
String fieldName = field.getName();
// judge current filed wether in propertyList need to be select like
criteria = example.createCriteria();
if (needCheckPropertyList) {
for (String property : propertyList) {
if (property.equals(fieldName)) {
if ("java.lang.String".equals(canonicalNameType)) {
criteria.andLike(property, keyValue);
example.or(criteria);
}
// TODO 其它类型
}
}
} else {
if ("java.lang.String".equals(canonicalNameType)) {
criteria.andLike(fieldName, keyValue);
example.or(criteria);
}
// TODO 其它类型
}
}
return mapper.selectByExample(example);
}
/**
* 获取当前字节码对象的属性包含父类属性
*
* @param clazz 字节码对象
* @return 属性集合
* @author
* @date
*/
public static List getFieldList(Class> clazz) {
if (null == clazz) {
return null;
}
List fieldList = new LinkedList<>();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
/** 过滤静态属性**/
if (Modifier.isStatic(field.getModifiers())) {
continue;
}
/** 过滤transient 关键字修饰的属性**/
if (Modifier.isTransient(field.getModifiers())) {
continue;
}
fieldList.add(field);
}
/** 处理父类字段**/
Class> superClass = clazz.getSuperclass();
if (superClass.equals(Object.class)) {
return fieldList;
}
List fieldListSupper = getFieldList(superClass);
if (fieldListSupper != null) {
fieldList.addAll(fieldListSupper);
}
return fieldList;
}
使用如下
@Test
public void keyValueByExample() {
List daList = userService.keyValueByExample("da", User.class, null);
System.out.println("<< ==== keyValueByExample ===== >> " + daList);
}