Skip to content

Commit 07eb1a9

Browse files
committed
SQLのログ出力設定の追加
1 parent 9f70e68 commit 07eb1a9

File tree

7 files changed

+348
-1
lines changed

7 files changed

+348
-1
lines changed

sqlmapper-parent/sqlmapper-core/src/main/java/com/github/mygreen/sqlmapper/core/SqlMapperContext.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.github.mygreen.sqlmapper.core.meta.EntityMetaFactory;
1616
import com.github.mygreen.sqlmapper.core.meta.StoredParamMetaFactory;
1717
import com.github.mygreen.sqlmapper.core.naming.NamingRule;
18+
import com.github.mygreen.sqlmapper.core.query.SqlLogger;
1819
import com.github.mygreen.sqlmapper.core.type.ValueTypeRegistry;
1920

2021
import lombok.Getter;
@@ -87,6 +88,11 @@ public class SqlMapperContext {
8788
*/
8889
private SqlTemplateEngine sqlTemplateEngine;
8990

91+
/**
92+
* SQLログ出力
93+
*/
94+
private SqlLogger sqlLogger;
95+
9096
/**
9197
* トランザクションの伝搬タイプが {@link TransactionDefinition#PROPAGATION_REQUIRES_NEW} のトランザクションテンプレートを作成します。
9298
* <p>ID生成用のトランザクションテンプレートとして使用します。
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.github.mygreen.sqlmapper.core.config;
2+
3+
import org.slf4j.event.Level;
4+
5+
import lombok.Data;
6+
7+
/**
8+
* SQLをログに出力する設定。
9+
*
10+
* @since 0.4
11+
* @author T.TSUCHIE
12+
*
13+
*/
14+
@Data
15+
public class ShowSqlProperties {
16+
17+
/** SQLのログ出力機能を有効にするかどうか。 */
18+
private boolean enabled;
19+
20+
/** SQL出力時のログレベル */
21+
private Level logLevel;
22+
23+
/** SQLのバインド変数に関するSQLの出力設定 */
24+
private BindParamProperties bindParam;
25+
26+
/**
27+
* SQLログ出力のバインドパラメータ設定
28+
*
29+
* @since 0.4
30+
* @author T.TSUCHIE
31+
*
32+
*/
33+
@Data
34+
public static class BindParamProperties {
35+
36+
/** バインド変数を出力するかどうか */
37+
private boolean enabled;
38+
39+
/** バインド変数出力時のログレベル */
40+
private Level LogLevel;
41+
}
42+
43+
}

sqlmapper-parent/sqlmapper-core/src/main/java/com/github/mygreen/sqlmapper/core/config/SqlMapperConfigurationSupport.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import javax.sql.DataSource;
44

5+
import org.slf4j.event.Level;
56
import org.springframework.beans.BeansException;
67
import org.springframework.beans.factory.annotation.Autowired;
78
import org.springframework.context.ApplicationContext;
@@ -26,13 +27,15 @@
2627
import com.github.mygreen.sqlmapper.core.SqlMapper;
2728
import com.github.mygreen.sqlmapper.core.SqlMapperContext;
2829
import com.github.mygreen.sqlmapper.core.audit.AuditingEntityListener;
30+
import com.github.mygreen.sqlmapper.core.config.ShowSqlProperties.BindParamProperties;
2931
import com.github.mygreen.sqlmapper.core.dialect.Dialect;
3032
import com.github.mygreen.sqlmapper.core.meta.EntityMetaFactory;
3133
import com.github.mygreen.sqlmapper.core.meta.PropertyMetaFactory;
3234
import com.github.mygreen.sqlmapper.core.meta.StoredParamMetaFactory;
3335
import com.github.mygreen.sqlmapper.core.meta.StoredPropertyMetaFactory;
3436
import com.github.mygreen.sqlmapper.core.naming.DefaultNamingRule;
3537
import com.github.mygreen.sqlmapper.core.naming.NamingRule;
38+
import com.github.mygreen.sqlmapper.core.query.SqlLogger;
3639
import com.github.mygreen.sqlmapper.core.type.ValueTypeRegistry;
3740

3841
/**
@@ -93,6 +96,7 @@ public SqlMapperContext sqlMapperContext() {
9396
context.setDataSource(dataSource());
9497
context.setJdbcTemplateProperties(jdbcTemplateProperties());
9598
context.setTransactionManager(transactionManager());
99+
context.setSqlLogger(sqlLogger());
96100

97101
return context;
98102

@@ -137,6 +141,22 @@ public TableIdGeneratorProperties tableIdGeneratorProperties() {
137141
return prop;
138142
}
139143

144+
@Bean
145+
@Description("SQLのログ出力設定")
146+
public ShowSqlProperties showSqlProperties() {
147+
148+
ShowSqlProperties prop = new ShowSqlProperties();
149+
prop.setEnabled(Boolean.parseBoolean(env.getProperty("sqlmapper.show-sql.enabled")));
150+
prop.setLogLevel(Level.valueOf(env.getProperty("sqlmapper.show-sql.log-level").toUpperCase()));
151+
152+
BindParamProperties bindProp = new BindParamProperties();
153+
bindProp.setEnabled(Boolean.parseBoolean(env.getProperty("sqlmapper.show-sql.bind-param.enabled")));
154+
bindProp.setLogLevel(Level.valueOf(env.getProperty("sqlmapper.show-sql.bind-param.log-level").toUpperCase()));
155+
prop.setBindParam(bindProp);
156+
157+
return prop;
158+
}
159+
140160
@Bean
141161
@Description("エンティティの対応クラスからメタ情報を作成するBean。")
142162
public EntityMetaFactory entityMetaFactory() {
@@ -238,4 +258,10 @@ public AuditingEntityListener auditingEntityListener() {
238258
return new AuditingEntityListener();
239259
}
240260

261+
@Bean
262+
@Description("SQLのログ出力処理")
263+
public SqlLogger sqlLogger() {
264+
return new SqlLogger(showSqlProperties());
265+
}
266+
241267
}
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
package com.github.mygreen.sqlmapper.core.query;
2+
3+
import java.sql.Blob;
4+
import java.sql.Clob;
5+
import java.sql.Date;
6+
import java.sql.Time;
7+
import java.sql.Timestamp;
8+
import java.sql.Types;
9+
import java.text.SimpleDateFormat;
10+
import java.util.Arrays;
11+
import java.util.Collection;
12+
import java.util.List;
13+
14+
import org.slf4j.event.Level;
15+
import org.springframework.jdbc.core.SqlParameterValue;
16+
import org.springframework.jdbc.core.StatementCreatorUtils;
17+
import org.springframework.util.CollectionUtils;
18+
19+
import com.github.mygreen.sqlmapper.core.config.ShowSqlProperties;
20+
21+
import lombok.Getter;
22+
import lombok.RequiredArgsConstructor;
23+
import lombok.extern.slf4j.Slf4j;
24+
25+
/**
26+
* SQLをログ出力する処理。
27+
*
28+
* @since 0.4
29+
* @author T.TSUCHIE
30+
*
31+
*/
32+
@Slf4j
33+
@RequiredArgsConstructor
34+
public class SqlLogger {
35+
36+
/**
37+
* SQLのログ出力設定
38+
* @return SQLのログ出力設定を取得します。
39+
*/
40+
@Getter
41+
private final ShowSqlProperties prop;
42+
43+
private static final SimpleDateFormat FORMAT_SQL_TIME = new SimpleDateFormat("HH:mm:ss");
44+
45+
private static final SimpleDateFormat FORMAT_SQL_DATE = new SimpleDateFormat("yyyy-MM-dd");
46+
47+
private static final SimpleDateFormat FORMAT_SQL_TIMESTAMP = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
48+
49+
private static final SimpleDateFormat FORMAT_UTIL_DATE = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
50+
51+
/**
52+
* SQLをログ出力する。
53+
* @param sql 出力対象のSQL
54+
* @param params SQLのバインド変数
55+
*/
56+
public void out(final String sql, final Object[] params) {
57+
outSql(sql);
58+
if(prop.getBindParam().isEnabled() && params != null) {
59+
outParams(Arrays.asList(params));
60+
}
61+
62+
}
63+
64+
/**
65+
* SQLをログ出力する。
66+
* @param sql 出力対象のSQL
67+
* @param params SQLのバインド変数
68+
*/
69+
public void out(final String sql, final Collection<Object> params) {
70+
outSql(sql);
71+
outParams(params);
72+
}
73+
74+
/**
75+
* バッチ実行用のSQLをログ出力する。
76+
* @param sql 出力対象のSQL
77+
* @param batchParams バッチ変数用SQLのバインド変数
78+
*/
79+
public void outBatch(final String sql, final List<Object[]> batchParams) {
80+
outSql(sql);
81+
outBatchParams(batchParams);
82+
83+
}
84+
85+
/**
86+
* SQLをログ出力する。
87+
* @param sql 出力対象のSQL
88+
*/
89+
private void outSql(final String sql) {
90+
if(!prop.isEnabled()) {
91+
return;
92+
}
93+
invokeLog(prop.getLogLevel(), "sql statement : {}", new Object[]{sql});
94+
}
95+
96+
/**
97+
* SQLのバインド変数をログ出力する。
98+
* @param params SQLのバインド変数
99+
*/
100+
private void outParams(final Collection<Object> params) {
101+
if(!prop.isEnabled() || !prop.getBindParam().isEnabled() || CollectionUtils.isEmpty(params)) {
102+
return;
103+
}
104+
105+
int paramCount = 1;
106+
for(Object param : params) {
107+
String paramType = resolveBindParamType(param);
108+
String paramValue = resolveBindParamValue(param);
109+
110+
invokeLog(prop.getBindParam().getLogLevel(), "sql binding parameter : [{}] as [{}] - [{}]",
111+
new Object[]{paramCount, paramType, paramValue });
112+
113+
paramCount++;
114+
}
115+
}
116+
117+
/**
118+
* バッチ実行用のSQLのバインド変数をログ出力する。
119+
* @param batchParams SQLのバインド変数
120+
*/
121+
private void outBatchParams(final Collection<Object[]> batchParams) {
122+
if(!prop.isEnabled() || !prop.getBindParam().isEnabled() || CollectionUtils.isEmpty(batchParams)) {
123+
return;
124+
}
125+
126+
int recordCount = 1;
127+
for(Object[] recordParams : batchParams) {
128+
int paramCount = 1;
129+
for(Object param : recordParams) {
130+
String paramType = resolveBindParamType(param);
131+
String paramValue = resolveBindParamValue(param);
132+
133+
invokeLog(prop.getBindParam().getLogLevel(), "sql batch binding parameter : [{}][{}] as [{}] - [{}]",
134+
new Object[]{recordCount, paramCount, paramType, paramValue });
135+
136+
paramCount++;
137+
}
138+
recordCount++;
139+
}
140+
}
141+
142+
/**
143+
* ログレベルを指定してログに出力する。
144+
* @param level ログレベル。
145+
* @param message ログメッセージ。
146+
* @param args ログメッセージ中の引数。
147+
*/
148+
private void invokeLog(Level level, String message, Object[] args) {
149+
switch (level) {
150+
case TRACE:
151+
log.trace(message, args);
152+
break;
153+
case DEBUG:
154+
log.debug(message, args);
155+
break;
156+
case INFO:
157+
log.info(message, args);
158+
break;
159+
case WARN:
160+
log.warn(message, args);
161+
break;
162+
case ERROR:
163+
log.error(message, args);
164+
break;
165+
}
166+
}
167+
168+
/**
169+
* SQLのバンド変数のログ出力用のタイプ名に変換する。
170+
* @param value バンド変数
171+
* @return タイプ情報。
172+
*/
173+
private String resolveBindParamType(final Object value) {
174+
if (value == null) {
175+
return "NULL";
176+
} else if (value instanceof SqlParameterValue) {
177+
return ((SqlParameterValue)(value)).getTypeName();
178+
} else {
179+
int type = StatementCreatorUtils.javaTypeToSqlParameterType(value.getClass());
180+
switch (type) {
181+
case Types.BOOLEAN:
182+
return "BOOLEAN";
183+
case Types.TINYINT:
184+
return "TINYINT";
185+
case Types.SMALLINT:
186+
return "SMALLINT";
187+
case Types.INTEGER:
188+
return "INTEGER";
189+
case Types.BIGINT:
190+
return "BIGINT";
191+
case Types.FLOAT:
192+
return "FLOAT";
193+
case Types.DOUBLE:
194+
return "DOUBLE";
195+
case Types.DECIMAL:
196+
return "DECIMAL";
197+
case Types.NUMERIC:
198+
return "NUMERIC";
199+
case Types.BLOB:
200+
return "BLOB";
201+
case Types.CLOB:
202+
return "CLOB";
203+
case Types.CHAR:
204+
return "CHAR";
205+
case Types.VARCHAR:
206+
return "VARCHAR";
207+
case Types.DATE:
208+
return "DATE";
209+
case Types.TIMESTAMP:
210+
return "TIMESTAMP";
211+
default:
212+
return "UNKNOWN";
213+
}
214+
215+
}
216+
}
217+
218+
/**
219+
* SQLのバインド変数をログ出力用の値に変換する。
220+
* @param value バインド変数。
221+
* @return ログ出力用の値。
222+
*/
223+
private String resolveBindParamValue(final Object value) {
224+
if (value == null) {
225+
return "NULL";
226+
} else if (value instanceof Blob) {
227+
return "<BLOB DATA...>";
228+
} else if(value instanceof Clob) {
229+
return "<CLOB DATA...>";
230+
} else if(value instanceof Time) {
231+
return FORMAT_SQL_TIME.format(value);
232+
} else if(value instanceof Date) {
233+
return FORMAT_SQL_DATE.format(value);
234+
} else if(value instanceof Timestamp) {
235+
return FORMAT_SQL_TIMESTAMP.format(value);
236+
} else if(value instanceof java.util.Date) {
237+
return FORMAT_UTIL_DATE.format(value);
238+
} else if (value instanceof SqlParameterValue) {
239+
return ((SqlParameterValue)(value)).getValue().toString();
240+
} else {
241+
return value.toString();
242+
}
243+
}
244+
245+
246+
}

sqlmapper-parent/sqlmapper-core/src/main/java/com/github/mygreen/sqlmapper/core/sqlmapper.properties

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,8 @@ sqlmapper.table-id-generator.initial-value=0
2121
sqlmapper.sql-template.cache-mode=true
2222
sqlmapper.sql-template.encoding=UTF-8
2323

24+
## SQLのログ出力設定
25+
sqlmapper.show-sql.enabled=false
26+
sqlmapper.show-sql.log-level=DEBUG
27+
sqlmapper.show-sql.bind-param.enabled=false
28+
sqlmapper.show-sql.bind-param.log-level=DEBUG

0 commit comments

Comments
 (0)