# xp-mapper **Repository Path**: wxpcode123/xp-mapper ## Basic Information - **Project Name**: xp-mapper - **Description**: 这是一个mybatis通用的service接口实现。 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2020-03-05 - **Last Updated**: 2022-09-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MyBatis 通用 Mapper4的扩展 ## 介绍 这是一个Mybatis通用的service接口实现,通过继承service类和通用Mapper接口,实现对单表的增删改查。对查询参数可以任意自定义实体类、map等类型,返回参数可以自定义返回参数,通过对象拷贝实现参数自定义转换。 ## 软件架构 软件架构说明 spring-boot-starter、Mybatis、mapper等框架集成。 ## 使用教程 ### 1. 引入依赖包: ``` center.wxp mybatis.mapper 1.1.5 ``` ### 2. 对象关系映射 示例针对 MySql 数据库(数据库对主键影响较大,和 insert 关系密切,主键使用的是雪花算法)。 数据库表: ``` CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `name` varchar(30) DEFAULT NULL COMMENT '姓名', `age` int(11) DEFAULT NULL COMMENT '年龄', `email` varchar(50) DEFAULT NULL COMMENT '邮箱', `create_date` datetime DEFAULT NULL COMMENT '创建时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; ``` 对应的 Java 实体类型如下: ``` @ApiModelProperty(value = "主键ID") @NotNull(message="主键ID不能为空") @Id private String id; @ApiModelProperty(value = "姓名") private String name; @ApiModelProperty(value = "年龄") private Integer age; @ApiModelProperty(value = "邮箱") private String email; @ApiModelProperty(value = "创建时间") @Column(name = "create_date") private Date createDate; ``` 最简单的情况下,只需要一个 @Id 标记字段为主键即可。数据库中的字段名和实体类的字段名是完全相同的,这中情况下实体和表可以直接映射。 ### 3、查询接口示列: #### 3.1 自定义实体类 说明:参数自动判空,但是对空字符不能判断! 参数类: ``` @Data public class UserListDto { @ApiModelProperty(value = "主键ID") private String id; @ApiModelProperty(value = "姓名") private String name; @ApiModelProperty(value = "年龄") private Integer age; } ``` #### List findListByObject(Object obj) 接口 代码如下: ``` public Result> objList(UserListDto dto) { List list = userService.findListByObject(dto); return Result.ok().setData(list); } ``` SQL日志: ``` Preparing: SELECT id,name,age,email,create_date FROM user WHERE ( ( name = ? and id = ? and age = ? ) ) Parameters: Jone(String), 1(Long), 18(Integer) ``` UserListDto 类定义参数要跟表生成实体类字段名称一致,就可以进行查询。 #### List findListByMap(Map map) 接口 map:查询参数。 代码: ``` Map map = new HashMap<>(); map.put("id", dto.getId()); map.put("name", dto.getName()); list = userService.findListByMap(map); ``` SQL日志: ``` Preparing: SELECT id,name,age,email,create_date FROM user WHERE ( ( name = ? and id = ? ) ) Parameters: Jone(String), 1(Long) ``` #### List findListByOnly(String fieldName, Object value) 接口 fieldName:字段名属性,value:字段值 代码: ``` List list = new ArrayList<>(); try{ list = userService.findListByOnly("id", id); ``` 打印sql: ``` SELECT id,name,age,email,create_date FROM user WHERE ( ( id = ? ) ) ``` #### ArrayList findListByObject(Object obj, Class m) 接口 obj:查询参数 Class m:是自定义返回参数类。 返回实体类: ``` @Data public class UserListVo { @ApiModelProperty(value = "主键ID") private Long id; @ApiModelProperty(value = "姓名") private String name; } ``` 代码: ``` List list = new ArrayList<>(); try{ list = userService.findListByObject(dto, UserListVo.class); ``` 打印sql: ``` SELECT name , id FROM user WHERE ( ( id = ? ) ) ``` 3.2通过注解查询: 查询条件定义:id使用数组查询,创建时间在某个区间段,时间使用倒序返回,姓名使用模糊查询。 参数实体类: ``` @Data public class UserListAnnotationDto { @ApiModelProperty(value = "主键IDS") @ParamCondition(pattern = "in",entityName = "id") private String[] ids; @ApiModelProperty(value = "姓名") @ParamCondition(pattern = "like",fuzzyPosition = "all") private String name; @ApiModelProperty(value = "年龄") private Integer age; @ApiModelProperty(value = "开始创建时间") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @ParamCondition(pattern = ">=",entityName = "createDate") private Date beginCreateDate; @ApiModelProperty(value = "结束创建时间") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @ParamCondition(pattern = "<=", entityName = "createDate") private Date endCreateDate; } ``` 代码: ``` @ApiOperation(value = "Annotation查询参数实体类(list不分页)") @GetMapping("/objAnnotationList") public Result> objAnnotationList(UserListAnnotationDto dto) { List list = new ArrayList<>(); try{ //User.class是表实体类、dto查询参数,ConditionRewrite.equalToCondition注解解析 Condition condition = ConditionRewrite.equalToCondition(new Condition(User.class), dto); list = userService.findListByCondition(condition); }catch (Exception e) { log.error("UserController 获取信息异常:{}", e); return Result.failure().setCode(StatusCode.FAILURE.getCode()).setMsg("UserController 获取信息异常!"); } return Result.ok().setData(list); } ``` 打印sql: ``` Preparing: SELECT id,name,age,email,create_date FROM user WHERE ( ( id in ( ? , ? ) and name like ? and create_date >= ? and create_date <= ? ) ) Parameters: 1(Long), 2(Long), %J%(String), 2020-03-20 16:48:50.0(Timestamp), 2020-03-20 16:48:50.0(Timestamp) ``` ### 4、保存 #### String saveSelectiveIdObject(Object obj)接口:有选择保存参数。自动加入主键id,id使用雪花算法。 String 返回雪花算法id。 代码如下: ``` @ApiOperation(value = "添加信息") @PostMapping("/add") public Result add(User user) { String id = userService.saveSelectiveId(user); return Result.ok().setData(id); } ``` SQL日志: ``` Preparing: INSERT INTO user ( id,name,age,email ) VALUES( ?,?,?,? ) Parameters: 691656638020452352(String), 老王(String), 20(Integer), 1099@qq.com(String) ``` #### int saveOrUpdateKeySelective(Object obj)保存或更新,当主键冲突时更新信息。 int:返回保存或更新行数 代码如下: ``` @ApiOperation(value = "添加或更新信息") @PostMapping("/addOrUpdate") public Result addOrUpdate(User user) { int count = userService.saveOrUpdateKeySelective(user); return Result.ok().setData(count); } ``` SQL日志: ``` Preparing: INSERT INTO user ( id,name,age,email ) VALUES( ?,?,?,? ) on duplicate key update name = ?,age = ?,email = ? Parameters: 691656638020452352(String), 张三(String), 30(Integer), 1099272020@qq.com(String), 张三(String), 30(Integer), 1099272020@qq.com(String) ``` #### int saveOrUpdateKeyList(List models),批量保存或更新。 参数: ``` [ { "age": 60, "email": "1099272020@qq.com", "id": "691656638020452352", "name": "张三" }, { "age": 50, "email": "12346@qq.com", "id": "691656638020452353", "name": "赵六" } ] ``` 代码如下: ``` @ApiOperation(value = "批量保存或更新信息") @PostMapping("/batchAddOrUpdate") public Result batchAddOrUpdate(@RequestBody List list) { for (User user : list) { user.setCreateDate(new Date()); } int count = userService.saveOrUpdateKeyList(list); return Result.ok().setData(count); } ``` SQL日志: ``` Preparing: INSERT INTO user ( id,name,age,email,create_date ) VALUES ( ?,?,?,?,? ) , ( ?,?,?,?,? ) on duplicate key update id=VALUES (id ),name=VALUES (name ),age=VALUES (age ),email=VALUES (email ),create_date=VALUES (create_date ) Parameters: 691656638020452352(String), 张三(String), 60(Integer), 1099272020@qq.com(String), 2020-03-23 15:36:24.714(Timestamp), 691656638020452353(String), 赵六(String), 50(Integer), 12346@qq.com(String), 2020-03-23 15:36:24.714(Timestamp) ``` ### 5、更新 #### int updateBySelectiveObject(Object tbO, Object obj),更新。 tbO:更新表字段。 obj:更新条件参数。 代码: ``` @ApiOperation(value = "修改信息") @PutMapping("/update") public Result update(User user) { try { userService.updateBySelectiveObject(user,user); } catch (Exception e) { log.error("UserController 更新信息异常:{}", e); return Result.failure().setCode(StatusCode.FAILURE.getCode()).setMsg("UserController 更新信息异常!"); } return Result.ok(); } ``` ``` 这里输入代码 ``` SQL日志: ``` Preparing: UPDATE user SET name = ?,email = ? WHERE ( ( name = ? and id = ? and email = ? ) ) Parameters: 王二(String), 1099272022@qq.com(String), 王二(String), 1(String), 1099272022@qq.com(String) ``` ### 6、删除 #### int deleteBySelectCondition(Condition condition),通过查询参数作为删除条件。 代码: ``` Condition condition = new Condition(User.class); Condition.Criteria criteria = condition.createCriteria(); criteria.andNotIn("id", Arrays.asList((String[]) ids)); criteria.andEqualTo("age", 12); userService.deleteBySelectCondition(condition); ``` 删除不在ids并且age等于12的数据。 SQL日志: ``` Preparing: DELETE FROM user WHERE id IN (SELECT id FROM (SELECT id FROM user WHERE ( ( id not in ( ? ) and age = ? ) ) ) AS id) Parameters: 1(String), 12(Integer) ``` ### 7、注解类ConditionRewrite使用说明 #### 7.1注解类 ``` @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface ParamCondition { String entityName() default ""; String pattern(); String patternType() default "and"; String fuzzyPosition() default ""; String order() default ""; String orderType() default "desc"; } ``` entityName:表字段名称,不填写的话默认取实体类名称。 示列:这里取的是createDate。 ``` @ParamCondition(pattern = "<=", entityName = "createDate") private Date endCreateDate; ``` ##### pattern:查询符号,可取值(is not null、=、!=、>、>=、<、<=、in、not in、like、not like),默认值:=。 ##### patternType:参数连接符号,可取值(and、or),默认值:and。 ##### fuzzyPosition:模糊查询符号,需要和like和not like一起使用,可取值(before(前模糊)、after(后模糊)、all(前后模糊))。 ##### order:排序,可取值(order) ##### orderType:排序类型,和order一起使用,可取值(desc,asc) #### 7.2注解使用示列: ``` @Data public class UserListAnnotationDto { @ApiModelProperty(value = "主键IDS") @ParamCondition(pattern = "in",entityName = "id") private Long[] ids; @ApiModelProperty(value = "姓名") @ParamCondition(pattern = "like",fuzzyPosition = "all") private String name; @ApiModelProperty(value = "年龄") @ParamCondition(order = "order",orderType = "desc") private Integer age; @ApiModelProperty(value = "开始创建时间") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @ParamCondition(pattern = ">=",entityName = "createDate") private Date beginCreateDate; @ApiModelProperty(value = "结束创建时间") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @ParamCondition(pattern = "<=", entityName = "createDate") private Date endCreateDate; } ``` SQL日志: ``` Preparing: SELECT id,name,age,email,create_date FROM user WHERE ( ( id in ( ? ) and name like ? and create_date >= ? and create_date <= ? ) ) order by age DESC Parameters: 1(Long), %J%(String), 2020-03-20 16:48:50.0(Timestamp), 2020-03-20 16:48:50.0(Timestamp) ``` #### 码云特技 ##### 1、个人CSDN博客地址:https://blog.csdn.net/xp_lx1 ##### 2、通用mapper文档:https://github.com/abel533/Mapper/wiki ##### 3、使用demo地址:https://gitee.com/wxpcode123/mybatis-mapper-demo