基于tkmybatis封装常用的增删改查接口

一、背景

2019年偶然的机会了解到Agilebpm开源工作流项目,当然我不是要给他们打广告哦,真的觉得这个项目代码写得挺好的,扩展性很强。看它们的前端后端代码,我也可以学到一些设计思想什么的。不扯其它的,他们团队也封装了一套增删改查接口。看了他们的代码之后,当时我们项目用的是tk-mybatis组件,那么就想着基于tk-mybatis组件稍微封装一下这个接口,这个查询接口就会变得很灵活,当然你们用的mybatis-plus组件也是一样的。

二、代码封装

2.1 Pom

pom文件引入相关的依赖,数据源是MySQL还是PostgreSQL,可根据自己的情况添加相应的依赖。

<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper-spring-boot-starter</artifactId>
    <version>2.1.5</version>
</dependency>
<!-- pagehelper -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.2.12</version>
</dependency>
<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper</artifactId>
    <version>4.1.5</version>
</dependency>

2.2 Entity

2.2.1 BaseModel

实体类父类,非必须,不需要的话可忽略,也可以根据自己的需要修改父类字段,这里只是做个示范。

@Data
public class BaseModel  implements Serializable {

    @Column(name = "create_user")
    private Integer createUser;

    @Column(name = "create_time")
    private Date createTime;

    @Column(name = "update_user")
    private Integer updateUser;

    @Column(name = "update_time")
    private Date updateTime;

    @LogicDelete
    @Column(name = "is_delete")
    private Boolean isDelete;

}
2.2.2 QueryOP

查询操作符枚举类,后面接口调用会根据这个类来处理查询逻辑。

public enum QueryOP {
    EQUAL("EQ", "=", "等于", new String[]{"V", "N", "D"}),
    LESS("LT", "<", "小于", new String[]{"V","N", "D"}),
    GREAT("GT", ">", "大于", new String[]{"V","N", "D"}),
    LESS_EQUAL("LTE", "<=", "小于等于", new String[]{"V","N", "D"}),
    GREAT_EQUAL("GTE", ">=", "大于等于", new String[]{"V","N", "D"}),
    NOT_EQUAL("NE", "!=", "不等于", new String[]{"V", "N", "D"}),
    LIKE("LK", "like", "相似", new String[]{"V"}),
    LEFT_LIKE("LFK", "like", "左相似", new String[]{"V"}),
    RIGHT_LIKE("RHK", "like", "右相似", new String[]{"V"}),
    IS_NULL("INL", "is null", "为空", new String[]{"V", "N", "D"}),
    NOTNULL("NNL", "is not null", "非空", new String[]{"V", "N", "D"}),
    IN("IN", "in", "在...中", new String[]{"V", "N", "D"}),
    NOT_IN("NI", "not in", "不在...中", new String[]{"V", "N", "D"}),
    BETWEEN("BT", "between", "在...之间", new String[]{"N", "D"}),
    NOT_BETWEEN("NBT", "not between", "不在...之间", new String[]{"N", "D"});
    private String val;
    private String op;
    private String desc;
    private String[] supports;//V->varchar N->number D->date

    private QueryOP(String val, String op, String desc, String[] supports) {
        this.val = val;
        this.op = op;
        this.desc = desc;
        this.supports = supports;
    }

    public String value() {
        return val;
    }

    public String op() {
        return op;
    }

    public String desc() {
        return desc;
    }

    public String[] supports() {
        return supports;
    }

    

    public static QueryOP getByVal(String val) {
        for (QueryOP queryOP : values()) {
            if (queryOP.val.equals(val)) {
                return queryOP;
            }
        }
        return null;
    }

}

2.3 Mapper

2.3.1 BaseMapper
public interface BaseMapper<T> extends Mapper<T>, MySqlMapper<T> {
    //TODO
    //FIXME 特别注意,该接口不能被扫描到,否则会出错
}

2.4 Service

2.4.1 IBaseService

Service层接口类父类,可根据需要自行添加其它方法。

public interface IBaseService<T> {

    /**
     * 添加记录
     * @param entity
     * @return
     */
    int save(T entity);

