Java通过实体类生成建表的sql语句-二

比眉伴天荒 2023-10-09 23:13 177阅读 0赞

方式一:

  1. package com.xz;
  2. import com.xz.entity.IndexProduct;//本地实体类
  3. import com.xz.entity.User;//本地实体类
  4. import java.io.BufferedWriter;
  5. import java.io.File;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;
  8. import java.io.OutputStreamWriter;
  9. import java.lang.annotation.Annotation;
  10. import java.lang.reflect.Field;
  11. import javax.xml.bind.annotation.XmlElement;
  12. public class CreateTable {
  13. /**
  14. * @param args
  15. * @throws IOException
  16. */
  17. public static void main(String[] args) throws IOException {
  18. createTable(User.class, null);
  19. // createTable(Book.class, null);
  20. }
  21. public static void createTable(Class obj,String tableName) throws IOException{
  22. Field[] fields = null;
  23. fields = obj.getDeclaredFields();
  24. Class annotationType = null;
  25. Object param = null;
  26. String column = null;
  27. XmlElement xmlElement = null;
  28. StringBuilder sb = null;
  29. sb = new StringBuilder(50);
  30. if(tableName==null||tableName.equals("")){
  31. //未传表明默认用类名
  32. tableName = obj.getName();
  33. tableName = tableName.substring(tableName.lastIndexOf(".")+1);
  34. }
  35. sb.append("\r\ndrop table if exists ").append(tableName).append(";\r\n");
  36. sb.append("create table ").append(tableName).append(" ( \r\n");
  37. System.out.println(tableName);
  38. boolean firstId = true;
  39. File file = null;
  40. for(Field f:fields){
  41. column = f.getName();
  42. sb.append(column).append(" ");
  43. System.out.println(column+","+f.getType());
  44. param = f.getType();
  45. sb.append(column);//一般第一个是主键
  46. if(param instanceof Integer){
  47. sb.append(" INTEGER ");
  48. }else{
  49. sb.append(" VARCHAR(30) ");//根据需要自行修改
  50. }
  51. if(firstId){//类型转换
  52. sb.append(" PRIMARY KEY ");
  53. firstId = false;
  54. }
  55. //获取字段中包含fieldMeta的注解
  56. //2、获取属性上的所有注释
  57. Annotation[] allAnnotations = f.getAnnotations();
  58. for(Annotation an : allAnnotations){
  59. sb.append(" COMMIT '");
  60. xmlElement = (XmlElement)an;
  61. annotationType = an.annotationType();
  62. param = ((XmlElement) an).name();
  63. System.out.println("属性【"+f.getName()+"-----的注释类型有: " + param);
  64. sb.append(param).append("'");
  65. }
  66. sb.append(",\n ");
  67. }
  68. String sql = null;
  69. sql = sb.toString();
  70. sql = sb.substring(0, sql.length()-1)+" )ENGINE =INNODB DEFAULT CHARSET= utf8;\r\n";
  71. file = new File("WebContent/createTable/User.sql"); //文件保存路径与命名
  72. if (!file.getParentFile().exists()) {
  73. if (!file.getParentFile().mkdirs()) {
  74. }
  75. }
  76. if (!file.exists()) {
  77. file.createNewFile();
  78. }
  79. System.out.println("文件路径:"+file.getAbsolutePath());
  80. BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file,true)));
  81. out.write(sql) ;
  82. out.flush();
  83. out.close() ;
  84. }
  85. }

实体类:

  1. package com.xz.entity;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. @Data
  6. //使用这个注解,就不用再去手写Getter,Setter,equals,canEqual,hasCode,toString等方法了,注解后在编译时会自动加进去。
  7. @AllArgsConstructor
  8. //使用后添加一个构造函数,该构造函数含有所有已声明字段属性参数
  9. @NoArgsConstructor
  10. //使用后创建一个无参构造函数
  11. public class User {
  12. private int uid;
  13. private String uname;
  14. private String upwd;
  15. private String email;
  16. private String phone;
  17. private String avatar;
  18. private String user_name;
  19. private int gender;
  20. }

