IDEA 自动生成Mapper

还在为数据表太多而烦恼吗?
No, 我要偷懒, 让其自动创建。
了解到 maven 有插件可以生成mapper, 但那不是我想要的,我想要的是 @注解方式
通过数据表实体自动创建 我从中得到了启发,那就是 拼接字符串并生成文件,正好可以获取数据表与字段信息
自动生成流程

菜单

首先选择要添加的表,一个或多个, 右键-Scripted Extensions 就有一个脚本选择菜单
从中选择 Generator MyMappers.groovy
在这里插入图片描述

选择实体类的目录

在这里插入图片描述

选择存放mapper的目录

在这里插入图片描述

代码生成完成

package c.test.demo.mapper;
import org.apache.ibatis.annotations.*;
import java.sql.Timestamp;
import c.test.demo.entry.User;
/**
 * 由Groovy自动生成 
 * <p>Date: 2019/11/28 下午2:03.</p>
 * Description: null
 * @see User
 * @author Mr.Wang
 */
@Mapper
@CacheNamespace
public interface UserMapper {
	/**
	 * 添加记录
	 * @param user 要插入的对象,包含必要信息
	 */
	@Insert("insert into user(id,username,password,sex,birthday) value (#{id},#{username},#{password},#{sex},#{birthday})")
	@Options(useGeneratedKeys = true, keyProperty = "id")
	void addUser(User user);

	/**
	 * 删除记录
	 * @param id 【主键】
	 * @return true/false 是否有记录被修改
	 */
	@Delete("delete from user where id = #{id}")
	boolean deleteUserById(Integer id);
	/**
	 * 修改参数对象中主键字段对应的记录
	 * @param user 要修改的对象,此对象应该是被查询的对象,并且必须包含主键
	 * @return true/false 是否有记录被修改
	 */
	@Update("update user set id=#{id},username=#{username},password=#{password},sex=#{sex},birthday=#{birthday} where id = #{id}")
	boolean updateUser(User user);

	/**
	 * 修改字段 username
	 * @param id 
	 * @param username 
	 * @return true/false 是否有记录被修改
	 */
	@Update("update user set username=#{username} where id = #{id}")
	boolean updateFieldUsername(@Param("id") Integer id,@Param("username") String username);

	/**
	 * 修改字段 password
	 * @param id 
	 * @param password 
	 * @return true/false 是否有记录被修改
	 */
	@Update("update user set password=#{password} where id = #{id}")
	boolean updateFieldPassword(@Param("id") Integer id,@Param("password") String password);

	/**
	 * 修改字段 sex
	 * @param id 
	 * @param sex 
	 * @return true/false 是否有记录被修改
	 */
	@Update("update user set sex=#{sex} where id = #{id}")
	boolean updateFieldSex(@Param("id") Integer id,@Param("sex") Boolean sex);

	/**
	 * 修改字段 birthday
	 * @param id 
	 * @param birthday 
	 * @return true/false 是否有记录被修改
	 */
	@Update("update user set birthday=#{birthday} where id = #{id}")
	boolean updateFieldBirthday(@Param("id") Integer id,@Param("birthday") Timestamp birthday);

	/**
	 * 通过主键 id查询
	 * @param id 【主键】
	 * @return object or null
	 */
	@Select("select * from user where id = #{id}")
	User getUser(Integer id);
}

阐述

生成的要点:

  1. 没试过复合主键表
  2. 有主键或无主键都可
  3. 无主键的将只有 查找所有和修改所有方法,以及单个字段的修改
  4. 有主键的将有 增删改查, 以及每个字段的修改方法(以主键为条件)
  5. 即使添加方法写了主键也无影响

Generator MyMappers.groovy

参考第一张图, 选择 “Go to Scripts Directory” 跳转到脚本目录, 将文件放入其中就可以选择.

或者在目录 C:\Users\用户名.IntelliJIdea~\config\extensions\com.intellij.database\schema 文件夹

import com.intellij.database.model.DasTable
import com.intellij.database.util.Case
import com.intellij.database.util.DasUtil

import java.text.SimpleDateFormat

/*
 * Available context bindings:
 *   SELECTION   Iterable<DasObject>
 *   PROJECT     project
 *   FILES       files helper
 */