    /**
     * 批量添加记录 只适合主键为数值类型且自增的情况
     * @param list
     * @return
     */
    int saveList(List<T> list);

    /**
     * 批量添加记录 主键为UUID
     * @param list
     * @return
     */
    int saveListNoUseGeneratedKeysAndUuid(List<T> list);

    /**
     * 根据主键删除记录
     * @param key
     * @return
     */
    int delete(Object key);

    /**
     * 根据实体删除记录
     * @param entity 删除条件:实体类不为空的字段
     * @return
     */
    int deleteByEntity(T entity);

    /**
     * 批量删除记录
     * @param keys 属性集合
     * @param clazz
     * @param idName 为空此属性默认为“id”
     * @return
     */
    int deleteByKeys(List keys, Class clazz, String idName);


    /**
     * 更新记录
     * @param entity 实体类所有字段
     * @return
     */
    int updateAll(T entity);

    /**
     * 更新记录
     * @param entity 实体类不为空的字段
     * @return
     */
    int updateNotNull(T entity);

    /**
     * 批量更新记录
     * @param list
     * @return
     */
    int updateAllList(List<T> list);



    /**
     * 批量更新记录
     * @param list
     * @return
     */
    int updateNotNullList(List<T> list);

    /**
     * 批量更新记录【属性集合】(只适合于多条记录更改成一样的情况)
     * 例如 我需要把这一批设备的状态全部更改为“在线”
     * @param keys
     * @param t
     * @param idName
     * @return
     */
    int updateByKeys(List keys, T t, String idName);

    /**
     * 批量更新记录【表达式】
     * @param t
     * @param example
     * @return
     */
    int updateByExampleSelective(T t, Example example);


    /**
     * 根据主键查找记录
     * @param key 主键
     * @return
     */
	T selectByKey(Object key);

    /**
     *批量查找记录
     * @param keys 某属性集合
     * @param clazz
     * @param idName 为null此属性默认为“id”
     * @return
     */
    List<T> selectByKeys(List keys, Class clazz, String idName);

    /**
     * 查找某一记录 必须保证唯一
     * @param t 筛选条件:实体类不为空的字段
     * @return
     */
    T selectOne(T t);

    /**
     * 根据实体类查找对象
     * @param t
     * @return
     */
    List<T> selectByEntity(T t);

    /**
     * 查找对象
     * @param example 【tk表达式】
     * @return
     */
    List<T> selectByExample(Example example);

    /**
     * 分页查找对象
     * @param t
     * @param pageNum
     * @param pageSize
     * @return
     */
    PageInfo<T> selectPageByEntity(T t, int pageNum, int pageSize);

    /**
     * 分页查找对象
     * @param example 【tk表达式】
     * @param pageNum
     * @param pageSize
     * @return
     */
    PageInfo<T> selectPageByExample(Example example, int pageNum, int pageSize);

   



    //TODO 其他...
}

2.4.2 BaseService

Service层接口实现类父类。


public abstract class BaseService<T> implements IBaseService<T> {

    private static final Logger LOG = Logger.getLogger(BaseService.class);

    @Autowired
    protected Mapper<T> mapper;

    @Autowired
    protected MySqlMapper<T> mySqlMapper;

    @Autowired
    protected MyDefineUpdateMapper<T> myDefineUpdateMapper;



    public Mapper<T> getMapper() {
        return mapper;
    }

    @Override
    public T selectByKey(Object key) {
        return mapper.selectByPrimaryKey(key);
    }

    @Override
    public List<T> selectByKeys(List keys, Class clazz, String idName) {
        if(keys == null || keys.size() == 0){
            return Collections.emptyList();
        }
        Example example = new Example(clazz);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn(StringUtils.isEmpty(idName) ? "id" : idName, keys);
        return selectByExample(example);
    }

    @Override
    public T selectOne(T t) {
        return mapper.selectOne(t);
    }

    @Override
    @Transactional
    public int save(T t) {
        return mapper.insertSelective(t);
    }


    @Override
    @Transactional
    public int delete(Object key) {
        return mapper.deleteByPrimaryKey(key);
    }



