1. 首先创建一个连接的Model类
public class JDBC_CONN { private String base_driver; private String base_url; private String base_name; private String base_pass; public String getBase_driver() { return base_driver; } public void setBase_driver(String base_driver) { this.base_driver = base_driver; } public String getBase_url() { return base_url; } public void setBase_url(String base_url) { this.base_url = base_url; } public String getBase_name() { return base_name; } public void setBase_name(String base_name) { this.base_name = base_name; } public String getBase_pass() { return base_pass; } public void setBase_pass(String base_pass) { this.base_pass = base_pass; } }
2. 在Controller类获得前端传递来的参数
// 根据ID,取得caravel数据集信息和Hawq的结构 @ResponseBody @RequestMapping(value="/getTableInfo/{artId}") public Map<String, Object> getTableInfo(@PathVariable String artId, @ModelAttribute JDBC_CONN JDBC_CONN) throws UnsupportedEncodingException { // 判断前端传递来的驱动是否为空 if (JDBC_CONN.getBase_driver() != "") { // 如果不为空,走自己的动态数据源 return toMysqlService.selectTableInfo(artId,JDBC_CONN); } else { // 如果为空走系统启动已经加载的数据源 return toMysqlService.selectTableInfo(artId,null); } }
3. ToMysqlService接口(Service接口)
@Service public interface ToMysqlService { Map<String, Object> selectTableInfo(String artId, JDBC_CONN JDBC_CONN); Map<String, Object> selectReportInfo(String artId, String artType); }
4.ToMysqlServiceImpl(Service接口实现类)
// hawq表结构查询 List<Map<String, String>> listStructure = null; // 判断传入的JDBC_CONN是否为空 if(JDBC_CONN == null) // 为空,则走默认的数据源 listStructure = daoToHawq.queryForStructure(strTableName); else // 不为空,则走规定的动态数据源 listStructure = JDBC_CONN.queryForStructure(strTableName);
5. 在JDBC_CONN的Model类中添加如下方法 queryForStructure()
// 连接参数 Connection conn = null; PreparedStatement preStmt = null; ResultSet rs = null; String tableName = strTableName; // 传入的表名称 List<Map<String, String>> result = null; // 定义一个list<map>来存值 try { // 添加数据库驱动 Class.forName(base_driver); String url = base_url; conn = DriverManager.getConnection(url,base_name,base_pass); // 定义一个List<Map> result = new ArrayList<Map<String, String>>(); // 判断前端传入的base_driver中是否存在postgresql,如果存在,需单独处理,如果不是,则是大众数据库的样式进行处理(因为postgresql比较特殊,这种方式不能获取到数据库的表结构) if (!(base_driver.contains("postgresql"))) { // Oracle,mysql等查询表结构 DatabaseMetaData metaData = conn.getMetaData(); rs = metaData.getColumns(null, "%", tableName, "%"); while(rs.next()) { Map<String, String> mapColumn = new HashMap<String, String>(); mapColumn.put("name", rs.getString("COLUMN_NAME")); mapColumn.put("type", rs.getString("TYPE_NAME")); mapColumn.put("size", rs.getString("COLUMN_SIZE")); result.add(mapColumn); } } else { // 否则执行postgresql的查询表结构的方式 // PostgreSql查询表结构 String[] str = tableName.split("\\."); // source.inspur String schema = str[0]; // source String table = str[1]; // inspur // 根据information_schema.columns表能够查询表结构(此表用来存储表结构) String sql = "SELECT * FROM information_schema.columns WHERE TABLE_SCHEMA = '"+schema+"' AND TABLE_NAME = '"+table+"'"; //执行查询 preStmt = (PreparedStatement)conn.prepareStatement(sql); rs = preStmt.executeQuery(); while(rs.next()) { Map<String, String> mapColumn = new HashMap<String, String>(); mapColumn.put("name", rs.getString("COLUMN_NAME")); mapColumn.put("type", rs.getString("UDT_NAME")); // 判断UDT_NAME的值是什么然后赋予不同的值 if (rs.getString("UDT_NAME").equals("date")) { mapColumn.put("size", "13"); } else if (rs.getString("UDT_NAME").equals("timestamp")) { mapColumn.put("size", "29"); } else { mapColumn.put("size", rs.getString("CHARACTER_OCTET_LENGTH")); } result.add(mapColumn); } } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 释放资源 try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } conn = null; } return result; }
6. 就这样,根据调用的返回到前端视图中,这样就连接了自己传入的动态数据源.
补充(核心代码):
1.Oracle,MySQL,DB2等查询表结构的方式:
DatabaseMetaData metaData = conn.getMetaData(); rs = metaData.getColumns(null, "%", tableName, "%"); // tableName表示传入的表名称 while(rs.next()) { Map<String, String> mapColumn = new HashMap<String, String>(); mapColumn.put("name", rs.getString("COLUMN_NAME")); // 获取到COLUMN_NAME列名 mapColumn.put("type", rs.getString("TYPE_NAME")); // 类型varchar,int等 mapColumn.put("size", rs.getString("COLUMN_SIZE")); // 字段的大小 }
2.PostgreSQL查询表结构的方式(由于数据库处理机制不一样,查询资料得知postgresql中有一个表专门存各个表结构的信息):
// 保存表结构的表information_schema.columns String sql = "SELECT * FROM information_schema.columns WHERE TABLE_SCHEMA = '"+schema+"' AND TABLE_NAME = '"+table+"'"; //执行查询 preStmt = (PreparedStatement)conn.prepareStatement(sql); rs = preStmt.executeQuery(); while(rs.next()) { Map<String, String> mapColumn = new HashMap<String, String>(); // COLUMN_NAME, UDT_NAME,CHARACTER_OCTET_LENGTH这些字段都是在information_schema.columns 真实存在的 mapColumn.put("name", rs.getString("COLUMN_NAME")); mapColumn.put("type", rs.getString("UDT_NAME")); mapColumn.put("size", rs.getString("CHARACTER_OCTET_LENGTH")); result.add(mapColumn); }
在这里再说一下: postgresql保存表结构的表是: information_schema.columns