packageName = ""
etityPackageName = ""
tableComment = ""
hasPrimaryKey = false
typeMapping = [
        (~/(?i)int/)                      : "Integer",
        (~/(?i)float|double|decimal|real/): "Double",
        (~/(?i)datetime|timestamp/)       : "Timestamp",
        (~/(?i)date/)                     : "Date",
        (~/(?i)time/)                     : "java.sql.Time",
        (~/(?i)bit/)                      : "Boolean",
        (~/(?i)/)                         : "String"
]
//选择实体类包路径,选择的包路径,用于添加import包语句.
FILES.chooseDirectoryAndSave(unicodeToString("\\u9009\\u62e9\\u5b9e\\u4f53\\u7c7b\\u5305\\u8def\\u5f84")
        , unicodeToString("\\u9009\\u62e9\\u7684\\u5305\\u8def\\u5f84\\u002c\\u7528\\u4e8e\\u6dfb\\u52a0\\u0069\\u006d\\u0070\\u006f\\u0072\\u0074\\u5305\\u8bed\\u53e5\\u002e")) { dir ->
  generate(dir)
}
//选择Mapper存放的包路径,选择的目录将生成Mapper文件
FILES.chooseDirectoryAndSave(unicodeToString("\\u9009\\u62e9\\u004d\\u0061\\u0070\\u0070\\u0065\\u0072\\u5b58\\u653e\\u7684\\u5305\\u8def\\u5f84")
        , unicodeToString("\\u9009\\u62e9\\u7684\\u76ee\\u5f55\\u5c06\\u751f\\u6210\\u004d\\u0061\\u0070\\u0070\\u0065\\u0072\\u6587\\u4ef6")) { dir ->
  SELECTION.filter { it instanceof DasTable }.each { generate(it, dir) }
}
def generate(dir){
  etityPackageName = dir.toString().replaceAll("\\\\", ".").replaceAll("/", ".").replaceAll("^.*src(\\.main\\.java\\.)?", "")
}
def generate(table, dir) {
  def className = javaName(table.getName(), true)
  def tableName = table.getName()
  def fields = calcFields(table)
  packageName = getPackageName(dir)
  //文件名的拼接
  PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(new File(dir, className + "Mapper.java")), "UTF-8"))
  printWriter.withPrintWriter {out -> generate(out, className, tableName, fields)}
}

// 获取包所在文件夹路径
def getPackageName(dir) {
  return (dir.toString().replaceAll("\\\\", ".").replaceAll("/", ".").replaceAll("^.*src(\\.main\\.java\\.)?", "") + ";");//.substring(1)
}