    @Override
    public int deleteByKeys(List keys, Class clazz, String idName) {
        if(keys == null || keys.size() == 0){
            return 0;
        }
        Example example = new Example(clazz);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn(StringUtils.isEmpty(idName) ? "id" : idName, keys);
        return mapper.deleteByExample(example);
    }

    @Override
    @Transactional
    public int updateByKeys(List keys, T t, String idName) {
        if(keys == null || keys.size() == 0){
            return 0;
        }
        Example example = new Example(t.getClass());
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn(StringUtils.isEmpty(idName) ? "id" : idName, keys);
        updateByExampleSelective(t, example);
        return 0;
    }

    @Override
    @Transactional
    public int deleteByEntity(T t) {
        return mapper.delete(t);
    }

    @Override
    @Transactional
    public int updateAll(T t) {
        return mapper.updateByPrimaryKey(t);
    }


    @Override
    @Transactional
    public int updateNotNull(T t) {
        return mapper.updateByPrimaryKeySelective(t);
    }

    @Override
    public List<T> selectByEntity(T t) {
        return mapper.select(t);
    }


    @Override
    public List<T> selectByExample(Example example) {
        return mapper.selectByExample(example);
    }

    @Override
    public PageInfo<T> selectPageByEntity(T t, int pageNum, int pageSize) {
        //分页查询
        PageHelper.startPage(pageNum, pageSize); // , true
        List<T> list = selectByEntity(t);
        return new PageInfo<>(list);
    }


    @Override
    public PageInfo<T> selectPageByExample(Example example, int pageNum, int pageSize) {
        //分页查询
        PageHelper.startPage(pageNum, pageSize); // , true
        List<T> list = selectByExample(example);
        return new PageInfo<>(list);
    }

    //TODO 其他...

    @Override
    @Transactional
    public int saveList(List<T> list) {
        if(list != null && list.size() > 0){
            return mySqlMapper.insertList(list);
        }
        return 0;
    }

    

    @Override
    @Transactional
    public int saveListNoUseGeneratedKeysAndUuid(List<T> list) {
        if(list != null && list.size() > 0) {
            return mySqlMapper.insertListNoUseGeneratedKeys(list);
        }
        return 0;
    }

    @Override
    @Transactional
    public int updateByExampleSelective(T t, Example example) {
        return mapper.updateByExampleSelective(t,example);
    }

  

   

    @Override
    @Transactional
    public int updateAllList(List<T> list) {
        if(list != null && list.size() > 0) {
            for(T t : list){
                setTimeAndUser(t,false);
            }
            return myDefineUpdateMapper.batchUpdateByPrimaryKey(list);
        }
        return 0;
    }

   

    @Override
    @Transactional
    public int updateNotNullList(List<T> list) {
        if(list != null && list.size() > 0) {
             return myDefineUpdateMapper.batchUpdateByPrimaryKeySelective(list);
        }
        return 0;
    }

    


}

需要注意的是:
1)批量添加方法:tkmybatis只提供了insertList方法,主键为UUID类型的话,即便是你指定了生成主键方式为UUID,它也会报ID不能为空错,看源码不难发现,insertList忽略了ID的值,所以此方法只适应自增的主键,你把insertList复制出来需要稍微修改即可。
在这里插入图片描述

2)批量更新方法:tkmybatis没有提供批量更新方法,需要实现手动实现。

@RegisterMapper
public interface MyDefineUpdateMapper<T> {

    /**
     * 根据Example条件批量更新实体`record`包含的不是null的属性值
     *
     * @return
     */
    @UpdateProvider(type = MyDefineUpdateProvider.class, method = "dynamicSQL")
    int batchUpdateByPrimaryKeySelective(List<? extends T> recordList);

    /**
     * 根据Example条件批量更新实体`record`的属性值
     *
     * @return
     */
    @UpdateProvider(type = MyDefineUpdateProvider.class, method = "dynamicSQL")
    int batchUpdateByPrimaryKey(List<? extends T> recordList);




}

注意MyDefineUpdateProvider 类getSql方法,根据不同的数据源稍微修改一下。

public class MyDefineUpdateProvider extends ExampleProvider {

