解析SQLは、クエリーの列名を取得します。
6119 ワード
今日は一つのクエリSQLを解析して、SQL文の列名をどうやって取得すればいいですか?
1.SQL文を解析する
解析SQLは、ツールjarパッケージを介して実現することができる。
短所:select*from table文の*は解析できなくなり、文字列として扱われます。
利点:データベースが検索できさえすれば、すべて解析できます。
短所:データベースとの対話が必要で、速度が比較的遅いです。
コードは以下の通りです
1.SQL文を解析する
解析SQLは、ツールjarパッケージを介して実現することができる。
com.github.jsqlparser
jsqlparser
1.4-SNAPSHOT
利点:データベースとの相互作用がなくてもいいです。スピードが速いです。短所:select*from table文の*は解析できなくなり、文字列として扱われます。
public static void main(String[] args) {
String sql1 = "select * from soa_sys_user";
List column1 = analyzeSelectSQL(sql1);
System.out.println("sql1 :");
for (String str : column1) {
System.out.print(str + ", ");
}
System.out.println("");
System.out.println("sql2 :");
String sql2 = "select user_id, user_name as userName, email, weixin, to_date(sysdate, 'yyyy-mm-dd hh24:mi:ss') from soa_sys_user";
List column2 = analyzeSelectSQL(sql2);
for (String str : column2) {
System.out.print(str + ", ");
}
}
public static List analyzeSelectSQL(String sql){
List result = new ArrayList();
try {
CCJSqlParserManager pm = new CCJSqlParserManager();
Statement statement = pm.parse(new StringReader(sql));
if (statement instanceof Select) {
Select selectStatement = (Select) statement;
PlainSelect selectBody = (PlainSelect) selectStatement
.getSelectBody();
List selectItemlist = selectBody.getSelectItems();
SelectItem selectItem = null;
SelectExpressionItem selectExpressionItem = null;
AllTableColumns allTableColumns = null;
Alias alias = null;
SimpleNode node = null;
if (selectItemlist != null) {
for (int i = 0; i < selectItemlist.size(); i++) {
selectItem = selectItemlist.get(i);
if (selectItem instanceof SelectExpressionItem) {
selectExpressionItem = (SelectExpressionItem) selectItemlist
.get(i);
alias = selectExpressionItem.getAlias();
node = selectExpressionItem.getExpression()
.getASTNode();
Object value = node.jjtGetValue();
String columnName = "";
if (value instanceof Column) {
columnName = ((Column) value).getColumnName();
} else if (value instanceof Function) {
columnName = ((Function) value).toString();
}else {
// select 'aaa' from table;
columnName = ObjectUtils.praseObjectToString(value);
columnName = columnName.replace("'", "");
columnName = columnName.replace("\"", "");
}
if (alias != null) {
columnName = alias.getName();
}
result.add(columnName);
} else if (selectItem instanceof AllTableColumns) {
allTableColumns = (AllTableColumns) selectItemlist
.get(i);
result.add(allTableColumns.toString());
} else {
result.add(selectItem.toString());
}
}
}
}
} catch (JSQLParserException e) {
e.printStackTrace();
}
return result;
}
実行結果:sql1 :
*,
sql2 :
user_id, userName, email, weixin, to_date(sysdate, 'yyyy-mm-dd hh24:mi:ss'),
2.SQLを実行し、データベースと対話し、クエリ結果の列名を取得する利点:データベースが検索できさえすれば、すべて解析できます。
短所:データベースとの対話が必要で、速度が比較的遅いです。
コードは以下の通りです
public static void main(String[] args) {
Connection conn = null;
Statement stm = null;
ResultSet rs = null;
try {
StringBuffer sqlBuffer = new StringBuffer();
sqlBuffer.append("select * from soa_sys_user order by user_id ");
conn = JdbcUtils.getConnection();
stm = conn.createStatement();
rs = stm.executeQuery(sqlBuffer.toString());
ResultSetMetaData rsmd = rs.getMetaData();
List columnList = new ArrayList();
for (int i = 1; i < rsmd.getColumnCount() + 1; i++) {
String columnName = rsmd.getColumnName(i).toLowerCase();
columnList.add(columnName);
}
for (String str : columnList) {
System.out.print(str + ", ");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (null != conn) {
conn.close();
}
if (null != stm) {
stm.close();
}
if (null != rs) {
rs.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
出力結果:user_id, user_account, user_name, user_password, email, phone, mobile, weixin, group_code, rev_mail, rev_sms, rev_weixin, province_code, attribute1, attribute2, attribute3, attribute4, attribute5, enabled_flag, created_by, created_date, last_update_by, last_update_date, user_type, mgt_province_code, user_flag, login_time, error_times,