def generate(out, className, tableName, fields) {
  out.println "package $packageName"
  out.println "import org.apache.ibatis.annotations.*;"
  Set types = new HashSet()
  fields.each() {
    types.add(it.type)
  }
  if (types.contains("Timestamp")) {
    out.println "import java.sql.Timestamp;"
  }
  if (types.contains("Date")) {
    out.println "import java.util.Date;"
  }
  out.println "import $etityPackageName.${className};"
  out.println "/**"
  Locale.setDefault(Locale.CHINA)
  sdf = new SimpleDateFormat()
  //由Groovy自动生成
  out.println " * ${unicodeToString('\\u7531\\u0047\\u0072\\u006f\\u006f\\u0076\\u0079\\u81ea\\u52a8\\u751f\\u6210')} "
  out.println " * <p>Date: " + sdf.format(new java.util.Date()) + ".</p>"
  out.println " * Description: $tableComment"
  out.println " * @see $className"
  out.println " * @author Mr.Wang"
  out.println " */"
  out.println "@Mapper"
  out.println "@CacheNamespace"
  out.println "public interface ${className}Mapper {"
  //如果没有主键的表 则
  if(!hasPrimaryKey){
    //查找
    out.println "\t/**"
    //查找所有记录
    out.println "\t * " + unicodeToString("\\u67e5\\u627e\\u6240\\u6709\\u8bb0\\u5f55")
    out.println "\t * @return object or null"
    out.println "\t */"
    out.println "\t@Select(\"select * from $tableName\")"
    out.println "\t$className find$className();"
    out.println ""
    //修改
    out.println "\t/**"
    //修改对象属性对应的所有字段
    out.println "\t * " + unicodeToString("\\u4fee\\u6539\\u5bf9\\u8c61\\u5c5e\\u6027\\u5bf9\\u5e94\\u7684\\u6240\\u6709\\u5b57\\u6bb5")
    //要修改的对象,此对象应该是经过查询的对象
    out.println "\t * @param ${javaName(className, false)} " + unicodeToString("\\u8981\\u4fee\\u6539\\u7684\\u5bf9\\u8c61\\uff0c\\u6b64\\u5bf9\\u8c61\\u5e94\\u8be5\\u662f\\u7ecf\\u8fc7\\u67e5\\u8be2\\u7684\\u5bf9\\u8c61")
    //是否有记录被修改
    out.println "\t * @return true/false " + unicodeToString("\\u662f\\u5426\\u6709\\u8bb0\\u5f55\\u88ab\\u4fee\\u6539")
    out.println "\t */"
    out.print "\t@Update(\"update $tableName "
    first = true
    fields.each(){
      if(first){
        out.print "set ${it.colName}=#{${it.name}}"
        first = false
      } else out.print ",${it.colName}=#{${it.name}}"
    }
    out.println "\")"
    //********此处根据需要而定, 如果修改超过一条记录 因改为 int , 同理 删除的地方也是************//
    out.println "\tboolean update$className($className ${javaName(className, false)});"
    //单字段修改
    out.println ""
    fields.each(){
      out.println "\t/**"
      //修改字段
      out.println "\t * ${unicodeToString('\\u4fee\\u6539\\u5b57\\u6bb5')} ${it.name}"
      out.println "\t * @param ${it.name} ${it.comment}"
      //是否有记录被修改
      out.println "\t * @return true/false " + unicodeToString("\\u662f\\u5426\\u6709\\u8bb0\\u5f55\\u88ab\\u4fee\\u6539")
      out.println "\t */"
      out.println "\t@Update(\"update $tableName set ${it.colName}=#{${it.name}}\")"
      out.println "\tboolean updateFiled${javaName(it.name,true)}(${it.type} ${it.name});"
      out.println ""
    }
    out.println "}"

    return
  }
  boolean first = false//判断是否为循环第一次,用于控制输出","等
  //获取主键信息
  def pk = [:]
  fields.each() {
    if(it.isPk) {
      pk.put("name", it.name)
      pk.put("colName", it.colName)
      pk.put("type", it.type)
      pk.put("comment", it.comment)
    }
    return false
  }
  //增
  out.println "\t/**"
  //添加记录
  out.println "\t * " + unicodeToString("\\u6dfb\\u52a0\\u8bb0\\u5f55")
  //要插入的对象,包含必要信息
  out.println "\t * @param ${javaName(className, false)} " + unicodeToString("\\u8981\\u63d2\\u5165\\u7684\\u5bf9\\u8c61\\u002c\\u5305\\u542b\\u5fc5\\u8981\\u4fe1\\u606f")
  out.println "\t */"
  out.print "\t@Insert(\"insert into $tableName("
  first = true
  fields.each(){
    if(first){
      out.print "${it.colName}"
      first = false
    } else out.print ",${it.colName}"
  }
  out.print ") values ("
  first = true
  fields.each(){
    if(first){
      out.print "#{${it.name}}"
      first = false
    } else out.print ",#{${it.name}}"
  }
  out.println ")\")"
  //是否需要将自动生成的键设置到对象中
  out.println "\t@Options(useGeneratedKeys = true, keyProperty = \"${pk.name}\")"
  out.println "\tvoid add$className($className ${javaName(className, false)});"
  out.println ""

  //删 @Delete("delete from admin_role where id = #{roleId}")
  out.println "\t/**"
  //删除记录
  out.println "\t * " + unicodeToString("\\u5220\\u9664\\u8bb0\\u5f55")
  //【主键】
  out.println "\t * @param ${pk.name} ${pk.comment}" + unicodeToString("\\u3010\\u4e3b\\u952e\\u3011")
  //是否有记录被修改
  out.println "\t * @return true/false " + unicodeToString("\\u662f\\u5426\\u6709\\u8bb0\\u5f55\\u88ab\\u4fee\\u6539")
  out.println "\t */"
  out.println "\t@Delete(\"delete from $tableName where ${pk.colName} = #{${pk.name}}\")"
  out.println "\tboolean delete${className}ById(${pk.type} ${pk.name});"

  //改
  out.println "\t/**"
  //修改参数对象中主键字段对应的记录
  out.println "\t * " + unicodeToString("\\u4fee\\u6539\\u53c2\\u6570\\u5bf9\\u8c61\\u4e2d\\u4e3b\\u952e\\u5b57\\u6bb5\\u5bf9\\u5e94\\u7684\\u8bb0\\u5f55")
  //要修改的对象,此对象应该是被查询的对象,并且必须包含主键
  out.println "\t * @param ${javaName(className, false)} " + unicodeToString("\\u8981\\u4fee\\u6539\\u7684\\u5bf9\\u8c61\\uff0c\\u6b64\\u5bf9\\u8c61\\u5e94\\u8be5\\u662f\\u88ab\\u67e5\\u8be2\\u7684\\u5bf9\\u8c61\\uff0c\\u5e76\\u4e14\\u5fc5\\u987b\\u5305\\u542b\\u4e3b\\u952e")
  //是否有记录被修改
  out.println "\t * @return true/false " + unicodeToString("\\u662f\\u5426\\u6709\\u8bb0\\u5f55\\u88ab\\u4fee\\u6539")
  out.println "\t */"
  out.print "\t@Update(\"update $tableName "
  first = true
  fields.each(){
    if(first){
      out.print "set ${it.colName}=#{${it.name}}"
      first = false
    } else out.print ",${it.colName}=#{${it.name}}"
  }
  out.println " where ${pk.colName} = #{${pk.name}}\")"
  out.println "\tboolean update$className($className ${javaName(className, false)});"
  out.println ""
  //单字段修改
  fields.each(){
    if(it.isPk) return //主键跳过
    out.println "\t/**"
    //修改字段
    out.println "\t * ${unicodeToString('\\u4fee\\u6539\\u5b57\\u6bb5')} ${it.name}"
    out.println "\t * @param ${pk.name} ${pk.comment}"
    out.println "\t * @param ${it.name} ${it.comment}"
    //是否有记录被修改
    out.println "\t * @return true/false " + unicodeToString("\\u662f\\u5426\\u6709\\u8bb0\\u5f55\\u88ab\\u4fee\\u6539")
    out.println "\t */"
    out.println "\t@Update(\"update $tableName set ${it.colName}=#{${it.name}} where ${pk.colName} = #{${pk.name}}\")"
    out.println "\tboolean updateField${javaName(it.name,true)}(@Param(\"${pk.name}\") ${pk.type} ${pk.name},@Param(\"${it.name}\") ${it.type} ${it.name});"
    out.println ""
  }
  //查
  out.println "\t/**"
  //通过主键 ${pk.name} 查询
  out.println "\t * ${unicodeToString('\\u901a\\u8fc7\\u4e3b\\u952e')} ${pk.name}" + unicodeToString("\\u67e5\\u8be2")
  out.println "\t * @param ${pk.name} ${pk.comment}" + unicodeToString("\\u3010\\u4e3b\\u952e\\u3011")
  out.println "\t * @return object or null"
  out.println "\t */"
  out.println "\t@Select(\"select * from $tableName where ${pk.colName} = #{${pk.name}}\")"
  out.println "\t$className get$className(${pk.type} ${pk.name});"
  //类结束
  out.println "}"
}