    public MyDefineUpdateProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
        super(mapperClass, mapperHelper);
    }


    /**
     * 拼update sql, 使用case when方式,id为主键
     *
     * @param ms
     * @return
     */
    public String batchUpdateByPrimaryKeySelective(MappedStatement ms) {
        final Class<?> entityClass = getEntityClass(ms);
        //开始拼sql
        StringBuilder sql = new StringBuilder();
        sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
        sql.append("<trim prefix=\"set\" suffixOverrides=\",\">");

        //获取全部列
        Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);
        for (EntityColumn column : columnList) {
            if (!column.isId() && column.isUpdatable()) {
                sql.append("  <trim prefix=\""+column.getColumn()+" =case\" suffix=\"end,\">");
                sql.append("    <foreach collection=\"list\" item=\"i\" index=\"index\">");
                if(column.getJavaType().equals(String.class)){
                    sql.append("      <if test=\"i."+column.getEntityField().getName()+"!=null and i."+column.getEntityField().getName()+"!='' \">");
                }else{
                    sql.append("      <if test=\"i."+column.getEntityField().getName()+"!=null\">");
                }
                sql.append(getSql(column));
                sql.append("      </if>");
                sql.append("    </foreach>");
                sql.append("  </trim>");
            }

        }

        sql.append("</trim>");
        sql.append("WHERE");
        sql.append(" id IN ");
        sql.append("<trim prefix=\"(\" suffix=\")\">");
        sql.append("<foreach collection=\"list\" separator=\", \" item=\"i\" index=\"index\" >");
        sql.append("#{i.id}");
        sql.append("</foreach>");
        sql.append("</trim>");

        return sql.toString();
    }

    /**
     * 拼update sql, 使用case when方式,id为主键
     *
     * @param ms
     * @return
     */
    public String batchUpdateByPrimaryKey(MappedStatement ms) {
        final Class<?> entityClass = getEntityClass(ms);
        //开始拼sql
        StringBuilder sql = new StringBuilder();
        sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
        sql.append("<trim prefix=\"set\" suffixOverrides=\",\">");

        //获取全部列
        Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);
        for (EntityColumn column : columnList) {
            if (!column.isId() && column.isUpdatable()) {
                sql.append("  <trim prefix=\""+column.getColumn()+" =case\" suffix=\"end,\">");
                sql.append("    <foreach collection=\"list\" item=\"i\" index=\"index\">");
                sql.append(getSql(column));
                sql.append("    </foreach>");
                sql.append("  </trim>");
            }

        }

        sql.append("</trim>");
        sql.append("WHERE");
        sql.append(" id IN ");
        sql.append("<trim prefix=\"(\" suffix=\")\">");
        sql.append("<foreach collection=\"list\" separator=\", \" item=\"i\" index=\"index\" >");
        sql.append("#{i.id}");
        sql.append("</foreach>");
        sql.append("</trim>");

        return sql.toString();
    }

	//MySQL直接获取就行,PostgreSQL需要类型严格一致,需要转换一下数据类型。
    private String getSql(EntityColumn column){
        if(column.getEntityField().getJavaType().equals(Date.class)){
            return "         when id=#{i.id} then cast("+column.getColumnHolder("i") +"as  timestamp) ";
        }else if(column.getEntityField().getJavaType().equals(String.class)){
            JSONAnno jsonAnno = column.getEntityField().getAnnotation(JSONAnno.class);
            if(jsonAnno != null){
                return "         when id=#{i.id} then "+column.getColumnHolder("i") +"::"+jsonAnno.value();

            }else{
                return "         when id=#{i.id} then "+column.getColumnHolder("i");
            }
        }else{
            return "         when id=#{i.id} then "+column.getColumnHolder("i") +"::numeric";
        }
    }
    
    

}

3)插入和更新:比如需要给创建用户/时间、更新用户/时间赋值,可在实体类增加相应的注解再通过反射方式实现,因为这个涉及到用户的获取,这里就把这块的代码删除了,注解类参考如下。


@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface TimeAndUserAnno {
    boolean createTimeExist() default true;
    String createTimeType() default "D";
    String createTimeSetMethod() default "setCreatetime";
    String createTimeGetMethod() default "getCreatetime";


    boolean updateTimeExist() default true;
    boolean updateTimeType() default "D";
    String updateTimeSetMethod() default "setUpdateTime";
    String updateTimeGetMethod() default "getUpdateTime";


    boolean createUserExist() default true;
    String createUserSetMethod() default "setCreateUser";
    String createUserGetMethod() default "getCreateUser";


    boolean updateUserExist() default true;
    String updateUserSetMethod() default "setUpdateUser";
    String updateUserGetMethod() default "getUpdateUser";


}

