文档章节

编写自己的代码生成工具四:数据库信息查询实现

Yemon
 Yemon
发布于 2016/05/17 10:33
字数 1126
阅读 5
收藏 0
点赞 2
评论 0

数据库信息的查询,无非就是查询表拥有的列,列的备注以及表的主键,实现起来十分简单。

这里主要考虑的就是,如何能有一个好的扩展,在更换数据库的时候可以方便的切换而不用修改源代码。

我们先来定义一个接口,这个接口只有一个方法,就是查询表的列信息:


  
  1. /**
  2. * 数据库操作接口
  3. *
  4. * User: liyd
  5. * Date: 13-12-6
  6. * Time: 上午10:30
  7. */
  8. public interface DatabaseProvider {
  9. /**
  10. * 获取数据库表的信息
  11. *
  12. * @param tableName 表名
  13. * @return meta data
  14. */
  15. public List<Column> getTableMetaData(String tableName);
  16. }

Column类代码如下:


  
  1. /**
  2. * 列信息
  3. *
  4. * User: liyd
  5. * Date: 13-11-28
  6. * Time: 下午5:19
  7. */
  8. public class Column {
  9. /** 列名 */
  10. private String name;
  11. /** 是否主键 */
  12. private boolean isPrimaryKey;
  13. /** 列备注 */
  14. private String comment;
  15. /** 数据库类型 */
  16. private String dbType;
  17. /** jdbc类型 */
  18. private String jdbcType;
  19. /** java类型 例:String */
  20. private String javaType;
  21. /** java类型class名称例:java.lang.String */
  22. private String javaClass;
  23. getter and setter...
  24. }

定义了接口,接下来就是要实现它了,但是如果我们直接进行实现,那么数据库连接的获取关闭等操作都要在这个方法里面完成,而且每实现一个数据查询类都需要这些,将会比较麻烦。因此,我们先来一个抽象的实现:


  
  1. /**
  2. * 数据库操作抽象类
  3. *
  4. * User: liyd
  5. * Date: 13-12-6
  6. * Time: 上午11:13
  7. */
  8. public abstract class AbstractDatabaseProvider implements DatabaseProvider {
  9. /**
  10. * 获取数据库表的信息
  11. *
  12. * @param tableName 表名
  13. * @return meta data
  14. */
  15. @Override
  16. public List<Column> getTableMetaData(String tableName) {
  17. Connection connection = DBUtils.getDefaultConnection();
  18. return getMetaData(tableName, connection);
  19. }
  20. /**
  21. * 获取数据库表元信息
  22. *
  23. * @param tableName the table name
  24. * @param connection the connection
  25. * @return meta data
  26. */
  27. public abstract List<Column> getMetaData(String tableName, Connection connection);
  28. }

在这个抽象类中,我们统一对数据库连接进行了获取,然后再调用getMetaData(String tableName, Connection connection)方法将表名和连接对象作为参数传入,由子类来实现。

这里获取的连接即是前面在代码生成组织者GenerationOrganizer中创建打开的连接,这里只进行获取,由外围负责打开和关闭。这样做的好处是一次性生成多张表的时候,连接只打开和关闭一次。还有就是具体的实现者不用关心这个连接是哪里来的,不会迷惑于连接到底是自己创建还是从哪里获取,清晰明了。

