当前位置: 代码网 > it编程>编程语言>Java > IDEA如何自动生成Mapper

IDEA如何自动生成Mapper

2026年03月11日 Java 我要评论
还在为数据表太多而烦恼吗?no, 我要偷懒, 让其自动创建。了解到 maven 有插件可以生成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);
}

阐述

生成的要点:

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

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编译器编码, 以上

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。 

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com