最近使用JBolt极速开发平台在做一个项目,使用的是Sqlserver数据库,表注释和字段注释都做好了,在Mysql下生成一点问题没有,在Sqlserver下生成却发现列注释remarks获取不到,无法正确生成!
debug发现是JDBC-Sqlserver的坑,没有很好的去实现标准,获取remarks无效。
无奈只能靠Sql语句自行查询解决了。
这里给出了自定义扩展SqlServer的MetaBuilder去解决了这个问题。
主要是buildTabelColumnRemark实现通过sql查询每个表的字段注释。
具体代码:
package cn.jbolt.common.gen; import java.sql.Connection; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; import java.util.List; import javax.sql.DataSource; import com.jfinal.kit.Kv; import com.jfinal.plugin.activerecord.dialect.SqlServerDialect; import com.jfinal.plugin.activerecord.generator.ColumnMeta; import com.jfinal.plugin.activerecord.generator.TableMeta; public class JBoltSqlServerMetaBuilder extends JBoltMetaBuilder{ private Connection columnRemarkConn; public JBoltSqlServerMetaBuilder (DataSource dataSource) { super(dataSource); } @Override protected void buildColumnMetas(TableMeta tableMeta) throws SQLException { String sql = dialect.forTableBuilderDoBuild(tableMeta.name); Statement stm = conn.createStatement(); ResultSet rs = stm.executeQuery(sql); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); Kv remarkKv=null; if (generateRemarks) { remarkKv=buildTabelColumnRemark(tableMeta.name); } ColumnMeta cm; for (int i=1; i<=columnCount; i++) { cm = new ColumnMeta(); cm.name = rsmd.getColumnName(i); String colClassName = rsmd.getColumnClassName(i); String typeStr = typeMapping.getType(colClassName); if (typeStr != null) { cm.javaType = typeStr; } else { int type = rsmd.getColumnType(i); if (type == Types.BINARY || type == Types.VARBINARY || type == Types.BLOB) { cm.javaType = "byte[]"; } else if (type == Types.SMALLINT) { cm.javaType="java.lang.Short"; } else if (type == Types.CLOB || type == Types.NCLOB) { cm.javaType = "java.lang.String"; } else { cm.javaType = "java.lang.String"; } } //特殊处理char(1) to Boolean if("java.lang.String".equals(cm.javaType)) { int scale = rsmd.getScale(i); // 小数点右边的位数,值为 0 表示整数 int precision = rsmd.getPrecision(i); // 最大精度 if (scale == 0 && precision == 1&&JBoltProjectGenConfig.charToBoolean) { cm.javaType = "java.lang.Boolean"; } } // 构造字段对应的属性名 attrName cm.attrName = buildAttrName(cm.name); // 备注字段赋值 if (generateRemarks) { cm.remarks = remarkKv.getStr(cm.name); } tableMeta.columnMetas.add(cm); } rs.close(); stm.close(); } @Override protected ResultSet getTablesResultSet() throws SQLException { setDialect(new SqlServerDialect()); ResultSet rs = dbMeta.getTables(conn.getCatalog(), null,"%", new String[]{"TABLE"}); return rs; } @Override protected void buildTableNames(List<TableMeta> ret) throws SQLException { ResultSet rs = getTablesResultSet(); while (rs.next()) { String schem = rs.getString("TABLE_SCHEM"); String tableName = rs.getString("TABLE_Name"); if (schem.equals("sys")) { JBoltConsoleUtil.printMessage(" Skip table :" + tableName + ",sys table"); continue; } if (excludedTables.contains(tableName)) { JBoltConsoleUtil.printMessage(" Skip table :" + tableName); continue; } if (isSkipTable(tableName)) { JBoltConsoleUtil.printMessage(" Skip table :" + tableName); continue; } TableMeta tableMeta = new TableMeta(); tableMeta.name = tableName; if(generateRemarks) { tableMeta.remarks =getTabelRemark(tableName); } tableMeta.modelName = buildModelName(tableName); tableMeta.baseModelName = buildBaseModelName(tableMeta.modelName); ret.add(tableMeta); } rs.close(); if(generateRemarks&&columnRemarkConn!=null&&columnRemarkConn.isClosed()==false) { columnRemarkConn.close(); } } private String getTabelRemark(String table) throws SQLException { Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery("SELECT cast(ds.value as varchar(200)) as remarks " + " FROM sys.extended_properties ds" + " LEFT JOIN sysobjects tbs ON ds.major_id=tbs.id" + " WHERE ds.minor_id=0 and tbs.name='"+table+"'"); String remark = null; if(rs.next()) { remark=rs.getString("remarks"); } rs.close(); return remark; } private Kv buildTabelColumnRemark(String table) throws SQLException { if(columnRemarkConn==null) { columnRemarkConn=dataSource.getConnection(); } Statement statement = columnRemarkConn.createStatement(); ResultSet rs = statement.executeQuery("SELECT cast(col.name as varchar(200)) AS name ," + " cast(ISNULL(ep.[value], '') as varchar(200)) AS remarks" + " FROM dbo.syscolumns col" + " LEFT JOIN dbo.systypes t ON col.xtype = t.xusertype" + " inner JOIN dbo.sysobjects obj ON col.id = obj.id" + " AND obj.xtype = 'U'" + " AND obj.status >= 0" + " LEFT JOIN dbo.syscomments comm ON col.cdefault = comm.id" + " LEFT JOIN sys.extended_properties ep ON col.id = ep.major_id" + " AND col.colid = ep.minor_id" + " AND ep.name = 'MS_Description'" + " LEFT JOIN sys.extended_properties epTwo ON obj.id = epTwo.major_id" + " AND epTwo.minor_id = 0" + " AND epTwo.name = 'MS_Description'" + " WHERE obj.name = '"+table+"'"); Kv kv=Kv.create(); while(rs.next()) { kv.set(rs.getString("name"), rs.getString("remarks")); } rs.close(); return kv; } }
这样再去执行代码生成就没有任何问题了!
表注释和字段注释都没问题了!
方案用的是笨办法,目前快速搞定,先用上,谁有更好的方法,可以交流。
咨询加入,加我微信:
mumengmeng
推荐