下面贴上具体的mysql实现类:


  
  1. /**
  2. * mysql操作类
  3. *
  4. * User: liyd
  5. * Date: 14-1-13
  6. * Time: 上午11:40
  7. */
  8. public class MysqlProvider extends AbstractDatabaseProvider {
  9. /**
  10. * 获取数据库表元信息
  11. *
  12. * @param tableName the table name
  13. * @param connection the connection
  14. * @return meta data
  15. */
  16. @Override
  17. public List<Column> getMetaData(String tableName, Connection connection) {
  18. List<Column> columnList = new ArrayList<Column>();
  19. PreparedStatement pst = null;
  20. ResultSet rs = null;
  21. ResultSetMetaData rsd = null;
  22. try {
  23. //查询时没有数据,只返回表头信息
  24. pst = connection.prepareStatement("select * from " + tableName + " where 1=2");
  25. rsd = pst.executeQuery().getMetaData();
  26. //查询主键
  27. String primaryKey = null;
  28. pst = connection
  29. .prepareStatement("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE CONSTRAINT_NAME='PRIMARY' and TABLE_NAME = ?");
  30. pst.setString(1, tableName.toUpperCase());
  31. rs = pst.executeQuery();
  32. if (rs.next()) {
  33. primaryKey = rs.getString(1);
  34. }
  35. //查询列备注
  36. pst = connection
  37. .prepareStatement("select column_name, column_comment from information_schema.columns where table_name = ?");
  38. pst.setString(1, tableName.toUpperCase());
  39. rs = pst.executeQuery();
  40. //先将注释放入到map再获取,防止有些列没有注释获取不对应的问题
  41. Map<String, String> commentMap = new HashMap<String, String>();
  42. while (rs.next()) {
  43. commentMap.put(rs.getString("COLUMN_NAME"), rs.getString("column_comment"));
  44. }
  45. for (int i = 1; i <= rsd.getColumnCount(); i++) {
  46. String name = rsd.getColumnName(i);
  47. String dbType = rsd.getColumnTypeName(i);
  48. String javaClass = rsd.getColumnClassName(i);
  49. String comment = commentMap.get(name);
  50. boolean b = StringUtils.equalsIgnoreCase(primaryKey, name) ? true : false;
  51. Column column = new Column();
  52. column.setName(name);
  53. column.setDbType(dbType);
  54. column.setJdbcType(dbType);
  55. column.setJavaClass(javaClass);
  56. column.setComment(comment);
  57. column.setIsPrimaryKey(b);
  58. columnList.add(column);
  59. }
  60. } catch (SQLException e) {
  61. throw new EasyCodeException(e);
  62. } finally {
  63. try {
  64. if (pst != null) {
  65. pst.close();
  66. }
  67. if (rs != null) {
  68. rs.close();
  69. }
  70. } catch (SQLException e) {
  71. //ignore
  72. }
  73. }
  74. return columnList;
  75. }
  76. }