2.5 Controller

2.5.1 RequestParamUtils

查询接口请求参数处理工具类,注意RequestParamUtils 类getValue方法,根据不同的数据源稍微修改一下。

@Slf4j
public class RequestParamUtils {

    private static final String FIELD_SPILT = "_";
    private static final String SQL_LIKE_CONTACT_STR = "%";
    private static final String REQUEST_PARAM_ERROR = "请求参数格式无效";

    /**
     * 处理请求参数
     * @param obj
     * @return
     */
    public static Example handlerRequestParam(Object obj) {
        Example example = new Example(obj.getClass());
        Example.Criteria criteria = example.createCriteria();
        HttpServletRequest request =
                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        Map<String, String[]> parameterMap = new HashMap(request.getParameterMap());
        String[] orders = parameterMap.remove("order");
        String[] isAscs = parameterMap.remove("isAsc");
        boolean flag = false;
        for (Iterator iter = parameterMap.entrySet().iterator(); iter.hasNext();) {
            Map.Entry element = (Map.Entry) iter.next();
            String key = String.valueOf(element.getKey());
            String[] values = (String[])element.getValue();
            if(key.contains(FIELD_SPILT) &&  handlerRequestParam(key, values, criteria)){
                flag = true;
            }
        }
        if(!flag){
            example = new Example(obj.getClass());
        }
        orderRequestParam(example, orders, isAscs);
        return example;
    }

    public static void orderRequestParam(Example example,String[] orders,String[] isAscs){
        if(Optional.ofNullable(isAscs).isPresent() && "false".equals(isAscs[0])){
            Optional.ofNullable(orders).ifPresent(val ->example.orderBy(val[0]).desc());
        }else{
            Optional.ofNullable(orders).ifPresent(val ->example.orderBy(val[0]).asc());
        }
    }

    private static boolean handlerRequestParam(String key, String[] values,Example.Criteria criteria){
        try {
            int index = key.lastIndexOf(FIELD_SPILT);
            String field = key.substring(0,index);
            String opVal = key.substring(index + 1);
            int size = criteria.getCriteria().size();
            if(opVal.length() > 1){
                String type = opVal.substring(0, 1);
                opVal = opVal.substring(1);
                QueryOP queryOP = QueryOP.getByVal(opVal);
                Optional<List<String>> lists = Optional.ofNullable(queryOP)
                        .map(QueryOP::supports)
                        .map(Arrays::asList);
                if(lists.isPresent() && lists.get().contains(type)){
                    if(queryOP != QueryOP.IS_NULL && queryOP != QueryOP.NOTNULL){
                        if(!isNotNull(values)){
                            return false;
                        }
                    }
                    switch (queryOP){
                        case EQUAL:
                           criteria.andEqualTo(field, getValue(values[0], type));
                            break;
                        case NOT_EQUAL:
                           criteria.andNotEqualTo(field, getValue(values[0], type));
                            break;
                        case LESS:
                           criteria.andLessThan(field, getValue(values[0], type));
                            break;
                        case GREAT:
                            criteria.andGreaterThan(field, getValue(values[0], type));
                            break;
                        case LESS_EQUAL:
                            criteria.andLessThanOrEqualTo(field, getValue(values[0], type));
                            break;
                        case GREAT_EQUAL:
                            criteria.andGreaterThanOrEqualTo(field, getValue(values[0], type));
                            break;
                        case LIKE:
                            criteria.andLike(field,SQL_LIKE_CONTACT_STR+getValue(values[0], type)+SQL_LIKE_CONTACT_STR);
                            break;
                        case LEFT_LIKE:
                           criteria.andLike(field,SQL_LIKE_CONTACT_STR+getValue(values[0], type));
                            break;
                        case RIGHT_LIKE:
                           criteria.andLike(field,getValue(values[0], type)+SQL_LIKE_CONTACT_STR);
                            break;
                        case IS_NULL:
                            criteria.andIsNull(field);
                            break;
                        case NOTNULL:
                            criteria.andIsNull(field);
                            break;
                        case IN:
                           criteria.andIn(field,getValues(values,type));
                            break;
                        case NOT_IN:
                           criteria.andNotIn(field,getValues(values,type));
                            break;
                        case BETWEEN:
                            criteria.andBetween(field, getValue(values[0], type), getValue(values[1], type));
                            break;
                        case NOT_BETWEEN:
                           criteria.andNotBetween(field, getValue(values[0], type), getValue(values[1], type));
                            break;
                        default:
                    }

                }
            }
            return  criteria.getCriteria().size() > size;
        }catch (Exception e){
            log.error(REQUEST_PARAM_ERROR,e);
            return false;
        }
    }

