Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
holden_csdn
tx-lcn
提交
edb18587
T
tx-lcn
项目概览
holden_csdn
/
tx-lcn
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
tx-lcn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
edb18587
编写于
7月 01, 2020
作者:
W
wangliang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
TransactionLog 事务日志记录
上级
7fd08b82
变更
19
隐藏空白更改
内联
并排
Showing
19 changed file
with
262 addition
and
24 deletion
+262
-24
example/example-tc/src/main/resources/application.properties
example/example-tc/src/main/resources/application.properties
+2
-1
txlcn-tc/pom.xml
txlcn-tc/pom.xml
+6
-0
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/aspect/TxDataSourceInterceptor.java
...om/codingapi/txlcn/tc/aspect/TxDataSourceInterceptor.java
+1
-5
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/config/TxConfig.java
...src/main/java/com/codingapi/txlcn/tc/config/TxConfig.java
+5
-0
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/control/TransactionContext.java
...va/com/codingapi/txlcn/tc/control/TransactionContext.java
+2
-1
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/JdbcConfiguration.java
...n/java/com/codingapi/txlcn/tc/jdbc/JdbcConfiguration.java
+2
-0
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/JdbcTransaction.java
...ain/java/com/codingapi/txlcn/tc/jdbc/JdbcTransaction.java
+39
-0
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/JdbcTransactionThreadLocal.java
...m/codingapi/txlcn/tc/jdbc/JdbcTransactionThreadLocal.java
+20
-0
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/ProxyConnection.java
...ain/java/com/codingapi/txlcn/tc/jdbc/ProxyConnection.java
+9
-2
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/TransactionJdbcEvent.java
...ava/com/codingapi/txlcn/tc/jdbc/TransactionJdbcEvent.java
+1
-2
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/TransactionJdbcEventListener.java
...codingapi/txlcn/tc/jdbc/TransactionJdbcEventListener.java
+4
-9
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/event/JdbcEventConfiguration.java
...codingapi/txlcn/tc/jdbc/event/JdbcEventConfiguration.java
+3
-2
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/event/LcnCommitTransactionJdbcEvent.java
...pi/txlcn/tc/jdbc/event/LcnCommitTransactionJdbcEvent.java
+6
-1
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/event/LcnExecuteTransactionJdbcEvent.java
...i/txlcn/tc/jdbc/event/LcnExecuteTransactionJdbcEvent.java
+14
-1
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/log/JdbcLogConfiguration.java
...com/codingapi/txlcn/tc/jdbc/log/JdbcLogConfiguration.java
+25
-0
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/log/LogExecutor.java
...ain/java/com/codingapi/txlcn/tc/jdbc/log/LogExecutor.java
+16
-0
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/log/MysqlLogExecutor.java
...ava/com/codingapi/txlcn/tc/jdbc/log/MysqlLogExecutor.java
+24
-0
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/log/TransactionLog.java
.../java/com/codingapi/txlcn/tc/jdbc/log/TransactionLog.java
+52
-0
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/log/TransactionLogExecutor.java
...m/codingapi/txlcn/tc/jdbc/log/TransactionLogExecutor.java
+31
-0
未找到文件。
example/example-tc/src/main/resources/application.properties
浏览文件 @
edb18587
...
...
@@ -4,9 +4,10 @@ server.port=8090
logging.level.com.codingapi
=
debug
txlcn.tc.tms
=
127.0.0.1:8070
txlcn.tc.sql-type
=
mysql
txlcn.tc.application-name
=
example-tc
spring.datasource.url
=
jdbc:mysql://127.0.0.1:3306/test
spring.datasource.driver-class-name
=
com.mysql.cj.jdbc.Driver
spring.datasource.password
=
root
spring.datasource.username
=
root
\ No newline at end of file
spring.datasource.username
=
root
txlcn-tc/pom.xml
浏览文件 @
edb18587
...
...
@@ -47,6 +47,12 @@
<artifactId>
spring-tx
</artifactId>
<scope>
provided
</scope>
</dependency>
<dependency>
<groupId>
commons-dbutils
</groupId>
<artifactId>
commons-dbutils
</artifactId>
</dependency>
</dependencies>
<build>
...
...
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/aspect/TxDataSourceInterceptor.java
浏览文件 @
edb18587
package
com.codingapi.txlcn.tc.aspect
;
import
com.codingapi.txlcn.p6spy.CompoundJdbcEventListener
;
import
com.codingapi.txlcn.p6spy.common.ConnectionInformation
;
import
com.codingapi.txlcn.p6spy.wrapper.ConnectionWrapper
;
import
com.codingapi.txlcn.tc.info.TransactionInfo
;
import
com.codingapi.txlcn.tc.jdbc.ProxyConnection
;
import
lombok.AllArgsConstructor
;
...
...
@@ -28,9 +26,7 @@ public class TxDataSourceInterceptor implements MethodInterceptor {
TransactionInfo
transactionInfo
=
TransactionInfo
.
current
();
Connection
connection
=
(
Connection
)
invocation
.
proceed
();
if
(
transactionInfo
!=
null
&&
transactionInfo
.
hasSqlProxy
())
{
return
new
ProxyConnection
(
ConnectionWrapper
.
wrap
(
connection
,
compoundJdbcEventListener
,
ConnectionInformation
.
fromConnection
(
connection
)));
return
new
ProxyConnection
(
compoundJdbcEventListener
,
connection
);
}
else
{
return
connection
;
}
...
...
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/config/TxConfig.java
浏览文件 @
edb18587
...
...
@@ -20,6 +20,11 @@ import lombok.extern.slf4j.Slf4j;
@Model
(
flag
=
"C"
,
value
=
"TC模块配置信息"
,
color
=
"#FF88EE"
)
public
class
TxConfig
{
/**
* 数据库类型
*/
private
String
sqlType
;
/**
* 事务切面
*/
...
...
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/control/TransactionContext.java
浏览文件 @
edb18587
...
...
@@ -4,6 +4,7 @@ import com.codingapi.maven.uml.annotation.GraphRelation;
import
com.codingapi.maven.uml.annotation.Model
;
import
com.codingapi.txlcn.tc.event.transaction.TransactionEventContext
;
import
com.codingapi.txlcn.tc.info.TransactionInfo
;
import
com.codingapi.txlcn.tc.jdbc.JdbcTransaction
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
...
...
@@ -55,7 +56,7 @@ public class TransactionContext {
transactionStepContext
.
execute
(
transactionInfo
);
transactionEventContext
.
onAfterJoinTransaction
(
transactionInfo
);
}
JdbcTransaction
.
clear
();
transactionInfo
.
clear
();
}
...
...
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/JdbcConfiguration.java
浏览文件 @
edb18587
package
com.codingapi.txlcn.tc.jdbc
;
import
com.codingapi.txlcn.p6spy.CompoundJdbcEventListener
;
import
org.h2.util.JdbcUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
...
...
@@ -26,4 +27,5 @@ public class JdbcConfiguration {
return
new
TransactionJdbcEventListener
(
transactionJdbcEvents
);
}
}
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/JdbcTransaction.java
0 → 100644
浏览文件 @
edb18587
package
com.codingapi.txlcn.tc.jdbc
;
import
com.codingapi.txlcn.tc.jdbc.log.TransactionLog
;
import
lombok.Getter
;
import
java.sql.Connection
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* @author lorne
* @date 2020/7/1
* @description
*/
public
class
JdbcTransaction
{
@Getter
private
Connection
connection
;
private
List
<
TransactionLog
>
transactionLogs
;
public
static
JdbcTransaction
current
(){
return
JdbcTransactionThreadLocal
.
current
();
}
protected
JdbcTransaction
(
Connection
connection
){
this
.
connection
=
connection
;
this
.
transactionLogs
=
new
ArrayList
<>();
JdbcTransactionThreadLocal
.
push
(
this
);
}
public
static
void
clear
()
{
JdbcTransactionThreadLocal
.
push
(
null
);
}
public
void
add
(
TransactionLog
transactionLog
)
{
transactionLogs
.
add
(
transactionLog
);
}
}
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/JdbcTransactionThreadLocal.java
0 → 100644
浏览文件 @
edb18587
package
com.codingapi.txlcn.tc.jdbc
;
/**
* 事务信息ThreadLocal
* @author lorne 2020-0305
*/
class
JdbcTransactionThreadLocal
{
final
static
ThreadLocal
<
JdbcTransaction
>
threadLocal
=
new
ThreadLocal
<>();
static
JdbcTransaction
current
(){
return
threadLocal
.
get
();
}
static
void
push
(
JdbcTransaction
jdbcTransaction
){
threadLocal
.
set
(
jdbcTransaction
);
}
}
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/ProxyConnection.java
浏览文件 @
edb18587
package
com.codingapi.txlcn.tc.jdbc
;
import
com.codingapi.txlcn.p6spy.CompoundJdbcEventListener
;
import
com.codingapi.txlcn.p6spy.common.ConnectionInformation
;
import
com.codingapi.txlcn.p6spy.wrapper.ConnectionWrapper
;
import
java.sql.*
;
import
java.util.Map
;
import
java.util.Properties
;
...
...
@@ -14,8 +18,11 @@ public class ProxyConnection implements Connection {
private
Connection
connection
;
public
ProxyConnection
(
Connection
connection
)
{
this
.
connection
=
connection
;
public
ProxyConnection
(
CompoundJdbcEventListener
compoundJdbcEventListener
,
Connection
connection
)
{
new
JdbcTransaction
(
connection
);
this
.
connection
=
ConnectionWrapper
.
wrap
(
connection
,
compoundJdbcEventListener
,
ConnectionInformation
.
fromConnection
(
connection
));
}
@Override
...
...
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/TransactionJdbcEvent.java
浏览文件 @
edb18587
package
com.codingapi.txlcn.tc.jdbc
;
import
java.sql.Connection
;
import
java.sql.SQLException
;
/**
...
...
@@ -14,5 +13,5 @@ public interface TransactionJdbcEvent {
TransactionJdbcState
state
();
Object
execute
(
Connection
connection
,
Object
param
)
throws
SQLException
;
Object
execute
(
Object
param
)
throws
SQLException
;
}
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/TransactionJdbcEventListener.java
浏览文件 @
edb18587
...
...
@@ -8,7 +8,6 @@ import com.codingapi.txlcn.tc.info.TransactionInfo;
import
lombok.SneakyThrows
;
import
lombok.extern.slf4j.Slf4j
;
import
java.sql.Connection
;
import
java.sql.SQLException
;
import
java.util.ArrayList
;
import
java.util.List
;
...
...
@@ -43,42 +42,38 @@ public class TransactionJdbcEventListener extends P6spyJdbcEventListener {
@Override
public
String
onBeforeAnyExecute
(
StatementInformation
statementInformation
)
throws
SQLException
{
Connection
connection
=
statementInformation
.
getConnectionInformation
().
getConnection
();
String
sql
=
statementInformation
.
getSqlWithValues
();
Optional
<
TransactionJdbcEvent
>
optional
=
getTransactionJdbcEvent
(
TransactionJdbcState
.
EXECUTE
);
if
(!
optional
.
isPresent
()){
return
sql
;
}
return
(
String
)
optional
.
get
().
execute
(
connection
,
sql
);
return
(
String
)
optional
.
get
().
execute
(
sql
);
}
@Override
public
void
onBeforeCommit
(
ConnectionInformation
connectionInformation
,
JdbcCallable
callable
)
throws
SQLException
{
Connection
connection
=
connectionInformation
.
getConnection
();
Optional
<
TransactionJdbcEvent
>
optional
=
getTransactionJdbcEvent
(
TransactionJdbcState
.
COMMIT
);
if
(!
optional
.
isPresent
()){
callable
.
call
();
}
optional
.
get
().
execute
(
c
onnection
,
c
allable
);
optional
.
get
().
execute
(
callable
);
}
@Override
public
void
onBeforeRollback
(
ConnectionInformation
connectionInformation
,
JdbcCallable
callable
)
throws
SQLException
{
Connection
connection
=
connectionInformation
.
getConnection
();
Optional
<
TransactionJdbcEvent
>
optional
=
getTransactionJdbcEvent
(
TransactionJdbcState
.
ROLLBACK
);
if
(!
optional
.
isPresent
()){
callable
.
call
();
}
optional
.
get
().
execute
(
c
onnection
,
c
allable
);
optional
.
get
().
execute
(
callable
);
}
@SneakyThrows
@Override
public
void
onAfterAnyExecute
(
StatementInformation
statementInformation
,
long
timeElapsedNanos
,
SQLException
e
)
{
Connection
connection
=
statementInformation
.
getConnectionInformation
().
getConnection
();
Optional
<
TransactionJdbcEvent
>
optional
=
getTransactionJdbcEvent
(
TransactionJdbcState
.
AFTER
);
if
(
optional
.
isPresent
()){
optional
.
get
().
execute
(
connection
,
statementInformation
);
optional
.
get
().
execute
(
statementInformation
);
}
}
}
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/event/JdbcEventConfiguration.java
浏览文件 @
edb18587
package
com.codingapi.txlcn.tc.jdbc.event
;
import
com.codingapi.txlcn.tc.jdbc.log.TransactionLogExecutor
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
...
...
@@ -17,7 +18,7 @@ public class JdbcEventConfiguration {
}
@Bean
public
LcnExecuteTransactionJdbcEvent
lcnExecuteTransactionJdbcEvent
(){
return
new
LcnExecuteTransactionJdbcEvent
();
public
LcnExecuteTransactionJdbcEvent
lcnExecuteTransactionJdbcEvent
(
TransactionLogExecutor
transactionLogExecutor
){
return
new
LcnExecuteTransactionJdbcEvent
(
transactionLogExecutor
);
}
}
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/event/LcnCommitTransactionJdbcEvent.java
浏览文件 @
edb18587
...
...
@@ -2,8 +2,10 @@ package com.codingapi.txlcn.tc.jdbc.event;
import
com.codingapi.txlcn.p6spy.event.JdbcCallable
;
import
com.codingapi.txlcn.tc.TransactionConstant
;
import
com.codingapi.txlcn.tc.jdbc.JdbcTransaction
;
import
com.codingapi.txlcn.tc.jdbc.TransactionJdbcEvent
;
import
com.codingapi.txlcn.tc.jdbc.TransactionJdbcState
;
import
lombok.extern.slf4j.Slf4j
;
import
java.sql.Connection
;
import
java.sql.SQLException
;
...
...
@@ -13,6 +15,7 @@ import java.sql.SQLException;
* @date 2020/7/1
* @description
*/
@Slf4j
public
class
LcnCommitTransactionJdbcEvent
implements
TransactionJdbcEvent
{
@Override
...
...
@@ -26,7 +29,9 @@ public class LcnCommitTransactionJdbcEvent implements TransactionJdbcEvent {
}
@Override
public
Object
execute
(
Connection
connection
,
Object
param
)
throws
SQLException
{
public
Object
execute
(
Object
param
)
throws
SQLException
{
Connection
connection
=
JdbcTransaction
.
current
().
getConnection
();
log
.
info
(
"connection:{}"
,
connection
);
JdbcCallable
jdbcCallable
=
(
JdbcCallable
)
param
;
jdbcCallable
.
call
();
//不需要返回值,返回固定值1
...
...
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/event/LcnExecuteTransactionJdbcEvent.java
浏览文件 @
edb18587
package
com.codingapi.txlcn.tc.jdbc.event
;
import
com.codingapi.txlcn.tc.TransactionConstant
;
import
com.codingapi.txlcn.tc.jdbc.JdbcTransaction
;
import
com.codingapi.txlcn.tc.jdbc.TransactionJdbcEvent
;
import
com.codingapi.txlcn.tc.jdbc.TransactionJdbcState
;
import
com.codingapi.txlcn.tc.jdbc.log.TransactionLog
;
import
com.codingapi.txlcn.tc.jdbc.log.TransactionLogExecutor
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
java.sql.Connection
;
...
...
@@ -14,8 +18,11 @@ import java.sql.SQLException;
* @description
*/
@Slf4j
@AllArgsConstructor
public
class
LcnExecuteTransactionJdbcEvent
implements
TransactionJdbcEvent
{
private
TransactionLogExecutor
transactionLogExecutor
;
@Override
public
String
type
()
{
return
TransactionConstant
.
LCN
;
...
...
@@ -27,9 +34,15 @@ public class LcnExecuteTransactionJdbcEvent implements TransactionJdbcEvent {
}
@Override
public
Object
execute
(
Connection
connection
,
Object
param
)
throws
SQLException
{
public
Object
execute
(
Object
param
)
throws
SQLException
{
String
sql
=
(
String
)
param
;
Connection
connection
=
JdbcTransaction
.
current
().
getConnection
();
log
.
info
(
"connection:{}"
,
connection
);
log
.
info
(
"sql=>{}"
,
sql
);
TransactionLog
transactionLog
=
new
TransactionLog
(
sql
);
transactionLogExecutor
.
insert
(
connection
,
transactionLog
);
JdbcTransaction
.
current
().
add
(
transactionLog
);
return
sql
;
}
}
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/log/JdbcLogConfiguration.java
0 → 100644
浏览文件 @
edb18587
package
com.codingapi.txlcn.tc.jdbc.log
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
/**
* @author lorne
* @date 2020/7/1
* @description
*/
@Configuration
public
class
JdbcLogConfiguration
{
@Bean
public
TransactionLogExecutor
transactionLogExecutor
(
LogExecutor
logExecutor
){
return
new
TransactionLogExecutor
(
logExecutor
);
}
@Bean
@ConditionalOnProperty
(
name
=
"txlcn.tc.sql-type"
,
havingValue
=
"mysql"
)
public
LogExecutor
mysqlLogExecutor
(){
return
new
MysqlLogExecutor
();
}
}
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/log/LogExecutor.java
0 → 100644
浏览文件 @
edb18587
package
com.codingapi.txlcn.tc.jdbc.log
;
/**
* @author lorne
* @date 2020/7/1
* @description
*/
public
interface
LogExecutor
{
String
insert
(
TransactionLog
transactionLog
);
String
create
();
String
delete
(
long
id
);
}
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/log/MysqlLogExecutor.java
0 → 100644
浏览文件 @
edb18587
package
com.codingapi.txlcn.tc.jdbc.log
;
/**
* @author lorne
* @date 2020/7/1
* @description
*/
public
class
MysqlLogExecutor
implements
LogExecutor
{
@Override
public
String
insert
(
TransactionLog
transactionLog
)
{
return
"insert into `transaction_log`(`id`,`group_id`,`sql`,`time`,`flag`) values(?,?,?,?,?)"
;
}
@Override
public
String
create
()
{
return
null
;
}
@Override
public
String
delete
(
long
id
)
{
return
null
;
}
}
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/log/TransactionLog.java
0 → 100644
浏览文件 @
edb18587
package
com.codingapi.txlcn.tc.jdbc.log
;
import
com.codingapi.txlcn.tc.info.TransactionInfo
;
/**
* @author lorne
* @date 2020/7/1
* @description
*/
public
class
TransactionLog
{
public
TransactionLog
(
String
sql
)
{
//todo ID唯一算法
this
.
id
=
System
.
nanoTime
();
this
.
sql
=
sql
;
this
.
groupId
=
TransactionInfo
.
current
().
getGroupId
();
this
.
time
=
System
.
currentTimeMillis
();
this
.
flag
=
0
;
}
/**
* 日志主键
*/
private
long
id
;
/**
* 事务组Id
*/
private
String
groupId
;
/**
* 日志sql
*/
private
String
sql
;
/**
* 执行时间
*/
private
long
time
;
/**
* 日志标示
* 0 业务执行的sql
* 1 框架添加的sql
*/
private
int
flag
;
public
Object
[]
params
()
{
Object
[]
arrays
=
new
Object
[]{
id
,
groupId
,
sql
,
time
,
flag
};
return
arrays
;
}
}
txlcn-tc/src/main/java/com/codingapi/txlcn/tc/jdbc/log/TransactionLogExecutor.java
0 → 100644
浏览文件 @
edb18587
package
com.codingapi.txlcn.tc.jdbc.log
;
import
org.apache.commons.dbutils.QueryRunner
;
import
java.sql.Connection
;
import
java.sql.SQLException
;
/**
* @author lorne
* @date 2020/7/1
* @description
*/
public
class
TransactionLogExecutor
{
private
LogExecutor
logExecutor
;
private
QueryRunner
queryRunner
=
new
QueryRunner
();
public
TransactionLogExecutor
(
LogExecutor
logExecutor
)
{
this
.
logExecutor
=
logExecutor
;
}
public
void
insert
(
Connection
connection
,
TransactionLog
transactionLog
)
throws
SQLException
{
String
sql
=
logExecutor
.
insert
(
transactionLog
);
queryRunner
.
execute
(
connection
,
sql
,
transactionLog
.
params
());
}
public
void
delete
(
Connection
connection
,
long
id
)
throws
SQLException
{
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录