package org.nutz.mole.impl; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.nutz.json.Json; import org.nutz.lang.Strings; import org.nutz.log.Log; import org.nutz.log.Logs; import org.nutz.mole.ConfigPool; import org.nutz.mole.DatabaseAdaptor; import org.nutz.mole.MoleContext; import org.nutz.mole.meta.ZField; import org.nutz.mole.meta.ZTable; public class GenerallyDatabaseAdaptor implements DatabaseAdaptor { private static final Log log = Logs.get(); public MoleContext fromDb(MoleContext context) { Connection connection = null; ConfigPool config = context.getConfig(); try { //获取数据库连接 Class.forName(config.getProject().get("db_driver")); connection = DriverManager.getConnection( config.getProject().get("db_url"), config.getProject().get("db_username"), config.getProject().get("db_password")); if(connection==null || connection.isClosed()) { return null; } connection.setReadOnly(true); //获取数据库的元数据 DatabaseMetaData metaData = connection.getMetaData(); ResultSet tableResultset = metaData.getTables( null, null, null, new String[]{"TABLE"}); //开始遍历全部结果(即全部表) List<ZTable> tables = new ArrayList<ZTable>(10); while (tableResultset.next()) { ZTable zTable = new ZTable(); tables.add(zTable); zTable.setTableName(tableResultset.getString("TABLE_NAME")); //查询表名-->类名映射 zTable.setClassName(config.getTableMapping().get(zTable.getTableName())); if (zTable.getClassName() == null) { zTable.setClassName(toName(zTable.getTableName())); } zTable.setComment(tableResultset.getString("REMARKS")); } //把信息打印一下,这样用户比较清晰 if(log.isInfoEnabled()) log.infof("Load %d tables", tables.size()); if(log.isDebugEnabled()) log.debug("Tables:\n"+Json.toJson(tables)); //好了,开始找字段 for (ZTable zTable : tables) { //先来找找主键 Set<String> pks = new HashSet<String>(); ResultSet pkResultSet = metaData.getPrimaryKeys(null, null, zTable.getTableName()); while (pkResultSet.next()) { pks.add(pkResultSet.getString("COLUMN_NAME")); } ResultSet columnResultset = metaData.getColumns(null, null, zTable.getTableName(), null); while (columnResultset.next()) { ZField zField = new ZField(); zField.dbFieldName = columnResultset.getString("COLUMN_NAME"); zField.notNull = "NO".equals(columnResultset.getString("IS_NULLABLE")); zField.dbFieldType = columnResultset.getString("TYPE_NAME"); zField.fieldName = config.getTableFieldMapping().get(zTable.getTableName() + "." + zField.dbFieldName); if (zField.fieldName == null) zField.fieldName = config.getTableFieldMapping().get("*." + zField.dbFieldName); if (zField.fieldName == null) zField.fieldName = Strings.lowerFirst(toName(zField.dbFieldName)); if (pks.contains(zField.dbFieldName)) zField.isPrimaryKey = true; // 推断字段的Java类型 zField.classTypeName = config.getTypeMapping().get(zField.dbFieldType); if (zField.classTypeName == null) { log.warnf( "Unkown type_name %s.%s, skip!", zTable.getTableName(), zField.dbFieldName); continue; } zField.comment=columnResultset.getString("REMARKS"); if(zField.comment==null) zField.comment=""; zTable.getFields().add(zField); } } // return tables; context.setTables(tables); return context; } catch (SQLException sqle) { log.warn(sqle.getMessage()); } catch (Throwable e) { e.printStackTrace(); } finally { if (connection != null) try { connection.close(); } catch (Throwable e) {} } return null; } @Override public void toTarget(MoleContext context) { new PojoCreater().create(context); new HelpFileCreater().create(context); } public static final String toName(String srcName) { if (Strings.isBlank(srcName)) return ""; srcName = srcName.toLowerCase(); if (srcName.startsWith("t_")) srcName = srcName.substring(2); if (srcName.startsWith("tb_")) srcName = srcName.substring(3); String[] names = srcName.split("_"); StringBuilder sb = new StringBuilder(); for (int i = 0; i < names.length; i++) { sb.append(Strings.capitalize(names[i])); } return sb.toString(); } }