	//MySQL可忽略此方法,PostgreSQL需要类型严格一致,需要转换一下数据类型。
    private static Object getValue(String val , String type){
        switch (type){
            case "N":
                return Long.parseLong(val);
            case "D":
                return DateUtil.parse(val).toJdkDate();

        }
        return val;
    }

    private static List getValues(String[] values , String type){
        List list = new ArrayList();
        for(String str : values){
            list.add(getValue(str, type));
        }

        return list;
    }

    public static boolean isNotNull(String[] values){
        if(values == null || values.length == 0 || (values.length == 1 && values[0].equals(""))){
            return false;
        }
        return true;
    }

    

}
2.5.2 BaseController
public class BaseController<T> extends RequestParamUtils {
	@Autowired
	protected IBaseService<T> baseService;

	@ApiOperation("添加记录")
	@PostMapping("/add")
    public RestResponse<Void> add(@Valid @RequestBody T t) {
		int num = baseService.save(t);
		if(num == 0){
			return RestResponse.buildFailed("添加失败");
		}
		return RestResponse.buildSuccessMsg("添加成功");
    }

	@ApiOperation("批量添加记录")
	@PostMapping("/batchAdd")
	public RestResponse<Void> batchAdd(@Valid @RequestBody ValidableList<T> list) {
		int num = baseService.saveList(list);
		if(num == 0){
			return RestResponse.buildFailed("添加失败");
		}
		return RestResponse.buildSuccessMsg("添加成功");
	}


	@ApiOperation("更新记录(更新所有字段)")
	@PutMapping("/updateAll")
    public RestResponse<Void> updateAll(@Valid @RequestBody T t){
		int num = baseService.updateAll(t);
		return RestResponse.buildSuccessMsg("修改成功");
    }
    
	@ApiOperation("批量更新记录(更新所有字段)")
	@PutMapping("/batchUpdateAll")
	public RestResponse<Void> batchUpdateAll(@Valid @RequestBody ValidableList<T> list){
		int num = baseService.updateAllList(list);
		return RestResponse.buildSuccessMsg("修改成功");
	}

	@ApiOperation("更新记录(更新不为空的字段)")
	@PutMapping("/updateNotNull")
	public RestResponse<Void> updateNotNull(@Valid @RequestBody T t){
		int num = baseService.updateNotNull(t);
		return RestResponse.buildSuccessMsg("修改成功");
    }
    
	


	@ApiOperation("批量更新记录(更新不为空的字段)")
	@PutMapping("/batchUpdateNotNull")
	public RestResponse<Void> updateNotNull(@Valid @RequestBody ValidableList<T> list){
		int num = baseService.updateNotNullList(list);
		return RestResponse.buildSuccessMsg("修改成功");
	}

	@ApiOperation("根据ID删除记录")
	@DeleteMapping("/{id}")
	public RestResponse<Void> delete(@PathVariable Object id){
		int num = baseService.delete(id);
		if(num == 0){
			return RestResponse.buildFailed("没有查到记录");
		}
		return RestResponse.buildSuccessMsg("删除成功");
    }


	@ApiOperation("根据ID查询详情")
	@GetMapping("/{id}")
    public RestResponse find(@PathVariable Object id){
		T t = baseService.selectByKey(id);
		if(t == null){
			return  RestResponse.buildNotFound();
		}
		return RestResponse.buildSuccessData(t);
    }