成功演示:

在这里插入图片描述

方式二:

  1. package com.xz;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. import java.io.File;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.lang.reflect.Field;
  8. import java.util.ArrayList;
  9. import java.util.HashMap;
  10. import java.util.List;
  11. import java.util.Map;
  12. public class SqlGenerator {
  13. private static final Logger logger = LoggerFactory.getLogger(SqlGenerator.class);
  14. /**
  15. * 用来存储Java等属性类型与sql中属性类型的对照
  16. * </br>
  17. * 例如:java.lang.Integer 对应 integer
  18. */
  19. public static Map<String, String> map = new HashMap<>();
  20. public static void main(String[] args) {
  21. map.put("class java.lang.String", "varchar(255)");
  22. map.put("class java.lang.Integer", "int");
  23. map.put("class java.lang.Long", "integer unsigned");
  24. map.put("class java.lang.byte[]", "blob");
  25. map.put("class java.lang.Boolean", "bit");
  26. map.put("class java.math.BigInteger", "bigint unsigned");
  27. map.put("class java.lang.Float", "float");
  28. map.put("class java.lang.Double", "double");
  29. map.put("class java.sql.Date", "datetime");
  30. map.put("class java.sql.Time", "time");
  31. map.put("class java.sql.Timestamp", "datetime");
  32. map.put("class java.util.Date", "datetime");
  33. map.put("class java.time.LocalDateTime", "datetime");
  34. map.put("class java.time.LocalDate", "date");
  35. map.put("class java.time.LocalTime", "time");
  36. map.put("class java.lang.Byte", "tinyint");
  37. map.put("class java.math.BigDecimal", "decimal");
  38. //实体类所在的package在磁盘上的绝对路径
  39. String packageName = "D:/pro/m_system/src/main/java/com/test/model/entity";
  40. //生成的sql文件名
  41. String sqlName = "entityToSql";
  42. //生成sql的文件夹
  43. String filePath = "D:/pscp/" + sqlName;
  44. //表命名前缀
  45. String tablePrefix = "is_";
  46. //项目中实体类的路径,(可以不用修改)
  47. // String prefix = "com.test.model.entity.";
  48. String prefix = packageName.substring(packageName.indexOf("java") + 5).replace("/", ".") + ".";
  49. //开始构造sql
  50. sqlConstruction(packageName, filePath, prefix, tablePrefix);
  51. }
  52. /**
  53. * 生成sql建库语句
  54. * @param tablePrefix 表命名前缀
  55. * @param packageName 实体类所在的package在磁盘上的绝对路径
  56. * @param filePath 生成sql的文件夹
  57. * @param prefix 项目中实体类的路径
  58. */
  59. private static void sqlConstruction(String packageName, String filePath, String prefix, String tablePrefix) {
  60. String className = "";
  61. StringBuffer sqls = new StringBuffer();
  62. //获取包下的所有类名称
  63. List<String> list = getAllClasses(packageName);
  64. for (String str : list) {
  65. className = prefix + str.substring(0, str.lastIndexOf("."));
  66. String sql = generateSql(className, tablePrefix);
  67. sqls.append(sql);
  68. }
  69. StringToSql(sqls.toString(), filePath + ".sql");
  70. }
  71. /**
  72. * 根据实体类生成建表语句
  73. *
  74. * @param className 全类名
  75. * @param tablePrefix 表命名前缀
  76. * @return
  77. */
  78. public static String generateSql(String className, String tablePrefix) {
  79. try {
  80. Class<?> clz = Class.forName(className);
  81. className = clz.getSimpleName();
  82. // 表表名adminUser → tb_admin_user
  83. className = tablePrefix + getStandardFields(className);
  84. Field[] fields = clz.getDeclaredFields();
  85. StringBuffer column = new StringBuffer();
  86. String varchar = " CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,";
  87. for (Field f : fields) {
  88. if ("class java.lang.String".equals(f.getType().toString())){
  89. column.append(" \n `" + getStandardFields(f.getName()) + "`" + " " + map.get(f.getType().toString())).append(varchar);
  90. }else {
  91. column.append(" \n `" + getStandardFields(f.getName()) + "`" + " " + map.get(f.getType().toString())).append(",");
  92. }
  93. }
  94. //已单独指定id列的生成语句,去掉多余id的拼接
  95. String column1 = column.substring(column.indexOf(",") + 1);
  96. StringBuffer sql = new StringBuffer();
  97. sql.append("\n -- 表 " + className + "\n")
  98. .append("\n DROP TABLE IF EXISTS `" + className + "`; ")
  99. .append(" \n CREATE TABLE `" + className + "` (")
  100. .append(" \n `id` int(11) NOT NULL AUTO_INCREMENT,")
  101. .append(" " + column1)
  102. .append(" \n PRIMARY KEY (`id`) USING BTREE,")
  103. .append("\n INDEX `id`(`id`) USING BTREE")
  104. .append(" \n ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci; \n");
  105. return sql.toString();
  106. } catch (ClassNotFoundException e) {
  107. logger.debug("该类未找到!");
  108. return null;
  109. }
  110. }
  111. /**
  112. * 转换为标准等sql字段 例如 adminUser → admin_user
  113. *
  114. * @param str 转换为字符串的字段名
  115. * @return
  116. */
  117. public static String getStandardFields(String str) {
  118. StringBuffer sb = new StringBuffer();
  119. for (int i = 0; i < str.length(); i++) {
  120. char c = str.charAt(i);
  121. //非首字母,在大写字母A到Z之间
  122. if (i != 0 && (c >= 'A' && c <= 'Z')) {
  123. sb.append("_");
  124. }
  125. sb.append(c);
  126. }
  127. return sb.toString();
  128. }
  129. /**
  130. * 获取包下面等所有实体类名称,类似于获取 XXX.java
  131. *
  132. * @param packageName 全类名
  133. * @return
  134. */
  135. public static List<String> getAllClasses(String packageName) {
  136. List<String> classList = new ArrayList();
  137. String className = "";
  138. File f = new File(packageName);
  139. if (f.exists() && f.isDirectory()) {
  140. File[] files = f.listFiles();
  141. // 遍历实体类下面等所有.java文件 获取其类名
  142. for (File file : files) {
  143. className = file.getName();
  144. classList.add(className);
  145. }
  146. return classList;
  147. } else {
  148. logger.debug("包路径未找到!");
  149. return null;
  150. }
  151. }
  152. /**
  153. * 将生成等String字符串 写进sql文件
  154. *
  155. * @param str String字符串
  156. * @param path sql文件路径路径
  157. */
  158. public static void StringToSql(String str, String path) {
  159. byte[] sourceByte = str.getBytes();
  160. FileOutputStream os = null;
  161. if (null != sourceByte) {
  162. try {
  163. //文件路径(路径+文件名)
  164. File file = new File(path);
  165. //文件不存在则创建文件,先创建目录
  166. if (!file.exists()) {
  167. File dir = new File(file.getParent());
  168. dir.mkdirs();
  169. file.createNewFile();
  170. }
  171. //文件输出流用于将数据写入文件
  172. os = new FileOutputStream(file);
  173. os.write(sourceByte);
  174. os.flush();
  175. System.out.println("生成成功!!");
  176. } catch (Exception e) {
  177. e.printStackTrace();
  178. } finally {
  179. // 关闭文件输出流
  180. try {
  181. if (os != null) {
  182. os.close();
  183. }
  184. } catch (IOException e) {
  185. e.printStackTrace();
  186. }
  187. }
  188. }
  189. }
  190. }

发表评论

表情:
评论列表 (有 0 条评论,177人围观)

还没有评论,来说两句吧...

相关阅读