Mybatis注解 实现动态SQL
以前学习mybatis的时候,基本是在xml里编写sql语句,感觉在xml也还算方便吧。动态sql,参数类都是好管理的。但是,xml对于长sql友好,对短sql就不太友好了。我们写的时候写完接口方法,还是要跑到想关xml里编写,有没有简单方便的,直接可以使用java代码来实现呢?还真有,接下来主要介绍注释式的动态sql。
创建数据库
-- ----------------------------
-- Table structure for base_org
-- ----------------------------
DROP TABLE IF EXISTS `base_org`;
CREATE TABLE `base_org` (
`org_id` varchar(64) NOT NULL COMMENT '组织id',
`pId` varchar(32) DEFAULT NULL COMMENT '父组织id',
`name` varchar(50) DEFAULT NULL COMMENT '组织名称',
`isValid` int(2) DEFAULT NULL COMMENT '是否有效(1:无效,2:有效)',
`description` varchar(50) DEFAULT NULL COMMENT '描述',
`createTime` datetime DEFAULT NULL COMMENT '创建时间',
`updateTime` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`org_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of base_org
-- ----------------------------
INSERT INTO `base_org` VALUES ('1', '0', '设计部', '1', '', '2019-10-09 23:01:36', '2019-11-07 12:58:26');
INSERT INTO `base_org` VALUES ('2', '0', '开发部', '1', '', '2019-10-09 23:22:29', '2019-11-07 12:58:36');
Maven 依赖
<!-- SpringBoot 核心组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- SpringBoot-整合Web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 集成commons工具类 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- 集成lombok 框架 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- mybatis相关依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<!-- mysql 依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- springboot-log4j -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
编写实体类
本项目集成swagger2,不懂得朋友可以去看 https://blog.csdn.net/weixin_43727535/article/details/103426264 注解说明
DO
import lombok.Data;
import java.util.List;
/**
* @author jql
* @ClassName: OrgDo
* @Description: 组织实体类
* @date 2019/12/9 16:28
*/
@Data
public class OrgDo {
/**
*组织id
*/
private String orgId;
/**
*父组织id
*/
private String pId;
/**
*组织名称
*/
private String name;
/**
*是否有效
*/
private Integer isValid;
/**
*描述
*/
private String description;
/**
*创建时间
*/
private String createTime;
/**
*更新时间
*/
private String updateTime;
}
DTO
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author jql
* @ClassName: OrgDto
* @Description: 组织信息dto
* @date 2019/12/10 11:04
*/
@Data
@ApiModel(value = "用户信息实体类")
public class OrgDto {
@ApiModelProperty(value = "组织id")
private String orgId;
@ApiModelProperty(value = "父组织id")
private String pId;
@ApiModelProperty(value = "组织名称")
private String name;
@ApiModelProperty(value = "是否有效 (1:无效,2:有效)")
private Integer isValid;
@ApiModelProperty(value = "描述")
private String description;
}
编写Mapper
import cn.peak.entity.DO.OrgDo;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.jdbc.SQL;
import java.util.List;
import java.util.Map;
/**
* @author jql
* @InterfaceName: OrgMapper
* @Description: 机构组织管理
* @date 2019/12/9 16:51
*/
public interface OrgMapper {
/**
* @Title: selectOrgZTree
* @Description: 根据父id信息,查询组织信息
* @param fatherId 父id
* @return java.util.List<cn.peak.entity.DO.OrgDo>
* @date 2019/12/9 17:03
* @throws
*/
@SelectProvider(type = findOrgBypId.class,method = "selectOrgBypId")
List<Map<String, Object>> selectOrgBypId(@Param("fatherId") String fatherId);
class findOrgBypId{
public String selectOrgBypId(String fatherId){
return new SQL(){
//从这个toString可以看出,其内部使用高效的StringBuilder实现SQL拼接
{
SELECT("*");
FROM("base_org");
if(!StringUtils.isEmpty(fatherId)){
WHERE("pId = #{fatherId}");
}
}
}.toString();
}
}
/**
* @Title: insertOrg
* @Description: 添加组织结构信息
* @param orgDo 组织信息实体类
* @return int 返回受影响条数
* @date 2019/12/9 17:03
* @throws
*/
@Insert("insert into base_org(org_id,pId,name,isValid,description,createTime) " +
"values (#{orgId},#{pId},#{name},#{isValid},#{description},now())")
int insertOrg(OrgDo orgDo);
/**
* @Title: updateOrg
* @Description: 根据id,修改机构组织
* @param orgDo 组织实体类
* @return int 返回受影响数据条数
* @date 2019/12/9 17:01
* @throws
*/
@UpdateProvider(type = saveOrg.class,method = "updateOrg")
int updateOrg(OrgDo orgDo);
class saveOrg{
public String updateOrg(OrgDo orgDo){
return new SQL(){
{
UPDATE("base_org");
if(!StringUtils.isEmpty(orgDo.getPId())){
SET("pId = #{fatherId}");
}
if(!StringUtils.isEmpty(orgDo.getName())){
SET("name = #{name}");
}
if(orgDo.getIsValid() != 0){
SET("isValid = #{isValid}");
}
if(!StringUtils.isEmpty(orgDo.getDescription())){
SET("description = #{description}");
}
SET("updateTime = now()");
WHERE("org_id = #{orgId}");
}
}.toString();
}
}
/**
* @Title: deleteOrg
* @Description: 根据id删除机构组织
* @param ids 要删除的id集合
* @return int 返回受影响的条数
* @date 2019/12/9 16:59
* @throws
*/
@DeleteProvider(type = removeOrgByIds.class,method = "deleteOrg")
int deleteOrg(@Param("ids") List<String> ids);
class removeOrgByIds{
public String deleteOrg(List<String> ids){
StringBuffer sql = new StringBuffer();
sql.append("delete from base_org where org_id in (");
for (int i = 0; i <ids.size() ; i++) {
sql.append("'").append(ids.get(i)).append("'");
if(i<ids.size() - 1){
sql.append(",");
}
}
sql.append(")");
return sql.toString();
}
}
}
编写Service
import cn.peak.common.core.base.BaseResponse;
import cn.peak.entity.DO.OrgDo;
import cn.peak.entity.DTO.OrgDto;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
import java.util.Map;
/**
* @author jql
* @InterfaceName: OrgService
* @Description: 组织信息接口
* @date 2019/12/9 17:17
*/
@Api(tags = "组织信息接口")
@RequestMapping("/baseOrg")
public interface OrgService {
/**
* @Title: queryOrgZTree
* @Description: 根据父id信息,查询组织信息
* @param fatherId 父id
* @return cn.peak.common.core.base.BaseResponse<cn.peak.entity.DO.OrgDo>
* @date 2019/12/9 17:27
* @throws
*/
@PostMapping(value = "/queryOrgZTree")
@ApiOperation(value = "获取菜单树(组织菜单)")
BaseResponse<List<Map<String,Object>>> queryOrgZTree(String fatherId);
/**
* @Title: addOrg
* @Description: 添加组织结构信息
* @param orgDto 组织信息实体类
* @return cn.peak.common.core.base.BaseResponse<com.alibaba.fastjson.JSONObject>
* @date 2019/12/9 17:27
* @throws
*/
@PostMapping(value = "/addOrg")
@ApiOperation(value = "添加组织信息")
BaseResponse<JSONObject> addOrg(OrgDto orgDto);
/**
* @Title: saveOrg
* @Description: 根据id,修改机构组织
* @param orgDto 组织实体类
* @return cn.peak.common.core.base.BaseResponse<com.alibaba.fastjson.JSONObject>
* @date 2019/12/9 17:28
* @throws
*/
@PostMapping(value = "/saveOrg")
@ApiOperation(value = "根据id,修改组织信息")
BaseResponse<JSONObject> saveOrg(OrgDto orgDto);
/**
* @Title: removeOrg
* @Description: 根据id删除机构组织
* @param id 要删除的id,如果id为父节点,会把子节点一并删除
* @return cn.peak.common.core.base.BaseResponse<com.alibaba.fastjson.JSONObject>
* @date 2019/12/9 17:29
* @throws
*/
@PostMapping(value = "/removeOrg")
@ApiOperation(value = "根据ids删除组织信息")
BaseResponse<JSONObject> removeOrg(String id);
}
编写Impl
import cn.peak.common.core.base.BaseApiService;
import cn.peak.common.core.base.BaseResponse;
import cn.peak.common.core.utils.DoDtoUtils;
import cn.peak.entity.DO.OrgDo;
import cn.peak.entity.DTO.OrgDto;
import cn.peak.mapper.resources.OrgMapper;
import cn.peak.service.api.resources.OrgService;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* @author jql
* @ClassName: OrgServiceImpl
* @Description: 组织实现类
* @date 2019/12/10 8:59
*/
@RestController
@Slf4j
public class OrgServiceImpl implements OrgService {
@Autowired
private OrgMapper orgMapper;
@Override
public BaseResponse<List<Map<String,Object>>> queryOrgZTree(String fatherId) {
if(StringUtils.isEmpty(fatherId)){
return BaseApiService.setResultError("父id不能为空!");
}
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
//查询出所有根节点
List<Map<String, Object>> mapList = orgMapper.selectOrgBypId(fatherId);
//遍历根节点,查询根节点下的子节点
for (Map<String, Object> map : mapList) {
//利用递归,实现查询出所有子节点
List<Map<String, Object>> children = queryOrgZTree(map.get("org_id").toString()).getData();
if(children.size()>0){
map.put("children",children);
}
list.add(map);
}
return BaseApiService.setResultSuccess(list);
}
@Override
public BaseResponse<JSONObject> addOrg(OrgDto orgDto) {
if(orgDto == null){
return BaseApiService.setResultError("没有要添加的数据!");
}
if(StringUtils.isEmpty(orgDto.getPId())){
return BaseApiService.setResultError("父id不能为空!");
}
orgDto.setOrgId(UUID.randomUUID().toString().replace("-", ""));
try {
OrgDo orgDo = DoDtoUtils.doToDto(orgDto, OrgDo.class);
int i = orgMapper.insertOrg(orgDo);
if(i>0){
return BaseApiService.setResultSuccess("添加成功!");
}
return BaseApiService.setResultError("添加失败!");
}catch (Exception e){
log.info("添加组织信息失败:");
StackTraceElement[] stackTrace = e.getStackTrace();
for (StackTraceElement stackTraceElement : stackTrace) {
log.info(stackTraceElement.toString());
}
return BaseApiService.setResultError("添加失败!");
}
}
@Override
public BaseResponse<JSONObject> saveOrg(OrgDto orgDto) {
if(StringUtils.isEmpty(orgDto.getOrgId())){
return BaseApiService.setResultError("组织id不能为空!");
}
OrgDo orgDo = DoDtoUtils.dtoToDo(orgDto, OrgDo.class);
try {
int i = orgMapper.updateOrg(orgDo);
if(i>0){
return BaseApiService.setResultSuccess("修改成功!");
}
return BaseApiService.setResultError("修改失败!");
}catch (Exception e){
log.info("修改组织信息失败,组织id为:"+orgDo.getOrgId());
StackTraceElement[] stackTrace = e.getStackTrace();
for (StackTraceElement stackTraceElement : stackTrace) {
log.info(stackTraceElement.toString());
}
return BaseApiService.setResultError("修改失败!");
}
}
@Override
public BaseResponse<JSONObject> removeOrg(String id) {
if(StringUtils.isEmpty(id)){
return BaseApiService.setResultError("组织id不能为空!");
}
List<String> ids = new ArrayList<String>();
ids.add(id);
ids = getDeleteIds(id,ids);
try {
int i = orgMapper.deleteOrg(ids);
if(i>0){
return BaseApiService.setResultSuccess("删除成功!");
}
return BaseApiService.setResultError("删除失败!");
}catch (Exception e){
log.info("删除组织信息失败,组织id为:"+ids);
log.info(e.getStackTrace()+"");
return BaseApiService.setResultError("删除失败!");
}
}
public List<String> getDeleteIds(String id, List<String> list){
List<Map<String, Object>> mapList = orgMapper.selectOrgBypId(id);
for (Map<String, Object> map : mapList) {
list.add(map.get("org_id").toString());
getDeleteIds(map.get("org_id").toString(),list);
}
return list;
}
}