	@ApiOperation("根据表达式分页查找记录(等值、模糊、范围等)")
	@PostMapping("/findByPageAndExample")
	public RestResponse findByPageAndExample(T t,  @RequestParam(required = false, defaultValue = "1") int pageNumber,
			@RequestParam(required = false, defaultValue = "10") int pageSize) {
		Example example = handlerRequestParam(t);
		PageInfo<T> pageInfo = baseService.selectPageByExample(example,pageNumber,pageSize);
		return RestResponse.buildSuccessData(pageInfo);
    }

	@ApiOperation("根据实体类属性分页查找记录(等值查找)")
	@PostMapping("/findByPageAndObject")
	public RestResponse findByPageAndObject(T t,  @RequestParam(required = false, defaultValue = "1") int pageNumber,
														  @RequestParam(required = false, defaultValue = "10") int pageSize) {
		PageInfo<T> pageInfo = baseService.selectPageByEntity(t,pageNumber,pageSize);
		return RestResponse.buildSuccessData(pageInfo);
	}

	@ApiOperation("根据表达式查找记录(等值、模糊、范围等)")
	@PostMapping("/findByExample")
	public RestResponse findByExample(T t) {
		Example example = handlerRequestParam(t);
		List<T> list = baseService.selectByExample(example);
		return RestResponse.buildSuccessData(list);
    }

	@ApiOperation("根据实体类属性查找记录(等值查找)")
	@PostMapping("/findByObject")
	public RestResponse findByObject(T t) {
		List<T> list = baseService.selectByEntity(t);
		return RestResponse.buildSuccessData(list);
	}




}

三、后端使用说明(生成代码)

3.1 Pom文件引入依赖

项目中记得引入封装好的架包

 
  <dependency>
      <groupId>com.xxx.xxx</groupId>
      <artifactId>xxx_tkmybatis</artifactId>
      <version>1.0.0</version>
  </dependency>
  <plugin>
      <groupId>org.mybatis.generator</groupId>
      <artifactId>mybatis-generator-maven-plugin</artifactId>
      <version>1.3.7</version>
      <configuration>
          <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
          <overwrite>true</overwrite>
          <verbose>true</verbose>
      </configuration>
      <dependencies>
          <dependency>
              <groupId>org.postgresql</groupId>
              <artifactId>postgresql</artifactId>
              <version>42.2.6</version>
          </dependency>
          <!-- 
          <dependency>
              <groupId>mysql</groupId>
              <artifactId>mysql-connector-java</artifactId>
              <version>8.0.18</version>
          </dependency>
          -->
          <dependency>
              <groupId>tk.mybatis</groupId>
              <artifactId>mapper</artifactId>
              <version>4.1.5</version>
          </dependency>
      </dependencies>
  </plugin>

3.2 修改generatorConfig.xml的表名和实体类名

