前言

  我们在之前的实现了springboot与data-jpa的增、删、改、查简单使用(请戳:SpringBoot系列——Spring-Data-JPA),并实现了升级版(请戳:SpringBoot系列——Spring-Data-JPA(升级版)),在基础版、升级版中,我们实现了单表的基础get、save(插入/更新)、list、page、delete接口,并写了一套通用common代码,每个单表去继承从而实现这套基础接口、同时,我们使用用Vo去接收、传输数据,实体负责与数据库表映射。

  但是,单表增、删、改、查基础功能相似,代码高度相似,我们新增一个单表操作的步骤:复制、粘贴、修改文件夹、文件名、类名、修改传参实体对象...,为了实现快速开发,我们在前面两个版本的基础上,使用代码自动生成一套单表的基础增、删、改、查接口

  代码编写

  首先我们先创建一个新的工程项目,实现一套common代码,以便单表直接继承

  CodeDOM.java是一个比较大的类,因为我把所有的东西都丢在了里面...,接下来我们拆分讲解一下步骤(文末贴出CodeDOM.java完整代码)

  首先定义几个属性,构造函数传入表名,基础路径基于表名进行赋值

  1. /**
  2. * 表名
  3. */
  4. private String tableName;
  5.  
  6. /**
  7. * 基础路径
  8. */
  9. private String basePackage_;
  10. private String package_;
  11. private String basePath;

  构造函数

  1. /**
  2. * 构造参数,出入表名
  3. */
  4. private CodeDOM(String tableName) {
  5. this.tableName = tableName;
  6. basePackage_ = "cn\\huanzi\\springbootjpa\\";
  7. package_ = basePackage_ + StringUtil.camelCaseName(tableName).toLowerCase() + "\\";
  8. //System.getProperty("user.dir") 获取的是项目所在路径,如果我们是子项目,则需要添加一层路径
  9. basePath = System.getProperty("user.dir") + "\\src\\main\\java\\" + package_;
  10. }

  查询表信息

  首先要连接数据库,连接数据使用jdbc进行连接

  1. /**
  2. * 数据连接相关
  3. */
  4. private static final String URL = "jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8&characterEncoding=utf-8";
  5. private static final String USERNAME = "root";
  6. private static final String PASSWORD = "123456";
  7. private static final String DRIVERCLASSNAME = "com.mysql.jdbc.Driver";
  1. /**
  2. * JDBC连接数据库工具类
  3. */
  4. private static class DBConnectionUtil {
  5.  
  6. static {
  7. // 1、加载驱动
  8. try {
  9. Class.forName(DRIVERCLASSNAME);
  10. } catch (ClassNotFoundException e) {
  11. e.printStackTrace();
  12. }
  13. }
  14.  
  15. /**
  16. * 返回一个Connection连接
  17. *
  18. * @return
  19. */
  20. public static Connection getConnection() {
  21. Connection conn = null;
  22. // 2、连接数据库
  23. try {
  24. conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
  25. } catch (SQLException e) {
  26. e.printStackTrace();
  27. }
  28. return conn;
  29. }
  30.  
  31. /**
  32. * 关闭Connection,Statement连接
  33. *
  34. * @param conn
  35. * @param stmt
  36. */
  37. public static void close(Connection conn, Statement stmt) {
  38. try {
  39. conn.close();
  40. stmt.close();
  41. } catch (SQLException e) {
  42. e.printStackTrace();
  43. }
  44. }
  45.  
  46. /**
  47. * 关闭Connection,Statement,ResultSet连接
  48. *
  49. * @param conn
  50. * @param stmt
  51. * @param rs
  52. */
  53. public static void close(Connection conn, Statement stmt, ResultSet rs) {
  54. try {
  55. close(conn, stmt);
  56. rs.close();
  57. } catch (SQLException e) {
  58. e.printStackTrace();
  59. }
  60. }
  61.  
  62. }

  获取数据表的表机构信息(本系列用的是MySQL数据库),通过查询 information_schema 表,SQL:

  1. select column_name,data_type,column_comment,column_key,extra from information_schema.columns where table_name=?

  创建一个表结构对象,然后封装一下方法:

  1. /**
  2. * 表结构行信息实体类
  3. */
  4. private class TableInfo {
  5. private String columnName;
  6. private String dataType;
  7. private String columnComment;
  8. private String columnKey;
  9. private String extra;
  10.  
  11. TableInfo() {
  12. }
  13.  
  14. String getColumnName() {
  15. return columnName;
  16. }
  17.  
  18. void setColumnName(String columnName) {
  19. this.columnName = columnName;
  20. }
  21.  
  22. String getDataType() {
  23. return dataType;
  24. }
  25.  
  26. void setDataType(String dataType) {
  27. this.dataType = dataType;
  28. }
  29.  
  30. String getColumnComment() {
  31. return columnComment;
  32. }
  33.  
  34. void setColumnComment(String columnComment) {
  35. this.columnComment = columnComment;
  36. }
  37.  
  38. String getColumnKey() {
  39. return columnKey;
  40. }
  41.  
  42. void setColumnKey(String columnKey) {
  43. this.columnKey = columnKey;
  44. }
  45.  
  46. String getExtra() {
  47. return extra;
  48. }
  49.  
  50. void setExtra(String extra) {
  51. this.extra = extra;
  52. }
  53. }
  1. /**
  2. * 获取表结构信息
  3. *
  4. * @return list
  5. */
  6. private List<TableInfo> getTableInfo() {
  7. Connection conn = null;
  8. PreparedStatement ps = null;
  9. ResultSet rs = null;
  10. ArrayList<TableInfo> list = new ArrayList<>();
  11. try {
  12. conn = DBConnectionUtil.getConnection();
  13. String sql = "select column_name,data_type,column_comment,column_key,extra from information_schema.columns where table_name=?";
  14. ps = conn.prepareStatement(sql);
  15. ps.setString(1, tableName);
  16. rs = ps.executeQuery();
  17. while (rs.next()) {
  18. TableInfo tableInfo = new TableInfo();
  19. //列名,全部转为小写
  20. tableInfo.setColumnName(rs.getString("column_name").toLowerCase());
  21. //列类型
  22. tableInfo.setDataType(rs.getString("data_type"));
  23. //列注释
  24. tableInfo.setColumnComment(rs.getString("column_comment"));
  25. //主键
  26. tableInfo.setColumnKey(rs.getString("column_key"));
  27. //主键类型
  28. tableInfo.setExtra(rs.getString("extra"));
  29. list.add(tableInfo);
  30. }
  31. } catch (SQLException e) {
  32. e.printStackTrace();
  33. } finally {
  34. assert rs != null;
  35. DBConnectionUtil.close(conn, ps, rs);
  36. }
  37. return list;
  38. }

  那么oracle应该怎么查呢?

  1. --表结构信息
  2. select * from user_tab_columns where table_name='TB_USER'
  3. --表字段注释
  4. select * from user_col_comments where table_name='TB_USER'
  5. --表注释
  6. select * from user_tab_comments where table_name='TB_USER'

  我们看一下系统都提供有哪些表,这...太多了

  数据处理

  数据处理,比如数据字段类型转成java类型、字段的下划线转驼峰等,我们封装一下工具类:

  1. /**
  2. * 字符串处理工具类
  3. */
  4. private static class StringUtil {
  5. /**
  6. * 数据库类型->JAVA类型
  7. *
  8. * @param dbType 数据库类型
  9. * @return JAVA类型
  10. */
  11. private static String typeMapping(String dbType) {
  12. String javaType = "";
  13. if ("int|integer".contains(dbType)) {
  14. javaType = "Integer";
  15. } else if ("float|double|decimal|real".contains(dbType)) {
  16. javaType = "Double";
  17. } else if ("date|time|datetime|timestamp".contains(dbType)) {
  18. javaType = "Date";
  19. } else {
  20. javaType = "String";
  21. }
  22. return javaType;
  23. }
  24.  
  25. /**
  26. * 驼峰转换为下划线
  27. */
  28. public static String underscoreName(String camelCaseName) {
  29. StringBuilder result = new StringBuilder();
  30. if (camelCaseName != null && camelCaseName.length() > 0) {
  31. result.append(camelCaseName.substring(0, 1).toLowerCase());
  32. for (int i = 1; i < camelCaseName.length(); i++) {
  33. char ch = camelCaseName.charAt(i);
  34. if (Character.isUpperCase(ch)) {
  35. result.append("_");
  36. result.append(Character.toLowerCase(ch));
  37. } else {
  38. result.append(ch);
  39. }
  40. }
  41. }
  42. return result.toString();
  43. }
  44.  
  45. /**
  46. * 首字母大写
  47. */
  48. public static String captureName(String name) {
  49. char[] cs = name.toCharArray();
  50. cs[0] -= 32;
  51. return String.valueOf(cs);
  52.  
  53. }
  54.  
  55. /**
  56. * 下划线转换为驼峰
  57. */
  58. public static String camelCaseName(String underscoreName) {
  59. StringBuilder result = new StringBuilder();
  60. if (underscoreName != null && underscoreName.length() > 0) {
  61. boolean flag = false;
  62. for (int i = 0; i < underscoreName.length(); i++) {
  63. char ch = underscoreName.charAt(i);
  64. if ("_".charAt(0) == ch) {
  65. flag = true;
  66. } else {
  67. if (flag) {
  68. result.append(Character.toUpperCase(ch));
  69. flag = false;
  70. } else {
  71. result.append(ch);
  72. }
  73. }
  74. }
  75. }
  76. return result.toString();
  77. }
  78. }

  文件处理

  文件处理比如创建文件夹、文件,将字符写入文件等,我们先获取一下基础路径,并封装一下文件工具类:

  1. /**
  2. * file工具类
  3. */
  4. private static class FileUtil {
  5. /**
  6. * 创建文件
  7. *
  8. * @param pathNameAndFileName 路径跟文件名
  9. * @return File对象
  10. */
  11. private static File createFile(String pathNameAndFileName) {
  12. File file = new File(pathNameAndFileName);
  13. try {
  14. //获取父目录
  15. File fileParent = file.getParentFile();
  16. if (!fileParent.exists()) {
  17. fileParent.mkdirs();
  18. }
  19. //创建文件
  20. if (!file.exists()) {
  21. file.createNewFile();
  22. }
  23. } catch (Exception e) {
  24. file = null;
  25. System.err.println("新建文件操作出错");
  26. e.printStackTrace();
  27. }
  28. return file;
  29. }
  30.  
  31. /**
  32. * 字符流写入文件
  33. *
  34. * @param file file对象
  35. * @param stringBuffer 要写入的数据
  36. */
  37. private static void fileWriter(File file, StringBuffer stringBuffer) {
  38. //字符流
  39. try {
  40. FileWriter resultFile = new FileWriter(file, true);//true,则追加写入 false,则覆盖写入
  41. PrintWriter myFile = new PrintWriter(resultFile);
  42. //写入
  43. myFile.println(stringBuffer.toString());
  44.  
  45. myFile.close();
  46. resultFile.close();
  47. } catch (Exception e) {
  48. System.err.println("写入操作出错");
  49. e.printStackTrace();
  50. }
  51. }
  52. }

  

  创建代码

  根据我们项目的路径规范,代码编写规范,我们定义好文件的模板,并封装成对应的方法

  1. /**
  2. * 创建pojo实体类
  3. */
  4. private void createPojo(List<TableInfo> tableInfos) {
  5. File file = FileUtil.createFile(basePath + "pojo\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ".java");
  6. StringBuffer stringBuffer = new StringBuffer();
  7. stringBuffer.append(
  8. "package " + package_.replaceAll("\\\\", ".") + "pojo;\n" +
  9. "\n" +
  10. "import lombok.Data;\n" +
  11. "import javax.persistence.*;\n" +
  12. "import java.io.Serializable;\n" +
  13. "import java.util.Date;\n" +
  14. "\n" +
  15. "@Entity\n" +
  16. "@Table(name = \"" + tableName + "\")\n" +
  17. "@Data\n" +
  18. "public class " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + " implements Serializable {\n"
  19. );
  20. //遍历设置属性
  21. for (TableInfo tableInfo : tableInfos) {
  22. //主键
  23. if ("PRI".equals(tableInfo.getColumnKey())) {
  24. stringBuffer.append(" @Id\n");
  25. }
  26. //自增
  27. if ("auto_increment".equals(tableInfo.getExtra())) {
  28. stringBuffer.append(" @GeneratedValue(strategy= GenerationType.IDENTITY)\n");
  29. }
  30. stringBuffer.append(" private " + StringUtil.typeMapping(tableInfo.getDataType()) + " " + StringUtil.camelCaseName(tableInfo.getColumnName()) + ";//" + tableInfo.getColumnComment() + "\n\n");
  31. }
  32. stringBuffer.append("}");
  33. FileUtil.fileWriter(file, stringBuffer);
  34. }
  1. /**
  2. * 创建vo类
  3. */
  4. private void createVo(List<TableInfo> tableInfos) {
  5. File file = FileUtil.createFile(basePath + "vo\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo.java");
  6. StringBuffer stringBuffer = new StringBuffer();
  7. stringBuffer.append(
  8. "package " + package_.replaceAll("\\\\", ".") + "vo;\n" +
  9. "\n" +
    "import "+ basePackage_.replaceAll("\\\\", ".") +" common.pojo.PageCondition;"+
  10. "import lombok.Data;\n" +
  11. "import java.io.Serializable;\n" +
  12. "import java.util.Date;\n" +
  13. "\n" +
  14. "@Data\n" +
  15. "public class " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo extends PageCondition implements Serializable {\n"
  16. );
  17. //遍历设置属性
  18. for (TableInfo tableInfo : tableInfos) {
  19. stringBuffer.append(" private " + StringUtil.typeMapping(tableInfo.getDataType()) + " " + StringUtil.camelCaseName(tableInfo.getColumnName()) + ";//" + tableInfo.getColumnComment() + "\n\n");
  20. }
  21. stringBuffer.append("}");
  22. FileUtil.fileWriter(file, stringBuffer);
  23. }
  1. /**
  2. * 创建repository类
  3. */
  4. private void createRepository(List<TableInfo> tableInfos) {
  5. File file = FileUtil.createFile(basePath + "repository\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Repository.java");
  6. StringBuffer stringBuffer = new StringBuffer();
  7. String t = "String";
  8. //遍历属性
  9. for (TableInfo tableInfo : tableInfos) {
  10. //主键
  11. if ("PRI".equals(tableInfo.getColumnKey())) {
  12. t = StringUtil.typeMapping(tableInfo.getDataType());
  13. }
  14. }
  15. stringBuffer.append(
  16. "package " + package_.replaceAll("\\\\", ".") + "repository;\n" +
  17. "\n" +
  18. "import " + basePackage_.replaceAll("\\\\", ".") + "common.repository.*;\n" +
  19. "import " + package_.replaceAll("\\\\", ".") + "pojo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ";\n" +
  20. "import org.springframework.stereotype.Repository;\n" +
  21. "\n" +
  22. "@Repository\n" +
  23. "public interface " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Repository extends CommonRepository<" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ", " + t + "> {"
  24. );
  25. stringBuffer.append("\n");
  26. stringBuffer.append("}");
  27. FileUtil.fileWriter(file, stringBuffer);
  28. }
  1. /**
  2. * 创建service类
  3. */
  4. private void createService(List<TableInfo> tableInfos) {
  5. File file = FileUtil.createFile(basePath + "service\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Service.java");
  6. StringBuffer stringBuffer = new StringBuffer();
  7. String t = "String";
  8. //遍历属性
  9. for (TableInfo tableInfo : tableInfos) {
  10. //主键
  11. if ("PRI".equals(tableInfo.getColumnKey())) {
  12. t = StringUtil.typeMapping(tableInfo.getDataType());
  13. }
  14. }
  15. stringBuffer.append(
  16. "package " + package_.replaceAll("\\\\", ".") + "service;\n" +
  17. "\n" +
  18. "import " + basePackage_.replaceAll("\\\\", ".") + "common.service.*;\n" +
  19. "import " + package_.replaceAll("\\\\", ".") + "pojo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ";\n" +
  20. "import " + package_.replaceAll("\\\\", ".") + "vo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo;\n" +
  21. "\n" +
  22. "public interface " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Service extends CommonService<" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo, " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ", " + t + "> {"
  23. );
  24. stringBuffer.append("\n");
  25. stringBuffer.append("}");
  26. FileUtil.fileWriter(file, stringBuffer);
  27.  
  28. //Impl
  29. File file1 = FileUtil.createFile(basePath + "service\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "ServiceImpl.java");
  30. StringBuffer stringBuffer1 = new StringBuffer();
  31. stringBuffer1.append(
  32. "package " + package_.replaceAll("\\\\", ".") + "service;\n" +
  33. "\n" +
  34. "import " + basePackage_.replaceAll("\\\\", ".") + "common.service.*;\n" +
  35. "import " + package_.replaceAll("\\\\", ".") + "pojo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ";\n" +
  36. "import " + package_.replaceAll("\\\\", ".") + "vo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo;\n" +
  37. "import " + package_.replaceAll("\\\\", ".") + "repository." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Repository;\n" +
  38. "import org.springframework.beans.factory.annotation.Autowired;\n" +
  39. "import org.springframework.stereotype.Service;\n" +
  40. "import org.springframework.transaction.annotation.Transactional;\n" +
  41. "import javax.persistence.EntityManager;\n" +
  42. "import javax.persistence.PersistenceContext;\n" +
  43. "\n" +
  44. "@Service\n" +
  45. "@Transactional\n" +
  46. "public class " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "ServiceImpl extends CommonServiceImpl<" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo, " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ", " + t + "> implements " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Service{"
  47. );
  48. stringBuffer1.append("\n\n");
  49. stringBuffer1.append(
  50. " @PersistenceContext\n" +
  51. " private EntityManager em;\n");
  52.  
  53. stringBuffer1.append("" +
  54. " @Autowired\n" +
  55. " private " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Repository " + StringUtil.camelCaseName(tableName) + "Repository;\n");
  56. stringBuffer1.append("}");
  57. FileUtil.fileWriter(file1, stringBuffer1);
  58. }
  1. /**
  2. * 创建controller类
  3. */
  4. private void createController(List<TableInfo> tableInfos) {
  5. File file = FileUtil.createFile(basePath + "controller\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Controller.java");
  6. StringBuffer stringBuffer = new StringBuffer();
  7. String t = "String";
  8. //遍历属性
  9. for (TableInfo tableInfo : tableInfos) {
  10. //主键
  11. if ("PRI".equals(tableInfo.getColumnKey())) {
  12. t = StringUtil.typeMapping(tableInfo.getDataType());
  13. }
  14. }
  15. stringBuffer.append(
  16. "package " + package_.replaceAll("\\\\", ".") + "controller;\n" +
  17. "\n" +
  18. "import " + basePackage_.replaceAll("\\\\", ".") + "common.controller.*;\n" +
  19. "import " + package_.replaceAll("\\\\", ".") + "pojo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ";\n" +
  20. "import " + package_.replaceAll("\\\\", ".") + "vo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo;\n" +
  21. "import " + package_.replaceAll("\\\\", ".") + "service." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Service;\n" +
  22. "import org.springframework.beans.factory.annotation.Autowired;\n" +
  23. "import org.springframework.web.bind.annotation.*;\n" +
  24. "\n" +
  25. "@RestController\n" +
  26. "@RequestMapping(\"/" + StringUtil.camelCaseName(tableName) + "/\")\n" +
  27. "public class " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Controller extends CommonController<" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo, " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ", " + t + "> {"
  28. );
  29. stringBuffer.append("\n");
  30. stringBuffer.append("" +
  31. " @Autowired\n" +
  32. " private " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Service " + StringUtil.camelCaseName(tableName) + "Service;\n");
  33. stringBuffer.append("}");
  34. FileUtil.fileWriter(file, stringBuffer);
  35. }

  需要注意的是:目前生成的pojo的主键,只用了@Id声明该属性为表主键,尚缺一个主键生成策略,这个需要根据自己的情况来选择主键生成策略

  PS:缺少主键生成策略或者设置错误将会出现以下问题:

  程序不报错,JPA查询出来的数据长度正常,内容都是重复的,但mysql数据库运行查询语句结果正常

  1. /*
  2. JPA提供的四种主键生成策略
  3. GenerationType.TABLE:使用一个特定的数据库表格来保存主键。
  4. GenerationType.SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。
  5. GenerationType.IDENTITY:主键由数据库自动生成(主要是自动增长型)
  6. GenerationType.AUTO:主键由程序控制。
  7. */
  8. @GeneratedValue(strategy = GenerationType.IDENTITY)

  提供一个方法让外部直接调用

  1. /**
  2. * 快速创建,供外部调用,调用之前先设置一下项目的基础路径
  3. */
  4. private String create() {
  5. List<TableInfo> tableInfo = getTableInfo();
  6. createPojo(tableInfo);
  7. createVo(tableInfo);
  8. createRepository(tableInfo);
  9. createService(tableInfo);
  10. createController(tableInfo);
  11. return tableName + " 后台代码生成完毕!";
  12. }

  效果演示

  main方法运行

  1. public static void main(String[] args) {
  2. String[] tables = {"tb_user"};
  3. for (int i = 0; i < tables.length; i++) {
  4. String msg = new CodeDOM(tables[i]).create();
  5. System.out.println(msg);
  6. }
  7. }

  生成代码

  我们查看一下生成的代码

  1. package cn.huanzi.springbootjpa.tbuser.pojo;
  2.  
  3. import lombok.Data;
  4. import javax.persistence.*;
  5. import java.io.Serializable;
  6. import java.util.Date;
  7.  
  8. @Entity
  9. @Table(name = "tb_user")
  10. @Data
  11. public class TbUser implements Serializable {
  12. @Id
  13. @GeneratedValue(strategy= GenerationType.IDENTITY)
  14. private Integer id;//表id
  15.  
  16. private String username;//用户名
  17.  
  18. private String password;//密码
  19.  
  20. private Date created;//创建时间
  21.  
  22. private Integer descriptionId;//关联详情id
  23.  
  24. }
  1. package cn.huanzi.springbootjpa.tbuser.vo;
  2.  
  3. import lombok.Data;
  4. import java.io.Serializable;
  5. import java.util.Date;
  6.  
  7. @Data
  8. public class TbUserVo extends PageCondition implements Serializable {
  9. private Integer id;//表id
  10.  
  11. private String username;//用户名
  12.  
  13. private String password;//密码
  14.  
  15. private Date created;//创建时间
  16.  
  17. private Integer descriptionId;//关联详情id
  18.  
  19. }
  1. package cn.huanzi.springbootjpa.tbuser.repository;
  2.  
  3. import cn.huanzi.springbootjpa.common.repository.*;
  4. import cn.huanzi.springbootjpa.tbuser.pojo.TbUser;
  5. import org.springframework.stereotype.Repository;
  6.  
  7. @Repository
  8. public interface TbUserRepository extends CommonRepository<TbUser, Integer> {
  9. }
  1. package cn.huanzi.springbootjpa.tbuser.service;
  2.  
  3. import cn.huanzi.springbootjpa.common.service.*;
  4. import cn.huanzi.springbootjpa.tbuser.pojo.TbUser;
  5. import cn.huanzi.springbootjpa.tbuser.vo.TbUserVo;
  6.  
  7. public interface TbUserService extends CommonService<TbUserVo, TbUser, Integer> {
  8. }
  1. package cn.huanzi.springbootjpa.tbuser.service;
  2.  
  3. import cn.huanzi.springbootjpa.common.service.*;
  4. import cn.huanzi.springbootjpa.tbuser.pojo.TbUser;
  5. import cn.huanzi.springbootjpa.tbuser.vo.TbUserVo;
  6. import cn.huanzi.springbootjpa.tbuser.repository.TbUserRepository;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.stereotype.Service;
  9. import org.springframework.transaction.annotation.Transactional;
  10. import javax.persistence.EntityManager;
  11. import javax.persistence.PersistenceContext;
  12.  
  13. @Service
  14. @Transactional
  15. public class TbUserServiceImpl extends CommonServiceImpl<TbUserVo, TbUser, Integer> implements TbUserService{
  16.  
  17. @PersistenceContext
  18. private EntityManager em;
  19. @Autowired
  20. private TbUserRepository tbUserRepository;
  21. }
  1. package cn.huanzi.springbootjpa.tbuser.controller;
  2.  
  3. import cn.huanzi.springbootjpa.common.controller.*;
  4. import cn.huanzi.springbootjpa.tbuser.pojo.TbUser;
  5. import cn.huanzi.springbootjpa.tbuser.vo.TbUserVo;
  6. import cn.huanzi.springbootjpa.tbuser.service.TbUserService;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.web.bind.annotation.*;
  9.  
  10. @RestController
  11. @RequestMapping("/tbUser/")
  12. public class TbUserController extends CommonController<TbUserVo, TbUser, Integer> {
  13. @Autowired
  14. private TbUserService tbUserService;
  15. }

  我们启动项目

  依次访问基础接口:

  get接口

  http://localhost:10086/tbUser/get/1

  page接口

  http://localhost:10086/tbUser/page?page=1&rows=10

  

  list接口

  http://localhost:10086/tbUser/list

  save接口

  (插入跟更新)

  没有id或id不存在,为插入,http://localhost:10086/tbUser/save?username=张麻子&password=123

  id已存在,则为更新,注意:这里的更新是你的字段是什么jpa就帮你存什么,如果想要实现只更新接参对象有值的字段,应该先用id去同步数据,再更新,

  delete接口

  http://localhost:10086/tbUser/delete/15

  扩展

  1、有一些同学会发现,代码生成后idea并没有帮我们扫描出来,这时候我们可以手动去刷新一下,对着我们的项目右键,然后刷新

  2、个人觉得代码生成用groovy更加合适,只是我现在对它的语法使用还不熟悉,后面我们可以尝试一下使用groovy来生成代码,在idea里使用groovy生成代码:

  groovy文件的位置:

  使用方法:用idea的datebase连接数据库后,对着表右击

  后记

  这套代码的风格是单表继承通用CRUD、分页、排序接口,在启动类的同级目录下面,按一张表一个目录分层级存放文件,技术选型:springboot + thymeleaf + springdata-jpa + mysql,pojo实体对象负责ORM框架与数据库的映射,vo对象负责接参、传参,vo与pojo通过CopyUtil工具类进相互转换

  一人挖井,全村喝水;有了这一套基础代码跟代码自动生成单表基础增、删、改、查接口,我们的开发效率大大提高

  完整代码

  1. package cn.huanzi.qch.springbootjpa.util;
  2.  
  3. import java.io.File;
  4. import java.io.FileWriter;
  5. import java.io.PrintWriter;
  6. import java.sql.*;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9.  
  10. /**
  11. * 自动生成代码
  12. */
  13. public class CodeDOM {
  14.  
  15. /**
  16. * 构造参数,出入表名
  17. */
  18. private CodeDOM(String tableName) {
  19. this.tableName = tableName;
  20. basePackage_ = "cn\\huanzi\\qch\\springbootjpa\\";
  21. package_ = basePackage_ + StringUtil.camelCaseName(tableName).toLowerCase() + "\\";
  22. //System.getProperty("user.dir") 获取的是项目所在路径,如果我们是子项目,则需要添加一层路径
  23. basePath = System.getProperty("user.dir") + "\\springboot-jpa\\src\\main\\java\\" + package_;
  24. }
  25.  
  26. /**
  27. * 数据连接相关
  28. */
  29. private static final String URL = "jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8&characterEncoding=utf-8";
  30. private static final String USERNAME = "root";
  31. private static final String PASSWORD = "123456";
  32. private static final String DRIVERCLASSNAME = "com.mysql.jdbc.Driver";
  33. /**
  34. * 表名
  35. */
  36. private String tableName;
  37.  
  38. /**
  39. * 基础路径
  40. */
  41. private String basePackage_;
  42. private String package_;
  43. private String basePath;
  44.  
  45. /**
  46. * 创建pojo实体类
  47. */
  48. private void createPojo(List<TableInfo> tableInfos) {
  49. File file = FileUtil.createFile(basePath + "pojo\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ".java");
  50. StringBuffer stringBuffer = new StringBuffer();
  51. stringBuffer.append(
  52. "package " + package_.replaceAll("\\\\", ".") + "pojo;\n" +
  53. "\n" +
  54. "import lombok.Data;\n" +
  55. "import javax.persistence.*;\n" +
  56. "import java.io.Serializable;\n" +
  57. "import java.util.Date;\n" +
  58. "\n" +
  59. "@Entity\n" +
  60. "@Table(name = \"" + tableName + "\")\n" +
  61. "@Data\n" +
  62. "public class " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + " implements Serializable {\n"
  63. );
  64. //遍历设置属性
  65. for (TableInfo tableInfo : tableInfos) {
  66. //主键
  67. if ("PRI".equals(tableInfo.getColumnKey())) {
  68. stringBuffer.append(" @Id\n");
  69. }
  70. //自增
  71. if ("auto_increment".equals(tableInfo.getExtra())) {
  72. stringBuffer.append(" @GeneratedValue(strategy= GenerationType.IDENTITY)\n");
  73. }
  74. stringBuffer.append(" private " + StringUtil.typeMapping(tableInfo.getDataType()) + " " + StringUtil.camelCaseName(tableInfo.getColumnName()) + ";//" + tableInfo.getColumnComment() + "\n\n");
  75. }
  76. stringBuffer.append("}");
  77. FileUtil.fileWriter(file, stringBuffer);
  78. }
  79.  
  80. /**
  81. * 创建vo类
  82. */
  83. private void createVo(List<TableInfo> tableInfos) {
  84. File file = FileUtil.createFile(basePath + "vo\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo.java");
  85. StringBuffer stringBuffer = new StringBuffer();
  86. stringBuffer.append(
  87. "package " + package_.replaceAll("\\\\", ".") + "vo;\n" +
  88. "\n" +
  89. "import "+ basePackage_.replaceAll("\\\\", ".") +" common.pojo.PageCondition;"+
  90. "import lombok.Data;\n" +
  91. "import java.io.Serializable;\n" +
  92. "import java.util.Date;\n" +
  93. "\n" +
  94. "@Data\n" +
  95. "public class " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo extends PageCondition implements Serializable {\n"
  96. );
  97. //遍历设置属性
  98. for (TableInfo tableInfo : tableInfos) {
  99. stringBuffer.append(" private " + StringUtil.typeMapping(tableInfo.getDataType()) + " " + StringUtil.camelCaseName(tableInfo.getColumnName()) + ";//" + tableInfo.getColumnComment() + "\n\n");
  100. }
  101. stringBuffer.append("}");
  102. FileUtil.fileWriter(file, stringBuffer);
  103. }
  104.  
  105. /**
  106. * 创建repository类
  107. */
  108. private void createRepository(List<TableInfo> tableInfos) {
  109. File file = FileUtil.createFile(basePath + "repository\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Repository.java");
  110. StringBuffer stringBuffer = new StringBuffer();
  111. String t = "String";
  112. //遍历属性
  113. for (TableInfo tableInfo : tableInfos) {
  114. //主键
  115. if ("PRI".equals(tableInfo.getColumnKey())) {
  116. t = StringUtil.typeMapping(tableInfo.getDataType());
  117. }
  118. }
  119. stringBuffer.append(
  120. "package " + package_.replaceAll("\\\\", ".") + "repository;\n" +
  121. "\n" +
  122. "import " + basePackage_.replaceAll("\\\\", ".") + "common.repository.*;\n" +
  123. "import " + package_.replaceAll("\\\\", ".") + "pojo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ";\n" +
  124. "import org.springframework.stereotype.Repository;\n" +
  125. "\n" +
  126. "@Repository\n" +
  127. "public interface " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Repository extends CommonRepository<" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ", " + t + "> {"
  128. );
  129. stringBuffer.append("\n");
  130. stringBuffer.append("}");
  131. FileUtil.fileWriter(file, stringBuffer);
  132. }
  133.  
  134. /**
  135. * 创建service类
  136. */
  137. private void createService(List<TableInfo> tableInfos) {
  138. File file = FileUtil.createFile(basePath + "service\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Service.java");
  139. StringBuffer stringBuffer = new StringBuffer();
  140. String t = "String";
  141. //遍历属性
  142. for (TableInfo tableInfo : tableInfos) {
  143. //主键
  144. if ("PRI".equals(tableInfo.getColumnKey())) {
  145. t = StringUtil.typeMapping(tableInfo.getDataType());
  146. }
  147. }
  148. stringBuffer.append(
  149. "package " + package_.replaceAll("\\\\", ".") + "service;\n" +
  150. "\n" +
  151. "import " + basePackage_.replaceAll("\\\\", ".") + "common.service.*;\n" +
  152. "import " + package_.replaceAll("\\\\", ".") + "pojo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ";\n" +
  153. "import " + package_.replaceAll("\\\\", ".") + "vo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo;\n" +
  154. "\n" +
  155. "public interface " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Service extends CommonService<" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo, " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ", " + t + "> {"
  156. );
  157. stringBuffer.append("\n");
  158. stringBuffer.append("}");
  159. FileUtil.fileWriter(file, stringBuffer);
  160.  
  161. //Impl
  162. File file1 = FileUtil.createFile(basePath + "service\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "ServiceImpl.java");
  163. StringBuffer stringBuffer1 = new StringBuffer();
  164. stringBuffer1.append(
  165. "package " + package_.replaceAll("\\\\", ".") + "service;\n" +
  166. "\n" +
  167. "import " + basePackage_.replaceAll("\\\\", ".") + "common.service.*;\n" +
  168. "import " + package_.replaceAll("\\\\", ".") + "pojo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ";\n" +
  169. "import " + package_.replaceAll("\\\\", ".") + "vo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo;\n" +
  170. "import " + package_.replaceAll("\\\\", ".") + "repository." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Repository;\n" +
  171. "import org.springframework.beans.factory.annotation.Autowired;\n" +
  172. "import org.springframework.stereotype.Service;\n" +
  173. "import org.springframework.transaction.annotation.Transactional;\n" +
  174. "import javax.persistence.EntityManager;\n" +
  175. "import javax.persistence.PersistenceContext;\n" +
  176. "\n" +
  177. "@Service\n" +
  178. "@Transactional\n" +
  179. "public class " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "ServiceImpl extends CommonServiceImpl<" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo, " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ", " + t + "> implements " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Service{"
  180. );
  181. stringBuffer1.append("\n\n");
  182. stringBuffer1.append(
  183. " @PersistenceContext\n" +
  184. " private EntityManager em;\n");
  185.  
  186. stringBuffer1.append("" +
  187. " @Autowired\n" +
  188. " private " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Repository " + StringUtil.camelCaseName(tableName) + "Repository;\n");
  189. stringBuffer1.append("}");
  190. FileUtil.fileWriter(file1, stringBuffer1);
  191. }
  192.  
  193. /**
  194. * 创建controller类
  195. */
  196. private void createController(List<TableInfo> tableInfos) {
  197. File file = FileUtil.createFile(basePath + "controller\\" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Controller.java");
  198. StringBuffer stringBuffer = new StringBuffer();
  199. String t = "String";
  200. //遍历属性
  201. for (TableInfo tableInfo : tableInfos) {
  202. //主键
  203. if ("PRI".equals(tableInfo.getColumnKey())) {
  204. t = StringUtil.typeMapping(tableInfo.getDataType());
  205. }
  206. }
  207. stringBuffer.append(
  208. "package " + package_.replaceAll("\\\\", ".") + "controller;\n" +
  209. "\n" +
  210. "import " + basePackage_.replaceAll("\\\\", ".") + "common.controller.*;\n" +
  211. "import " + package_.replaceAll("\\\\", ".") + "pojo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ";\n" +
  212. "import " + package_.replaceAll("\\\\", ".") + "vo." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo;\n" +
  213. "import " + package_.replaceAll("\\\\", ".") + "service." + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Service;\n" +
  214. "import org.springframework.beans.factory.annotation.Autowired;\n" +
  215. "import org.springframework.web.bind.annotation.*;\n" +
  216. "\n" +
  217. "@RestController\n" +
  218. "@RequestMapping(\"/" + StringUtil.camelCaseName(tableName) + "/\")\n" +
  219. "public class " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Controller extends CommonController<" + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Vo, " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + ", " + t + "> {"
  220. );
  221. stringBuffer.append("\n");
  222. stringBuffer.append("" +
  223. " @Autowired\n" +
  224. " private " + StringUtil.captureName(StringUtil.camelCaseName(tableName)) + "Service " + StringUtil.camelCaseName(tableName) + "Service;\n");
  225. stringBuffer.append("}");
  226. FileUtil.fileWriter(file, stringBuffer);
  227. }
  228.  
  229. /**
  230. * 获取表结构信息
  231. *
  232. * @return list
  233. */
  234. private List<TableInfo> getTableInfo() {
  235. Connection conn = null;
  236. PreparedStatement ps = null;
  237. ResultSet rs = null;
  238. ArrayList<TableInfo> list = new ArrayList<>();
  239. try {
  240. conn = DBConnectionUtil.getConnection();
  241. String sql = "select column_name,data_type,column_comment,column_key,extra from information_schema.columns where table_name=?";
  242. ps = conn.prepareStatement(sql);
  243. ps.setString(1, tableName);
  244. rs = ps.executeQuery();
  245. while (rs.next()) {
  246. TableInfo tableInfo = new TableInfo();
  247. //列名,全部转为小写
  248. tableInfo.setColumnName(rs.getString("column_name").toLowerCase());
  249. //列类型
  250. tableInfo.setDataType(rs.getString("data_type"));
  251. //列注释
  252. tableInfo.setColumnComment(rs.getString("column_comment"));
  253. //主键
  254. tableInfo.setColumnKey(rs.getString("column_key"));
  255. //主键类型
  256. tableInfo.setExtra(rs.getString("extra"));
  257. list.add(tableInfo);
  258. }
  259. } catch (SQLException e) {
  260. e.printStackTrace();
  261. } finally {
  262. assert rs != null;
  263. DBConnectionUtil.close(conn, ps, rs);
  264. }
  265. return list;
  266. }
  267.  
  268. /**
  269. * file工具类
  270. */
  271. private static class FileUtil {
  272. /**
  273. * 创建文件
  274. *
  275. * @param pathNameAndFileName 路径跟文件名
  276. * @return File对象
  277. */
  278. private static File createFile(String pathNameAndFileName) {
  279. File file = new File(pathNameAndFileName);
  280. try {
  281. //获取父目录
  282. File fileParent = file.getParentFile();
  283. if (!fileParent.exists()) {
  284. fileParent.mkdirs();
  285. }
  286. //创建文件
  287. if (!file.exists()) {
  288. file.createNewFile();
  289. }
  290. } catch (Exception e) {
  291. file = null;
  292. System.err.println("新建文件操作出错");
  293. e.printStackTrace();
  294. }
  295. return file;
  296. }
  297.  
  298. /**
  299. * 字符流写入文件
  300. *
  301. * @param file file对象
  302. * @param stringBuffer 要写入的数据
  303. */
  304. private static void fileWriter(File file, StringBuffer stringBuffer) {
  305. //字符流
  306. try {
  307. FileWriter resultFile = new FileWriter(file, false);//true,则追加写入 false,则覆盖写入
  308. PrintWriter myFile = new PrintWriter(resultFile);
  309. //写入
  310. myFile.println(stringBuffer.toString());
  311.  
  312. myFile.close();
  313. resultFile.close();
  314. } catch (Exception e) {
  315. System.err.println("写入操作出错");
  316. e.printStackTrace();
  317. }
  318. }
  319. }
  320.  
  321. /**
  322. * 字符串处理工具类
  323. */
  324. private static class StringUtil {
  325. /**
  326. * 数据库类型->JAVA类型
  327. *
  328. * @param dbType 数据库类型
  329. * @return JAVA类型
  330. */
  331. private static String typeMapping(String dbType) {
  332. String javaType = "";
  333. if ("int|integer".contains(dbType)) {
  334. javaType = "Integer";
  335. } else if ("float|double|decimal|real".contains(dbType)) {
  336. javaType = "Double";
  337. } else if ("date|time|datetime|timestamp".contains(dbType)) {
  338. javaType = "Date";
  339. } else {
  340. javaType = "String";
  341. }
  342. return javaType;
  343. }
  344.  
  345. /**
  346. * 驼峰转换为下划线
  347. */
  348. public static String underscoreName(String camelCaseName) {
  349. StringBuilder result = new StringBuilder();
  350. if (camelCaseName != null && camelCaseName.length() > 0) {
  351. result.append(camelCaseName.substring(0, 1).toLowerCase());
  352. for (int i = 1; i < camelCaseName.length(); i++) {
  353. char ch = camelCaseName.charAt(i);
  354. if (Character.isUpperCase(ch)) {
  355. result.append("_");
  356. result.append(Character.toLowerCase(ch));
  357. } else {
  358. result.append(ch);
  359. }
  360. }
  361. }
  362. return result.toString();
  363. }
  364.  
  365. /**
  366. * 首字母大写
  367. */
  368. public static String captureName(String name) {
  369. char[] cs = name.toCharArray();
  370. cs[0] -= 32;
  371. return String.valueOf(cs);
  372.  
  373. }
  374.  
  375. /**
  376. * 下划线转换为驼峰
  377. */
  378. public static String camelCaseName(String underscoreName) {
  379. StringBuilder result = new StringBuilder();
  380. if (underscoreName != null && underscoreName.length() > 0) {
  381. boolean flag = false;
  382. for (int i = 0; i < underscoreName.length(); i++) {
  383. char ch = underscoreName.charAt(i);
  384. if ("_".charAt(0) == ch) {
  385. flag = true;
  386. } else {
  387. if (flag) {
  388. result.append(Character.toUpperCase(ch));
  389. flag = false;
  390. } else {
  391. result.append(ch);
  392. }
  393. }
  394. }
  395. }
  396. return result.toString();
  397. }
  398. }
  399.  
  400. /**
  401. * JDBC连接数据库工具类
  402. */
  403. private static class DBConnectionUtil {
  404.  
  405. {
  406. // 1、加载驱动
  407. try {
  408. Class.forName(DRIVERCLASSNAME);
  409. } catch (ClassNotFoundException e) {
  410. e.printStackTrace();
  411. }
  412. }
  413.  
  414. /**
  415. * 返回一个Connection连接
  416. *
  417. * @return
  418. */
  419. public static Connection getConnection() {
  420. Connection conn = null;
  421. // 2、连接数据库
  422. try {
  423. conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
  424. } catch (SQLException e) {
  425. e.printStackTrace();
  426. }
  427. return conn;
  428. }
  429.  
  430. /**
  431. * 关闭Connection,Statement连接
  432. *
  433. * @param conn
  434. * @param stmt
  435. */
  436. public static void close(Connection conn, Statement stmt) {
  437. try {
  438. conn.close();
  439. stmt.close();
  440. } catch (SQLException e) {
  441. e.printStackTrace();
  442. }
  443. }
  444.  
  445. /**
  446. * 关闭Connection,Statement,ResultSet连接
  447. *
  448. * @param conn
  449. * @param stmt
  450. * @param rs
  451. */
  452. public static void close(Connection conn, Statement stmt, ResultSet rs) {
  453. try {
  454. close(conn, stmt);
  455. rs.close();
  456. } catch (SQLException e) {
  457. e.printStackTrace();
  458. }
  459. }
  460.  
  461. }
  462.  
  463. /**
  464. * 表结构行信息实体类
  465. */
  466. private class TableInfo {
  467. private String columnName;
  468. private String dataType;
  469. private String columnComment;
  470. private String columnKey;
  471. private String extra;
  472.  
  473. TableInfo() {
  474. }
  475.  
  476. String getColumnName() {
  477. return columnName;
  478. }
  479.  
  480. void setColumnName(String columnName) {
  481. this.columnName = columnName;
  482. }
  483.  
  484. String getDataType() {
  485. return dataType;
  486. }
  487.  
  488. void setDataType(String dataType) {
  489. this.dataType = dataType;
  490. }
  491.  
  492. String getColumnComment() {
  493. return columnComment;
  494. }
  495.  
  496. void setColumnComment(String columnComment) {
  497. this.columnComment = columnComment;
  498. }
  499.  
  500. String getColumnKey() {
  501. return columnKey;
  502. }
  503.  
  504. void setColumnKey(String columnKey) {
  505. this.columnKey = columnKey;
  506. }
  507.  
  508. String getExtra() {
  509. return extra;
  510. }
  511.  
  512. void setExtra(String extra) {
  513. this.extra = extra;
  514. }
  515. }
  516.  
  517. /**
  518. * 快速创建,供外部调用,调用之前先设置一下项目的基础路径
  519. */
  520. private String create() {
  521. List<TableInfo> tableInfo = getTableInfo();
  522. createPojo(tableInfo);
  523. createVo(tableInfo);
  524. createRepository(tableInfo);
  525. createService(tableInfo);
  526. createController(tableInfo);
  527. System.out.println("生成路径位置:" + basePath);
  528. return tableName + " 后台代码生成完毕!";
  529. }
  530.  
  531. public static void main(String[] args) {
  532. String[] tables = {"tb_description"};
  533. for (String table : tables) {
  534. String msg = new CodeDOM(table).create();
  535. System.out.println(msg);
  536. }
  537. }
  538. }

CodeDOM

  补充

  1、发现了一个问题,我们在自动生成controller里有个地方是写死的...

  改一下,顺便升级一下CodeDOM类,我已经更新了博客文章,现在你看的文章已经是正确的,且是升级后的版本。

  2、有细心园友发现我们漏贴了CommonController的代码,我们在这里补贴一下,另外说一下,其他的common代码在jpa升级版中 SpringBoot系列——Spring-Data-JPA(升级版),但里面当时我们只写了service层、repository层的通用代码,以及通讯对象和实体与Vo转换工具等其他公用代码,controller是在本文才加上去的。

  1. /**
  2. * 通用Controller
  3. *
  4. * @param <V> 实体类Vo
  5. * @param <E> 实体类
  6. * @param <T> id主键类型
  7. */
  8. public class CommonController<V, E,T> {
  9.  
  10. @Autowired
  11. private CommonService<V, E,T> commonService;
  12.  
  13. /*
  14. CRUD、分页、排序测试
  15. */
  16. // @PostMapping("page")
  17. @RequestMapping("page")
  18. public Result<PageInfo<V>> page(V entityVo) {
  19. return commonService.page(entityVo);
  20. }
  21.  
  22. // @PostMapping("list")
  23. @RequestMapping("list")
  24. public Result<List<V>> list(V entityVo) {
  25. return commonService.list(entityVo);
  26. }
  27.  
  28. // @GetMapping("get/{id}")
  29. @RequestMapping("get/{id}")
  30. public Result<V> get( @PathVariable("id") T id) {
  31. return commonService.get(id);
  32. }
  33.  
  34. // @PostMapping("save")
  35. @RequestMapping("save")
  36. public Result<V> save( V entityVo) {
  37. return commonService.save(entityVo);
  38. }
  39.  
  40. // @GetMapping("delete/{id}")
  41. @RequestMapping("delete/{id}")
  42. public Result<T> delete( @PathVariable("id") T id) {
  43. /*
  44. 批量删除
  45. @DeleteMapping("deleteBatch")
  46. public Result<T> deleteBatch(@RequestBody List<String> ids){}
  47. 前端调用:
  48. $.ajax({
  49. url: ctx + "deleteBatch",
  50. type: "DELETE",
  51. data: JSON.stringify([id1,id2]),
  52. dataType: "JSON",
  53. contentType: 'application/json',
  54. success: function (data) {
  55.  
  56. }
  57. });
  58. */
  59. return commonService.delete(id);
  60. }
  61. }

CommonController

  代码开源

  代码已经开源、托管到我的GitHub、码云:

  GitHub:https://github.com/huanzi-qch/springBoot

  码云:https://gitee.com/huanzi-qch/springBoot

SpringBoot系列——Spring-Data-JPA(究极进化版) 自动生成单表基础增、删、改、查接口的更多相关文章

  1. spring-boot (三) spring data jpa

    学习文章来自:http://www.ityouknow.com/spring-boot.html spring data jpa介绍 首先了解JPA是什么? JPA(Java Persistence ...

  2. springboot整合spring Data JPA

    今天敲代码,一连串的错误,我也是服气~果然,我们不是在出bug,就是在找bug的路上…… 今天完成的是springboot整合spring data JPA ,出了一连串的错,真是头大 java.sq ...

  3. springboot整合spring data jpa 动态查询

    Spring Data JPA虽然大大的简化了持久层的开发,但是在实际开发中,很多地方都需要高级动态查询,在实现动态查询时我们需要用到Criteria API,主要是以下三个: 1.Criteria ...

  4. springboot集成Spring Data JPA数据查询

    1.JPA介绍 JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据.它的出现主要是为 ...

  5. spring boot学习(4) SpringBoot 之Spring Data Jpa 支持(1)

    第一节:Spring Data Jpa 简介 Spring-Data-Jpa JPA(Java Persistence API)定义了一系列对象持久化的标准,目前实现这一规范的产品有Hibernate ...

  6. IntelliJ IDEA 2017版 spring-boot使用Spring Data JPA搭建基础版的三层架构

    1.配置环境pom <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...

  7. IntelliJ IDEA 2017版 spring-boot使用Spring Data JPA使用Repository<T, T>编程

    1.环境搭建pom.xml搭建 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=& ...

  8. spring boot学习(5) SpringBoot 之Spring Data Jpa 支持(2)

    第三节:自定义查询@Query 有时候复杂sql使用hql方式无法查询,这时候使用本地查询,使用原生sql的方式:   第四节:动态查询Specification 使用 什么时候用呢?比如搜索有很多条 ...

  9. PostgreSQL 、springboot 、spring data jpa 集成

    项目地址:https://gitee.com/zhxs_code/PostgreSQL_springboot_jpa_demo.git 增删查改都已经实现. 重点部分: 1.定义自己的方言. pack ...

随机推荐

  1. 张高兴的 Windows 10 IoT 开发笔记:串口红外编解码模块 YS-IRTM

    This is a Windows 10 IoT Core project on the Raspberry Pi 2/3, coded by C#. GitHub: https://github.c ...

  2. python设计模式-观察者

    定义: 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖的对象都会得到通知并被自动更新. 观察者模式是对象的行为模式,又叫发布-订阅(pubish/subscribe)模式,模型 ...

  3. 【Java】广州三本秋招经历

    前言 只有光头才能变强 离上次发文章已经快两个月时间了,最近一直忙着秋招的事.今天是2018年10月22日,对于互联网行业来说,秋招就基本结束了.我这边的流程也走完了(不再笔试/面试了),所以来写写我 ...

  4. Spring Boot整合Mybatis并完成CRUD操作

    MyBatis 是一款优秀的持久层框架,被各大互联网公司使用,本文使用Spring Boot整合Mybatis,并完成CRUD操作. 为什么要使用Mybatis?我们需要掌握Mybatis吗? 说的官 ...

  5. 解决Error:All flavors must now belong to a named flavor dimension. Learn more at...

    低版本的gradle里面不会出现这个错误,高版本出现,不多说,看如何解决 在defaultConfig{}中添加:flavorDimensions "default" 保证所有的f ...

  6. 还在用AIDL吗?试试EasyMessenger吧

    EasyMessenger 直达Github项目地址 一款用于Android平台的基于Binder的进程间通信库,采用annotationProcessor生成IPC通信需要的代码.EasyMesse ...

  7. Kindle Windows版本 中文字体修改工具

    近来想要用Windows看Kindle电子书,无奈Windows 版本的Kindle不能修改中文字体,非常难看.把Kindle拉到IDA PRO看了一下,发现Kindle Windows版本的中文字体 ...

  8. Jmeter + Grafana搭建实时监控可视化

    小贴士: 建议使用jmeter3.3+版本,在这个版本以后才有backend listenter 对接influxDB. Jmeter中backend listenter如图 ​ influxdbUr ...

  9. SVN的安装与配置

    单独安装 SVN:1.安装:yum -y install subversionmkdir -p /data/svn/ 创建创库目录svnadmin create /data/svn/repos 构建版 ...

  10. Mysql B+Tree原理

    B+树索引是B+树在数据库中的一种实现,是最常见也是数据库中使用最为频繁的一种索引.B+树中的B代表平衡(balance),而不是二叉(binary),因为B+树是从最早的平衡二叉树演化而来的.在讲B ...