# 编译&运行插件

# 编译时能力

基于java apt能力开发的代码在编译期自动生成字节码的能力,具体能力如下:

# Dao自动生成:

根据实体定义自动生成增删改查方法,包括以下方法,可以通过配置指定或者排除部分方法生成

  • get("取得详情"),
  • getStatus("查询状态"),
  • insert("新增"),
  • insertBatch("批量新增"),
  • delete("删除"),
  • update("更新"),
  • deleteBatch("批量删除"),
  • updateStatus("更新状态"),
  • updateStatusBatch("批量修改状态");
@Mapper(value = UserEntity.class)
public interface UserDao {    
 }

加上@Mapper注解后会自动生成以上几个方法, 其中getStatus和updateStatus及updateStatusBatch需要在实体中定义状态字段后才会生成

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(value = "sys_user", comment = "用户表")
public class UserEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id(type = IdType.auto)
    @Column(value = "id")
    private String id;
    @Column(value = "name", meaning = Meaning.name)
    private String name;
    @Column(value = "nick_name")
    private String nickName;
    @Column(value = "account")
    private String account;
    @Column(value = "org_id")
    private String orgId;
    @Column(value = "password")
    private String password;
    @Column(value = "sex")
    private String sex;
    @Column(value = "birthday")
    private Date birthday;
    @Column(value = "id_card")
    private String idCard;
    @Column(value = "email")
    private String email;
    @Column(value = "mobile")
    private String mobile;
    @Column(value = "emp_no")
    private String empNo;
    @Column(value = "professional_posts")
    private String professionalPosts;
    @Column(value = "origin")
    private String origin;
    @Column(value = "first_landing")
    private Integer firstLanding;
    @Column(value = "password_expire_date")
    private Date passwordExpireDate;
    @Column(value = "expire_date")
    private Date expireDate;
    @Column(value = "locked_time")
    private Date lockedTime;
    @Column(value = "avatar_url")
    private String avatarUrl;
    @Column(value = "status", meaning = Meaning.status, defaultValue = "1")
    private String status;
    @Column(value = "is_deleted", meaning = Meaning.isDeleted, defaultValue = "0")
    private String isDeleted;
    @Column(value = "creator", meaning = Meaning.creator)
    private String creator;
    @Column(value = "creator_name", meaning = Meaning.creatorName)
    private String creatorName;
    @Column(value = "create_time", meaning = Meaning.createTime)
    private Date createTime;
    @Column(value = "modified_time", meaning = Meaning.modifiedTime)
    private Date modifiedTime; 
  }

# SQLMAP自动生成

以上自动生成的接口方法,MyBatis的SQLMap自动生成,位置在编译目录包下的[dao]_auto.xml文件中

# controller注解自动暴露

通过注解自动生成controller方法,多方法自动生成参数对象

@Expose(value = "/user", name = "用户管理", description = "用户管理", tags = {"用户管理", "测试用户"})
public interface UserService {

    @ExposeMapping(name = "新增用户", description = "新增用户")
    String insert(UserDTO userDTO);

    @ExposeMapping(name = "更改机构状态", description = "更改机构状态")
    String updateStatus(String id, String status);
  }

自动生成的controller代码:

import cn.techhawk.codes.coffee.result.SingleResult;
import cn.techhawk.codes.tester.dto.UserDTO;
import cn.techhawk.codes.tester.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.lang.String;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/user")
@RestController
@Api(value = "用户管理", description = "用户管理", tags = {"用户管理","测试用户"})
public class UserController {
  @Autowired
  private UserService userService;

  @RequestMapping(value = {"/insert"}, method = RequestMethod.POST)
  @ApiOperation(value = "新增用户", notes = "新增用户")
  public SingleResult<String> insert(@RequestBody UserDTO userDTO) {
    String result= userService.insert(userDTO);
    return new SingleResult<>(result);
  }

  @RequestMapping(value = {"/updateStatus"}, method = RequestMethod.POST)
  @ApiOperation(value = "更改机构状态", notes = "更改机构状态")
  public SingleResult<String> updateStatus(@RequestBody UpdateStatusFO updateStatusFO) {
    String result= userService.updateStatus(updateStatusFO.id,updateStatusFO.status);
    return new SingleResult<>(result);
  }

  @Getter
  @Setter
  public static class UpdateStatusFO {
    private String id;

    private String status;
  }
}

# 逻辑方法自动生成

通过注解自动生成简单调用方法,比如:分层简单调用。

@CreateMethod(value = UserDao.class)
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
}

通过注解@CreateMethod识别要自动生成,要调用的下级接口,实际生成的代码如下:(反编译)

import cn.techhawk.codes.coffee.transform.ObjectTransformer;
import cn.techhawk.codes.tester.dao.UserDao;
import cn.techhawk.codes.tester.dto.UserDTO;
import cn.techhawk.codes.tester.entity.UserEntity;
import cn.techhawk.codes.tester.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Transactional
    public String insert(UserDTO userDTO) {
        UserEntity _param = (UserEntity)ObjectTransformer.transform(userDTO, UserEntity.class);
        this.userDao.insert(_param);
        return _param.getId();
    }

    @Transactional
    public String updateStatus(String id, String status) {
        return null;
    }

    public UserServiceImpl() {
    }
}