<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <properties resource="gennerator-tools-pgsql.properties"/>

    <context id="pgsql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
        <!--处理sql中的`符号-->
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>

        <!--添加自定义的继承接口-->
        <plugin type="tk.mybatis.mapper.generator.MapperPlugin">
            <property name="mappers" value="com.xxx.utils.BaseMapper"/>
        </plugin>


        <!--数据源配置-->
        <jdbcConnection driverClass="${spring.datasource.driver-class-name}"
                        connectionURL="${spring.datasource.url}"
                        userId="${spring.datasource.username}"
                        password="${spring.datasource.password}">
        </jdbcConnection>

        <!--model包路径-->
        <javaModelGenerator targetPackage="com.xxx.model" targetProject="src/main/java">
            <property name="immutable" value="false"/>
            <!-- 给Model添加一个父类 -->
            <property name="rootClass" value="com.xxx.model.BaseModel"/>
        </javaModelGenerator>
        <!--mapper.xml包路径-->
        <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/>
        <!--mapper包路径-->
        <javaClientGenerator targetPackage="com.xxx.mapper" targetProject="src/main/java"
                             type="XMLMAPPER"/>
        <!--表配置,tableName支持%,表示全部生成-->
        <table tableName="t_sys_user" domainObjectName="SysUser">
            <!--mysql 配置-->
            <generatedKey column="id" identity="true"/>
        </table>
    </context>
</generatorConfiguration>

3.3 点击生成代码

这里会生成对应的实体类和Mapper类
在这里插入图片描述

3.4 修改实体类

如果实体类继承了BaseModel,这里没有对父类做判断,需要手动去掉创建用户时间等字段。

@Data
@Table(name="t_sys_user")
public class SysUser extends BaseModel {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;

	@NotNull(message="账户不能为空")
	private String account;//账户
	
	@NotNull(message="密码不能为空")
	private String password;//密码
	
	private Boolean gender; //性别(0:男;1::女)
	
	
	
}

3.5 新建Service接口继承IBaseService

public interface SysUserService extends IBaseService<SysUser> {

	
}

3.6 新建Service实现类继承BaseService

@Service("sysUserService")
public class SysUserServiceImpl extends BaseService<SysUser> implements SysUserService {
	
	
}

3.7 新建Controller类继承BaseController

@RestController
@RequestMapping("/sysUser")
@TableModule("用户模块")
public class SysUserController extends BaseController<SysUser> {




}

四、前端使用说明(调用接口)

添加、修改、删除等接口跟平常一样,下面重点说明下查询接口使用注意事项:

  1. findByObject:根据实体类不为空的字段进行等值查询,ftime=20200818。
  2. findByExample:根据tk表达式进行查询,组成格式:字段名_字段类型匹配类型。
  • 字段名:实体类属性值。

  • 字段类型:V(Varchar:字符串);N(Numbe:数字类型);D(Date:日期类型)。

  • 匹配类型:参考下图:
    在这里插入图片描述

  • 例子1:查询时间在20200801和20200820之间的数据
    ftime_DGTE=20200801,ftime_DLTE=20200820

  • 例子2:查询名称为小明的数据
    name_VEQ=小明

  • 例子3:模糊查询名称包含小的数据
    name_VLK=小

3.findByPageAndExample/findByPageAndObject同上,只是加了分页功能。

五 小结

到这里所有步骤就全部完成了,单表的增删改查基本几分钟就可以搞定了,而且查询接口参数也很灵活。如有错误,请批评指教。只是提供一个思路,大家根据需要修改。
在这里插入图片描述
在这里插入图片描述

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
使用Spring Boot,MyBatis和Vue进行增删操作的步骤如下: 1. 设置Spring Boot项目: - 使用Spring Initializr创建一个新的Spring Boot项目。 - 在pom.xml文件中添加所需的依赖项,包括Spring Boot、MyBatis和Vue相关的依赖项。 - 配置数据库连接信息,例如数据库URL、用户名和密码等。 2. 创建数据库表: - 使用SQL脚本或图形化工具创建数据库表,定义表结构和字段。 3. 创建实体类: - 在Spring Boot项目中创建Java实体类,代表数据库表中的每个字段。 - 使用注解(如@TableName)映射实体类和数据库表。 4. 创建Mapper接口: - 在Spring Boot项目中创建Mapper接口,用于定义数据库的增删操作。 - 使用MyBatis的注解(如@Select、@Insert、@Update、@Delete)映射接口方法和SQL询。 5. 实现Mapper接口: - 在Spring Boot项目中创建Mapper接口的实现类,实现具体的数据操作逻辑。 6. 创建Vue前端页面: - 在Vue项目中创建前端页面,用于展示数据和接收用户的输入。 - 使用Vue的模板语法和组件库构建用户界面。 7. 发送HTTP请求: - 在Vue前端页面中,使用axios或其他HTTP库发送HTTP请求到Spring Boot后端服务器的API接口。 - 根据需求,发送对应的增删请求(如GET请求询数据,POST请求添加数据,PUT请求更新数据,DELETE请求删除数据)。 8. 处理API请求: - 在Spring Boot项目中,处理来自Vue前端页面的API请求。 - 解析请求参数,调用对应的Mapper接口方法,进行增删操作。 - 将操作结果封装成JSON格式,返回给前端页面。 通过以上步骤,你可以实现使用Spring Boot、MyBatis和Vue进行增删操作的应用程序。这些步骤提供了一个基本的指导,你可以根据具体的需求进行调整和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值