oracle的实现类:


  
  1. /**
  2. * Oracle 操作类
  3. *
  4. * User: liyd
  5. * Date: 13-12-6
  6. * Time: 上午11:11
  7. */
  8. public class OracleProvider extends AbstractDatabaseProvider {
  9. /**
  10. * 获取数据库表元信息
  11. *
  12. * @param tableName the table name
  13. * @param connection the connection
  14. * @return meta data
  15. */
  16. @Override
  17. public List<Column> getMetaData(String tableName, Connection connection) {
  18. List<Column> columnList = new ArrayList<Column>();
  19. PreparedStatement pst = null;
  20. ResultSet rs = null;
  21. ResultSetMetaData rsd = null;
  22. try {
  23. //查询时没有数据,只返回表头信息
  24. pst = connection.prepareStatement("select * from " + tableName + " where 1=2");
  25. rsd = pst.executeQuery().getMetaData();
  26. //查询主键
  27. String primaryKey = null;
  28. pst = connection
  29. .prepareStatement("select col.column_name from user_constraints con, user_cons_columns col where con.constraint_name = col.constraint_name and con.constraint_type = 'P' and col.table_name = ?");
  30. pst.setString(1, tableName.toUpperCase());
  31. rs = pst.executeQuery();
  32. if (rs.next()) {
  33. primaryKey = rs.getString(1);
  34. }
  35. //查询列备注
  36. pst = connection
  37. .prepareStatement("SELECT * FROM USER_COL_COMMENTS WHERE TABLE_NAME = ?");
  38. pst.setString(1, tableName.toUpperCase());
  39. rs = pst.executeQuery();
  40. //先将注释放入到map再获取,防止有些列没有注释获取不对应的问题
  41. Map<String, String> commentMap = new HashMap<String, String>();
  42. while (rs.next()) {
  43. commentMap.put(rs.getString("COLUMN_NAME"), rs.getString("COMMENTS"));
  44. }
  45. for (int i = 1; i <= rsd.getColumnCount(); i++) {
  46. String name = rsd.getColumnName(i);
  47. String dbType = rsd.getColumnTypeName(i);
  48. String javaClass = rsd.getColumnClassName(i);
  49. String comment = commentMap.get(name);
  50. boolean b = StringUtils.equalsIgnoreCase(primaryKey, name) ? true : false;
  51. Column column = new Column();
  52. column.setName(name);
  53. column.setDbType(dbType);
  54. column.setJdbcType(dbType);
  55. column.setJavaClass(javaClass);
  56. column.setComment(comment);
  57. column.setIsPrimaryKey(b);
  58. columnList.add(column);
  59. }
  60. } catch (SQLException e) {
  61. throw new EasyCodeException(e);
  62. } finally {
  63. try {
  64. if (pst != null) {
  65. pst.close();
  66. }
  67. if (rs != null) {
  68. rs.close();
  69. }
  70. } catch (SQLException e) {
  71. }
  72. }
  73. return columnList;
  74. }

本文转载自:http://blog.csdn.net/hj7jay/article/details/51130540

共有 人打赏支持
Yemon
粉丝 10
博文 320
码字总数 22799
作品 0
广州
架构师
敢不敢更懒,自己编写的mysql C++自动代码生成工具

我一直有一个梦想,就是那天能够让计算机去帮我编写代码,而我只需要将我自己的规划告诉它,就可以自动生成我需要的代码。 梦想永远是梦想,一定要自己一步步的去实现,否则和咸鱼有什么区别...

自由的眼
2016/12/13
80
0
基于 JavaFX8 的图形界面 Spring 代码生成器 - Spring-generator

Spring-generator 是基于 javafx8 开发的图形界面 Spring 代码生成器,使用 Apache FreeMarker 作为代码文件的模板,用户可以一键将数据库中的表生成为任意风格的 .java 代码文件(比如经典的...

Mirren
06/19
0
0
Spring-generator 1.0.0 版正式发布,Spring 代码生成器

Spring-generator是基于javafx8开发的图形界面Spring代码生成器,使用 Apache FreeMarker作为代码文件的模板,用户可以一键将数据库中的表生成为任意风格的.java代码文件(比如经典的三层模型)...

Mirren
06/19
0
0
ShenzhenMirren/Spring-generator

基本介绍 官方QQ交流群号:519714660; Spring-generator是基于javafx8开发的图形界面Spring代码生成器,使用 Apache FreeMarker 作为代码文件的模板,用户可以一键将数据库中的表生成为任意风格...

ShenzhenMirren
06/19
0
0
OpenJWeb(v1.0) Java Web快速开发平台功能清单

一、OpenJWeb功能清单 OpenJWeb作为一款Java快速Web应用开发平台产品,目前提供了以下功能: 序 功能点 功能说明 1 系统基础数据—数据字典类型定义 定义数据字典类型,即编码种类 2 系统基础...

迷途d书童
2012/03/09
196
0
OpenJWeb的网友评论

OpenJWeb是一款基于Java技术实现的快速Web应用开发平台。为什么说此平台是一个快速的应用开发平台?因为此平台提供了各种功能创建 向导,用户可以完全通过平台的功能创建向导来创建自己的需要...

红薯
2009/12/11
1K
9
Web应用开发平台--OpenJWeb

OpenJWeb是一款基于Java技术实现的快速Web应用开发平台。为什么说此平台是一个快速的应用开发平台?因为此平台提供了各种功能创建 向导,用户可以完全通过平台的功能创建向导来创建自己的需要...

王保政
2009/04/02
20K
2
自己写的.Net(C#)代码自动生成器

这个东西其实是一年半前就写了,那时候看到很多代码都是一些有规律的重复劳动。所以,想写个工具来代替,一来节省时间,二来提高效率。更重要的让自己减轻劳动:)。但后来一直忙,也没怎么继续...

长平狐
2012/11/12
960
0
从零开始编写自己的C#框架(11)——创建解决方案

 这段时间一直在充电,拜读了园子中大神们的博文(wayfarer的《设计之道》、TerryLee的《.NET设计模式系列文章》、卡奴达摩的《设计模式》还有其他一些零散的文章),获益良多,虽然对大部分...

技术小胖子
2017/11/10
0
0
jeecg-framework-3.3.2-RELEASE 最新版本发布

平台介绍 JEECG(J2EE CodeGeneration)是一款基于代码生成器的智能开发平台,引领新开发模式(OnlineCoding模式->代码生成器模式->手工MERGE智能开发),可以帮助解决Java项目60%的重复工作,...

Jeecg
2013/09/02
0
1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

CVE-2013-0077 堆溢出分析

找了很久才发现这个环境比较容易搭建分析... 环境: 系统---Win XP SP3 漏洞程序:QQPlayer 3.7.892.400 出错DLL:quartz.dll 6.5.2600.5512 调试工具:x32db+gflag.exe 过程: 首先gflag设置...

Explorer0
11分钟前
1
0
python上传文件

//注意 <form action="/login/" method="post" enctype="multipart/form-data"> f=request.FILES.get('fafa') ff=open(f.name,mode='wb') for i in f.chunks(): ff.write(i) ff.close()......

南桥北木
23分钟前
0
0
CISCO VPN Client Reason 442 WIN8/10错误解决方案

http://jdkleo.iteye.com/blog/2163493 引用 http://my.oschina.net/cloudcoder/blog/220391?p={{currentPage 1}} 在使用cisco VPN 客户端登录时,产生Reason 442:Failedto enable Virtual......

chenfj_fer
26分钟前
0
0
信号量有没有容量限制?

之前一直误以为信号量初始化的时候那个初始化的值是信号量的“容量”,昨天同事指出了我的错误,最初我是不相信的,经过以下代码实践,证明了我的错误: Java版: import java.util.concurr...

锟斤拷烫烫烫
30分钟前
0
0
【RocketMQ】Message存储笔记

概述 消息中间件存储分为三种,一是保存在内存中,速度快但会因为系统宕机等因素造成消息丢失;二是保存在内存中,同时定时将消息写入DB中,好处是持久化消息,如何读写DB是MQ的瓶颈;三是内...

SaintTinyBoy
41分钟前
0
0
Android应用Context详解及源码解析

Android应用Context详解及源码解析 本文定位:优质文章收集 本文转载 1 背景 今天突然想起之前在上家公司(做TV与BOX盒子)时有好几个人问过我关于Android的Context到底是啥的问题,所以就马...

lichuangnk
今天
0
0
PostgreSQL的昨天今天和明天

PostgreSQL 是一种非常复杂的对象-关系型数据库管理系统(ORDBMS), 也是目前功能最强大,特性最丰富和最复杂的自由软件数据库系统。有些特性甚至连商业数据库都不具备。 这个起源于伯克利(...

闻术苑
今天
1
0
Mysql对自增主键ID进行重新排序

1,删除原有主键: ALTER TABLE `table_name` DROP `id`; 2,添加新主键字段: ALTER TABLE `table_name` ADD `id` MEDIUMINT( 8 ) NOT NULL FIRST; 3,设置新主键: ALTER TABLE `table_nam......

niithub
今天
0
0
福利篇:免费csdn vip账号分享

分享一个发布免费csdn vip账号的网站:啰嗦vip www.lostvip.com , 各种软件开发类的视频教程:慕课网、动脑学院、黑马各大培训机构VIP视频教程,非常不错!

在水一方发盐人
今天
1
0
Nginx+Tomcat搭建高性能负载均衡集群

一、 工具   nginx-1.8.0   apache-tomcat-6.0.33 二、 目标   实现高性能负载均衡的Tomcat集群:    三、 步骤   1、首先下载Nginx,要下载稳定版:      2、然后解压两个Tom...

码代码的小司机
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部