# 逻辑删除支持

根据模型定义自动判断数据删除方式,生成逻辑删除或物理删除SQL语句。 根据模型定义自动拼接逻辑删除条件减少人工操作。

<select id="getStatus" resultType="java.lang.String">
 select status from sys_user 
 where id=#{id}
 AND is_deleted = 0
</select>

# 单表操作注解设置

  • 自动解析结果模型提取固定字段
  • 自动解析参数模型提取SQL条件(支持opendoc定义解析和参数自动映射)
  • 自动生成SQLMap片段。
@Mapper(value = UserEntity.class)
public interface UserDao {
    @Query(value = {@Condition("account"), @Condition(value = "status", param = "statuses")})
    Page<UserEntity> findUsers(UserQueryDo queryDo);

    @Query(value = {@Condition(value = "status", placeholder = "'1'")})
    Page<UserEntity> findUsers1();
    
    @Delete(value = {@Condition("account"), @Condition(value = "status", param = "statuses")})
    int deleteByAccount(String account, List<String> statuses);
 
    @Update(fields = "account", value = @Condition(value = "status", param = "statuses"), deletedIgnored = true)
    int updateByAccount(String account, List<String> statuses);
 
    @Update(fields = "account", value = @Condition(value = "status", param = "statuses"))
    int updateByStatuses(UserQueryDo updateDo);
 }

生成的SQL

<select id="findUsers" resultMap="_X_AUTO_UserEntityMap">
        SELECT
        id id,name name,nick_name nickName,account account,org_id orgId,password password,sex sex,birthday
        birthday,id_card idCard,email email,mobile mobile,emp_no empNo,professional_posts professionalPosts,origin
        origin,first_landing firstLanding,password_expire_date passwordExpireDate,expire_date expireDate,locked_time
        lockedTime,avatar_url avatarUrl,status status,is_deleted isDeleted,creator creator,creator_name
        creatorName,create_time createTime,modified_time modifiedTime
        FROM sys_user
        <where>
            account = #{queryDo.account} and status in
            <foreach collection="queryDo.statuses" item="item" open="(" close=")" separator=",">
                #{item}
            </foreach>
            AND is_deleted = 0
        </where>
    </select>
    <select id="findUsers1" resultMap="_X_AUTO_UserEntityMap">
        SELECT
        id id,name name,nick_name nickName,account account,org_id orgId,password password,sex sex,birthday
        birthday,id_card idCard,email email,mobile mobile,emp_no empNo,professional_posts professionalPosts,origin
        origin,first_landing firstLanding,password_expire_date passwordExpireDate,expire_date expireDate,locked_time
        lockedTime,avatar_url avatarUrl,status status,is_deleted isDeleted,creator creator,creator_name
        creatorName,create_time createTime,modified_time modifiedTime
        FROM sys_user
        <where>
            status = '1'
            AND is_deleted = 0
        </where>
    </select>
    <resultMap id="_X_AUTO_UserDTOMap" type="cn.techhawk.codes.tester.dto.UserDTO">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="nickName" property="nickName"/>
        <result column="account" property="account"/>
        <result column="orgId" property="orgId"/>
        <result column="password" property="password"/>
        <result column="sex" property="sex"/>
        <result column="birthday" property="birthday"/>
        <result column="idCard" property="idCard"/>
        <result column="email" property="email"/>
    </resultMap>
    <select id="findUsers2" resultMap="_X_AUTO_UserDTOMap">
        SELECT
        id id,name name,nick_name nickName,account account,org_id orgId,password password,sex sex,birthday
        birthday,id_card idCard,email email
        FROM sys_user
        <where>
            account = #{account} and status = #{status}
        </where>
    </select>
    <update id="deleteByAccount">
        UPDATE sys_user SET is_deleted=1,modified_time=now()
        <where>
            account = #{account} and status in
            <foreach collection="statuses" item="item" open="(" close=")" separator=",">
                #{item}
            </foreach>
            AND is_deleted = 0
        </where>
    </update>
    <update id="updateByAccount">
        UPDATE sys_user
        <set>
            ,account=#{account}
            , modified_time=now()
        </set>
        <where>
            status in
            <foreach collection="statuses" item="item" open="(" close=")" separator=",">
                #{item}
            </foreach>
        </where>
    </update>
    <update id="updateByStatuses">
        UPDATE sys_user
        <set>
            ,account=#{updateDo.account}
            , modified_time=now()
        </set>
        <where>
            status in
            <foreach collection="updateDo.statuses" item="item" open="(" close=")" separator=",">
                #{item}
            </foreach>
            AND is_deleted = 0
        </where>
    </update>

# 运行时能力

# 逻辑删除支持

手动编写的SQL,如果表实体定义了逻辑删除字段,则会自动拼接逻辑删除条件

# 数据权限

支持数据权限机制,自动拼接数据SQL条件和设置参数。

# 数据防篡改

对于余额等敏感数据,支持数据防篡改计算和自动检测。

# 数据自动填充

对于Id、创建人、创建时间、修改时间、拼音码等支持自动数据填充,减少编码操作。