IT评测·应用市场-qidao123.com

标题: Java读取数据库表(二) [打印本页]

作者: 汕尾海湾    时间: 2023-5-4 23:47
标题: Java读取数据库表(二)
Java读取数据库表(二)


application.properties
  1. db.driver.name=com.mysql.cj.jdbc.Driver
  2. db.url=jdbc:mysql://localhost:3306/easycrud?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
  3. db.username=root
  4. db.password=xpx24167830
  5. #是否忽略表前缀
  6. ignore.table.prefix=true
  7. #参数bean后缀
  8. suffix.bean.param=Query
复制代码
辅助阅读

配置文件中部分信息被读取到之前文档说到的Constants.java中以常量的形式存储,BuildTable.java中会用到,常量命名和上面类似。
StringUtils.java
  1. package com.easycrud.utils;
  2. /**
  3. * @BelongsProject: EasyCrud
  4. * @BelongsPackage: com.easycrud.utils
  5. * @Author: xpx
  6. * @Email: 2436846019@qq.com
  7. * @CreateTime: 2023-05-03  13:30
  8. * @Description: 字符串大小写转换工具类
  9. * @Version: 1.0
  10. */
  11. public class StringUtils {
  12.     /**
  13.      * 首字母转大写
  14.      * @param field
  15.      * @return
  16.      */
  17.     public static String uperCaseFirstLetter(String field) {
  18.         if (org.apache.commons.lang3.StringUtils.isEmpty(field)) {
  19.             return field;
  20.         }
  21.         return field.substring(0, 1).toUpperCase() + field.substring(1);
  22.     }
  23.     /**
  24.      * 首字母转小写
  25.      * @param field
  26.      * @return
  27.      */
  28.     public static String lowerCaseFirstLetter(String field) {
  29.         if (org.apache.commons.lang3.StringUtils.isEmpty(field)) {
  30.             return field;
  31.         }
  32.         return field.substring(0, 1).toLowerCase() + field.substring(1);
  33.     }
  34.     /**
  35.      * 测试
  36.      * @param args
  37.      */
  38.     public static void main(String[] args) {
  39.         System.out.println(lowerCaseFirstLetter("Abcdef"));
  40.         System.out.println(uperCaseFirstLetter("abcdef"));
  41.     }
  42. }
复制代码
辅助阅读

org.apache.commons.lang3.StringUtils.isEmpty()

只能判断String类型是否为空(org.springframework.util包下的Empty可判断其他类型),源码如下
  1. public static boolean isEmpty(final CharSequence cs) {
  2.         return cs == null || cs.length() == 0;
  3. }
复制代码
xx.toUpperCase()

字母转大写
xx.toLowerCase()

字母转小写
xx.substring()

返回字符串的子字符串
  1. 索引从0开始
  2. public String substring(int beginIndex)        //起始索引,闭
  3. public String substring(int beginIndex, int endIndex)        //起始索引到结束索引,左闭右开