def calcFields(table) {
  hasPrimaryKey = DasUtil.getPrimaryKey(table) == null ? false : true
  tableComment = table.getComment()
  DasUtil.getColumns(table).reduce([]) { fields, col ->
    def spec = Case.LOWER.apply(col.getDataType().getSpecification())
    def typeStr = typeMapping.find { p, t -> p.matcher(spec).find() }.value
    fields += [
            colName : col.getName(),
            name :  javaName(col.getName(), false),
            type : typeStr,
            comment: getComment(col.getComment()),
            isPk : DasUtil.isPrimary(col),
            isFk : DasUtil.isIndexColumn(col)
    ]
  }
}

def javaName(str, capitalize) {
  def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
          .collect { Case.LOWER.apply(it).capitalize() }
          .join("")
          .replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_")
  capitalize || s.length() == 1? s : Case.LOWER.apply(s[0]) + s[1..-1]
}

def isNotEmpty(content) {
  return content != null && content.toString().trim().length() > 0
}
//获取注释
def getComment(comment){
  if (isNotEmpty(comment)) {
    return comment.toString()
  }
  return ""
}
/**
 * unicode转字符串
 * 用于 文件注释,由于 groovy 编译器不支持中文
 * @param unicode 编码为Unicode的字符串
 * @return 解码字符串
 */
def String unicodeToString(String unicode) {
  StringBuffer sb = new StringBuffer();
  String[] hex = unicode.split("\\\\u");
  for (int i = 1; i < hex.length; i++) {
    int index = Integer.parseInt(hex[i], 16);
    sb.append((char) index);
  }
  return sb.toString();
}


至于为何用Unicode, 因为用中文乱码! 我也找不到怎么配置Groovy编译器编码, 以上

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值