复制代码
BuildTable.java完整代码
  1. package com.easycrud.builder;
  2. import com.easycrud.bean.Constants;
  3. import com.easycrud.bean.FieldInfo;
  4. import com.easycrud.bean.TableInfo;
  5. import com.easycrud.utils.JsonUtils;
  6. import com.easycrud.utils.PropertiesUtils;
  7. import com.easycrud.utils.StringUtils;
  8. import org.apache.commons.lang3.ArrayUtils;
  9. import org.slf4j.Logger;
  10. import org.slf4j.LoggerFactory;
  11. import java.sql.*;
  12. import java.util.ArrayList;
  13. import java.util.HashMap;
  14. import java.util.List;
  15. import java.util.Map;
  16. /**
  17. * @BelongsProject: EasyCrud
  18. * @BelongsPackage: com.easycrud.builder
  19. * @Author: xpx
  20. * @Email: 2436846019@qq.com
  21. * @CreateTime: 2023-05-02  18:02
  22. * @Description: 读Table
  23. * @Version: 1.0
  24. */
  25. public class BuildTable {
  26.     private static final Logger logger = LoggerFactory.getLogger(BuildTable.class);
  27.     private static Connection conn = null;
  28.     /**
  29.      * 查表信息,表名,表注释等
  30.      */
  31.     private static String SQL_SHOW_TABLE_STATUS = "show table status";
  32.     /**
  33.      * 将表结构当作表读出字段的信息,如字段名(field),类型(type),自增(extra)...
  34.      */
  35.     private static String SQL_SHOW_TABLE_FIELDS = "show full fields from %s";
  36.     /**
  37.      * 检索索引
  38.      */
  39.     private static String SQL_SHOW_TABLE_INDEX = "show index from %s";
  40.     /**
  41.      * 读配置,连接数据库
  42.      */
  43.     static {
  44.         String driverName = PropertiesUtils.getString("db.driver.name");
  45.         String url = PropertiesUtils.getString("db.url");
  46.         String user = PropertiesUtils.getString("db.username");
  47.         String password = PropertiesUtils.getString("db.password");
  48.         try {
  49.             Class.forName(driverName);
  50.             conn = DriverManager.getConnection(url,user,password);
  51.         } catch (Exception e) {
  52.             logger.error("数据库连接失败",e);
  53.         }
  54.     }
  55.     /**
  56.      * 读取表
  57.      */
  58.     public static List<TableInfo> getTables() {
  59.         PreparedStatement ps = null;
  60.         ResultSet tableResult = null;
  61.         List<TableInfo> tableInfoList = new ArrayList();
  62.         try{
  63.             ps = conn.prepareStatement(SQL_SHOW_TABLE_STATUS);
  64.             tableResult = ps.executeQuery();
  65.             while(tableResult.next()) {
  66.                 String tableName = tableResult.getString("name");
  67.                 String comment = tableResult.getString("comment");
  68.                 //logger.info("tableName:{},comment:{}",tableName,comment);
  69.                 String beanName = tableName;
  70.                 /**
  71.                  * 去xx_前缀
  72.                  */
  73.                 if (Constants.IGNORE_TABLE_PREFIX) {
  74.                     beanName = tableName.substring(beanName.indexOf("_")+1);
  75.                 }
  76.                 beanName = processFiled(beanName,true);
  77. //                logger.info("bean:{}",beanName);
  78.                 TableInfo tableInfo = new TableInfo();
  79.                 tableInfo.setTableName(tableName);
  80.                 tableInfo.setBeanName(beanName);
  81.                 tableInfo.setComment(comment);
  82.                 tableInfo.setBeanParamName(beanName + Constants.SUFFIX_BEAN_PARAM);
  83.                 /**
  84.                  * 读字段信息
  85.                  */
  86.                 readFieldInfo(tableInfo);
  87.                 /**
  88.                  * 读索引
  89.                  */
  90.                 getKeyIndexInfo(tableInfo);
  91. //                logger.info("tableInfo:{}",JsonUtils.convertObj2Json(tableInfo));
  92.                 tableInfoList.add(tableInfo);
  93. //                logger.info("表名:{},备注:{},JavaBean:{},JavaParamBean:{}",tableInfo.getTableName(),tableInfo.getComment(),tableInfo.getBeanName(),tableInfo.getBeanParamName());
  94.             }
  95.             logger.info("tableInfoList:{}",JsonUtils.convertObj2Json(tableInfoList));
  96.         }catch (Exception e){
  97.             logger.error("读取表失败",e);
  98.         }finally {
  99.             if (tableResult != null) {
  100.                 try {
  101.                     tableResult.close();
  102.                 } catch (SQLException e) {
  103.                     e.printStackTrace();
  104.                 }
  105.             }
  106.             if (ps != null) {
  107.                 try {
  108.                     ps.close();
  109.                 } catch (SQLException e) {
  110.                     e.printStackTrace();
  111.                 }
  112.             }
  113.             if (conn != null) {
  114.                 try {
  115.                     conn.close();
  116.                 } catch (SQLException e) {
  117.                     e.printStackTrace();
  118.                 }
  119.             }
  120.         }
  121.         return tableInfoList;
  122.     }
  123.     /**
  124.      * 将表结构当作表读出字段的信息,如字段名(field),类型(type),自增(extra)...
  125.      * @param tableInfo
  126.      * @return
  127.      */
  128.     private static void readFieldInfo(TableInfo tableInfo) {
  129.         PreparedStatement ps = null;
  130.         ResultSet fieldResult = null;
  131.         List<FieldInfo> fieldInfoList = new ArrayList();
  132.         try{
  133.             ps = conn.prepareStatement(String.format(SQL_SHOW_TABLE_FIELDS,tableInfo.getTableName()));
  134.             fieldResult = ps.executeQuery();
  135.             while(fieldResult.next()) {
  136.                 String field = fieldResult.getString("field");
  137.                 String type = fieldResult.getString("type");
  138.                 String extra = fieldResult.getString("extra");
  139.                 String comment = fieldResult.getString("comment");
  140.                 /**
  141.                  * 类型例如varchar(50)我们只需要得到varchar
  142.                  */
  143.                 if (type.indexOf("(") > 0) {
  144.                     type = type.substring(0, type.indexOf("("));
  145.                 }
  146.                 /**
  147.                  * 将aa_bb变为aaBb
  148.                  */
  149.                 String propertyName = processFiled(field, false);
  150. //                logger.info("f:{},p:{},t:{},e:{},c:{},",field,propertyName,type,extra,comment);
  151.                 FieldInfo fieldInfo = new FieldInfo();
  152.                 fieldInfoList.add(fieldInfo);
  153.                 fieldInfo.setFieldName(field);
  154.                 fieldInfo.setComment(comment);
  155.                 fieldInfo.setSqlType(type);
  156.                 fieldInfo.setAutoIncrement("auto_increment".equals(extra) ? true : false);
  157.                 fieldInfo.setPropertyName(propertyName);
  158.                 fieldInfo.setJavaType(processJavaType(type));
  159. //                logger.info("JavaType:{}",fieldInfo.getJavaType());
  160.                 if (ArrayUtils.contains(Constants.SQL_DATE_TIME_TYPES, type)) {
  161.                     tableInfo.setHaveDataTime(true);
  162.                 }else {
  163.                     tableInfo.setHaveDataTime(false);
  164.                 }
  165.                 if (ArrayUtils.contains(Constants.SQL_DATE_TYPES, type)) {
  166.                     tableInfo.setHaveData(true);
  167.                 }else {
  168.                     tableInfo.setHaveData(false);
  169.                 }
  170.                 if (ArrayUtils.contains(Constants.SQL_DECIMAL_TYPE, type)) {
  171.                     tableInfo.setHaveBigDecimal(true);
  172.                 }else {
  173.                     tableInfo.setHaveBigDecimal(false);
  174.                 }
  175.             }
  176.             tableInfo.setFieldList(fieldInfoList);
  177.         }catch (Exception e){
  178.             logger.error("读取表失败",e);
  179.         }finally {
  180.             if (fieldResult != null) {
  181.                 try {
  182.                     fieldResult.close();
  183.                 } catch (SQLException e) {
  184.                     e.printStackTrace();
  185.                 }
  186.             }
  187.             if (ps != null) {
  188.                 try {
  189.                     ps.close();
  190.                 } catch (SQLException e) {
  191.                     e.printStackTrace();
  192.                 }
  193.             }
  194.         }
  195.     }
  196.     /**
  197.      * 检索唯一索引
  198.      * @param tableInfo
  199.      * @return
  200.      */
  201.     private static List<FieldInfo> getKeyIndexInfo(TableInfo tableInfo) {
  202.         PreparedStatement ps = null;
  203.         ResultSet fieldResult = null;
  204.         List<FieldInfo> fieldInfoList = new ArrayList();
  205.         try{
  206.             /**
  207.              * 缓存Map
  208.              */
  209.             Map<String,FieldInfo> tempMap = new HashMap();
  210.             /**
  211.              * 遍历表中字段
  212.              */
  213.             for (FieldInfo fieldInfo : tableInfo.getFieldList()) {
  214.                 tempMap.put(fieldInfo.getFieldName(),fieldInfo);
  215.             }
  216.             ps = conn.prepareStatement(String.format(SQL_SHOW_TABLE_INDEX,tableInfo.getTableName()));
  217.             fieldResult = ps.executeQuery();
  218.             while(fieldResult.next()) {
  219.                 String keyName = fieldResult.getString("key_name");
  220.                 Integer nonUnique = fieldResult.getInt("non_unique");
  221.                 String columnName = fieldResult.getString("column_name");
  222.                 /**
  223.                  * 0是唯一索引,1不唯一
  224.                  */
  225.                 if (nonUnique == 1) {
  226.                     continue;
  227.                 }
  228.                 List<FieldInfo> keyFieldList = tableInfo.getKeyIndexMap().get(keyName);
  229.                 if (null == keyFieldList) {
  230.                     keyFieldList = new ArrayList();
  231.                     tableInfo.getKeyIndexMap().put(keyName,keyFieldList);
  232.                 }
  233.                 keyFieldList.add(tempMap.get(columnName));
  234.             }
  235.         }catch (Exception e){
  236.             logger.error("读取索引失败",e);
  237.         }finally {
  238.             if (fieldResult != null) {
  239.                 try {
  240.                     fieldResult.close();
  241.                 } catch (SQLException e) {
  242.                     e.printStackTrace();
  243.                 }
  244.             }
  245.             if (ps != null) {
  246.                 try {
  247.                     ps.close();
  248.                 } catch (SQLException e) {
  249.                     e.printStackTrace();
  250.                 }
  251.             }
  252.         }
  253.         return fieldInfoList;
  254.     }
  255.     /**
  256.      * aa_bb__cc==>AaBbCc || aa_bb_cc==>aaBbCc
  257.      * @param field
  258.      * @param uperCaseFirstLetter,首字母是否大写
  259.      * @return
  260.      */
  261.     private static String processFiled(String field,Boolean uperCaseFirstLetter) {
  262.         StringBuffer sb = new StringBuffer();
  263.         String[] fields=field.split("_");
  264.         sb.append(uperCaseFirstLetter ? StringUtils.uperCaseFirstLetter(fields[0]):fields[0]);
  265.         for (int i = 1,len = fields.length; i < len; i++){
  266.             sb.append(StringUtils.uperCaseFirstLetter(fields[i]));
  267.         }
  268.         return sb.toString();
  269.     }
  270.     /**
  271.      * 为数据库字段类型匹配对应Java属性类型
  272.      * @param type
  273.      * @return
  274.      */
  275.     private static String processJavaType(String type) {
  276.         if (ArrayUtils.contains(Constants.SQL_INTEGER_TYPE,type)) {
  277.             return "Integer";
  278.         }else if (ArrayUtils.contains(Constants.SQL_LONG_TYPE,type)) {
  279.             return "Long";
  280.         }else if (ArrayUtils.contains(Constants.SQL_STRING_TYPE,type)) {
  281.             return "String";
  282.         }else if (ArrayUtils.contains(Constants.SQL_DATE_TIME_TYPES,type) || ArrayUtils.contains(Constants.SQL_DATE_TYPES,type)) {
  283.             return "Date";
  284.         }else if (ArrayUtils.contains(Constants.SQL_DECIMAL_TYPE,type)) {
  285.             return "BigDecimal";
  286.         }else {
  287.             throw new RuntimeException("无法识别的类型:"+type);
  288.         }
  289.     }
  290. }
复制代码
辅助阅读

去表名前缀,如tb_test-->test
  1. beanName = tableName.substring(beanName.indexOf("_")+1);
复制代码
indexOf("_")定位第一次出现下划线的索引位置,substring截取后面的字符串。
processFiled(String,Boolean)

自定义方法,用于将表名或字段名转换为Java中的类名或属性名,如aa_bb__cc-->AaBbCc || aa_bb_cc-->aaBbCc
processFiled(String,Boolean)中的String[] fields=field.split("_")

xx.split("_")是将xx字符串按照下划线进行分割。
processFiled(String,Boolean)中的append()

StringBuffer类包含append()方法,相当于“+”,将指定的字符串追加到此字符序列。
processJavaType(String)

自定义方法,用于做数据库字段类型与Java属性类型之间的匹配。
processJavaType(String)中的ArrayUtils.contains(A,B)

判断B是否在A中出现过。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4