【Java】JDBC连接MySQL
JDBC连接MySQL
虽然在项目中通常用ORM的框架实现持久化。但经常因测试某些技术的需要,要写一个完整的JDBC查询数据库。写一个在这儿备份。
首先引入驱动包:
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
</dependencies>
写一个简单的连接测试是否能查询数据:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement; public class JDBCTester { public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
System.out.println("成功加载驱动"); Connection connection = null;
Statement statement = null;
ResultSet resultSet = null; try {
String url = "jdbc:mysql://localhost:3306/demo?user=root&password=123456&useUnicode=true&characterEncoding=UTF8";
connection = DriverManager.getConnection(url);
System.out.println("成功获取连接"); statement = connection.createStatement();
String sql = "select * from t_balance";
resultSet = statement.executeQuery(sql); resultSet.beforeFirst();
while (resultSet.next()) {
System.out.println(resultSet.getString(1));
}
System.out.println("成功操作数据库");
} catch(Throwable t) {
// TODO 处理异常
t.printStackTrace();
} finally {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
System.out.println("成功关闭资源");
} } }
看到以下日志,说明程序是正确的:
成功加载驱动
成功获取连接
1
成功操作数据库
成功关闭资源
JDBC的Connection默认是自动提交
| case | AutoCommit | 描述 | 结果 |
| 1 | Default(true) | 没有异常,没有显式commit | 更新 |
| 2 | Default(true) | 有异常,没有显式commit | 更新 |
| 3 | Default(true) | 有异常,没有显式commit,有显式rollback | 更新,异常包含Can't call rollback when autocommit=true |
case 1:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class JDBCTools { public static void main(String[] args) throws Exception {
JDBCTools.query("select * from t_balance t");
System.out.println();
JDBCTools.execute("update t_balance t set t.balance = 20000 where t.user_id = 100");
System.out.println();
JDBCTools.query("select * from t_balance t");
} public static String HOST = "localhost";
public static String PORT = "3306";
public static String DATABASE_NAME = "demo";
public static String USER_NAME = "root";
public static String PASSWORD = "123456"; /**
* 获取数据库连接
* @return 数据库连接
*/
public static Connection getConn() throws Exception {
Class.forName("com.mysql.jdbc.Driver");
System.out.println("成功加载驱动"); String url = "jdbc:mysql://" + HOST + ":" + PORT + "/" + DATABASE_NAME + "?user=" + USER_NAME + "&password=" + PASSWORD + "&useUnicode=true&characterEncoding=UTF8";
Connection connection = DriverManager.getConnection(url);
System.out.println("成功获取连接");
return connection;
} /**
* 关闭资源
*/
public static void closeResource(Connection conn, Statement st, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
if (st != null) {
try {
st.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
System.out.println("成功关闭资源");
} /**
* 查询SQL
* @param sql 查询语句
* @return 数据集合
* @throws SQLException
*/
public static List<Map<String, String>> query(String sql) throws Exception {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
List<Map<String, String>> resultList = null; try {
connection = JDBCTools.getConn(); statement = connection.createStatement();
resultSet = statement.executeQuery(sql);
System.out.println("SQL : " + sql); ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
int columnCount = resultSetMetaData.getColumnCount();
String[] columnNames = new String[columnCount + 1];
for (int i = 1; i <= columnCount; i++) {
columnNames[i] = resultSetMetaData.getColumnName(i);
} resultList = new ArrayList<Map<String, String>>();
Map<String, String> resultMap = new HashMap<String, String>();
resultSet.beforeFirst();
while (resultSet.next()) {
for (int i = 1; i <= columnCount; i++) {
resultMap.put(columnNames[i], resultSet.getString(i));
}
resultList.add(resultMap);
}
System.out.println("成功查询数据库,查得数据:" + resultList);
} catch(Throwable t) {
// TODO 处理异常
t.printStackTrace();
} finally {
JDBCTools.closeResource(connection, statement, resultSet);
} return resultList;
} /**
* 执行SQL
* @param sql 执行的SQL
* @return 操作条数
*/
public static int execute(String sql) throws Exception {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
int num = 0; try {
connection = JDBCTools.getConn(); statement = connection.createStatement();
num = statement.executeUpdate(sql);
System.out.println("SQL : " + sql);
System.out.println("成功操作数据库,影响条数:" + num); // 模拟异常,用于测试事务
/*
if (1 == 1) {
throw new RuntimeException();
}
*/ } catch(Exception e) {
// 处理异常:回滚事务后抛出异常
e.printStackTrace();
// connection.rollback();
System.out.println("事务回滚");
throw e;
} finally {
JDBCTools.closeResource(connection, statement, resultSet);
} return num;
} }
成功加载驱动
成功获取连接
SQL : select * from t_balance t
成功查询数据库,查得数据:[{id=1, balance=10000, user_id=100}]
成功关闭资源 成功加载驱动
成功获取连接
SQL : update t_balance t set t.balance = 20000 where t.user_id = 100
成功操作数据库,影响条数:1
成功关闭资源 成功加载驱动
成功获取连接
SQL : select * from t_balance t
成功查询数据库,查得数据:[{id=1, balance=20000, user_id=100}]
成功关闭资源
case 2 :
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class JDBCTools { public static void main(String[] args) throws Exception {
JDBCTools.query("select * from t_balance t");
System.out.println();
JDBCTools.execute("update t_balance t set t.balance = 20000 where t.user_id = 100");
System.out.println();
JDBCTools.query("select * from t_balance t");
} public static String HOST = "localhost";
public static String PORT = "3306";
public static String DATABASE_NAME = "demo";
public static String USER_NAME = "root";
public static String PASSWORD = "123456"; /**
* 获取数据库连接
* @return 数据库连接
*/
public static Connection getConn() throws Exception {
Class.forName("com.mysql.jdbc.Driver");
System.out.println("成功加载驱动"); String url = "jdbc:mysql://" + HOST + ":" + PORT + "/" + DATABASE_NAME + "?user=" + USER_NAME + "&password=" + PASSWORD + "&useUnicode=true&characterEncoding=UTF8";
Connection connection = DriverManager.getConnection(url);
System.out.println("成功获取连接");
return connection;
} /**
* 关闭资源
*/
public static void closeResource(Connection conn, Statement st, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
if (st != null) {
try {
st.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
System.out.println("成功关闭资源");
} /**
* 查询SQL
* @param sql 查询语句
* @return 数据集合
* @throws SQLException
*/
public static List<Map<String, String>> query(String sql) throws Exception {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
List<Map<String, String>> resultList = null; try {
connection = JDBCTools.getConn(); statement = connection.createStatement();
resultSet = statement.executeQuery(sql);
System.out.println("SQL : " + sql); ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
int columnCount = resultSetMetaData.getColumnCount();
String[] columnNames = new String[columnCount + 1];
for (int i = 1; i <= columnCount; i++) {
columnNames[i] = resultSetMetaData.getColumnName(i);
} resultList = new ArrayList<Map<String, String>>();
Map<String, String> resultMap = new HashMap<String, String>();
resultSet.beforeFirst();
while (resultSet.next()) {
for (int i = 1; i <= columnCount; i++) {
resultMap.put(columnNames[i], resultSet.getString(i));
}
resultList.add(resultMap);
}
System.out.println("成功查询数据库,查得数据:" + resultList);
} catch(Throwable t) {
// TODO 处理异常
t.printStackTrace();
} finally {
JDBCTools.closeResource(connection, statement, resultSet);
} return resultList;
} /**
* 执行SQL
* @param sql 执行的SQL
* @return 操作条数
*/
public static int execute(String sql) throws Exception {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
int num = 0; try {
connection = JDBCTools.getConn(); statement = connection.createStatement();
num = statement.executeUpdate(sql);
System.out.println("SQL : " + sql);
System.out.println("成功操作数据库,影响条数:" + num); // 模拟异常,用于测试事务
if (1 == 1) {
throw new RuntimeException();
} } catch(Exception e) {
// 处理异常:回滚事务后抛出异常
e.printStackTrace();
// connection.rollback();
System.out.println("事务回滚");
throw e;
} finally {
JDBCTools.closeResource(connection, statement, resultSet);
} return num;
} }
成功加载驱动
成功获取连接
SQL : select * from t_balance t
成功查询数据库,查得数据:[{id=1, balance=10000, user_id=100}]
成功关闭资源 成功加载驱动
成功获取连接
SQL : update t_balance t set t.balance = 20000 where t.user_id = 100
成功操作数据库,影响条数:1
事务回滚
java.lang.RuntimeException
at JDBCTools.execute(JDBCTools.java:140)
at JDBCTools.main(JDBCTools.java:17)
成功关闭资源
Exception in thread "main" java.lang.RuntimeException
at JDBCTools.execute(JDBCTools.java:140)
at JDBCTools.main(JDBCTools.java:17)
case 3 :
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class JDBCTools { public static void main(String[] args) throws Exception {
JDBCTools.query("select * from t_balance t");
System.out.println();
JDBCTools.execute("update t_balance t set t.balance = 20000 where t.user_id = 100");
System.out.println();
JDBCTools.query("select * from t_balance t");
} public static String HOST = "localhost";
public static String PORT = "3306";
public static String DATABASE_NAME = "demo";
public static String USER_NAME = "root";
public static String PASSWORD = "123456"; /**
* 获取数据库连接
* @return 数据库连接
*/
public static Connection getConn() throws Exception {
Class.forName("com.mysql.jdbc.Driver");
System.out.println("成功加载驱动"); String url = "jdbc:mysql://" + HOST + ":" + PORT + "/" + DATABASE_NAME + "?user=" + USER_NAME + "&password=" + PASSWORD + "&useUnicode=true&characterEncoding=UTF8";
Connection connection = DriverManager.getConnection(url);
System.out.println("成功获取连接");
return connection;
} /**
* 关闭资源
*/
public static void closeResource(Connection conn, Statement st, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
if (st != null) {
try {
st.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
System.out.println("成功关闭资源");
} /**
* 查询SQL
* @param sql 查询语句
* @return 数据集合
* @throws SQLException
*/
public static List<Map<String, String>> query(String sql) throws Exception {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
List<Map<String, String>> resultList = null; try {
connection = JDBCTools.getConn(); statement = connection.createStatement();
resultSet = statement.executeQuery(sql);
System.out.println("SQL : " + sql); ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
int columnCount = resultSetMetaData.getColumnCount();
String[] columnNames = new String[columnCount + 1];
for (int i = 1; i <= columnCount; i++) {
columnNames[i] = resultSetMetaData.getColumnName(i);
} resultList = new ArrayList<Map<String, String>>();
Map<String, String> resultMap = new HashMap<String, String>();
resultSet.beforeFirst();
while (resultSet.next()) {
for (int i = 1; i <= columnCount; i++) {
resultMap.put(columnNames[i], resultSet.getString(i));
}
resultList.add(resultMap);
}
System.out.println("成功查询数据库,查得数据:" + resultList);
} catch(Throwable t) {
// TODO 处理异常
t.printStackTrace();
} finally {
JDBCTools.closeResource(connection, statement, resultSet);
} return resultList;
} /**
* 执行SQL
* @param sql 执行的SQL
* @return 操作条数
*/
public static int execute(String sql) throws Exception {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
int num = 0; try {
connection = JDBCTools.getConn(); statement = connection.createStatement();
num = statement.executeUpdate(sql);
System.out.println("SQL : " + sql);
System.out.println("成功操作数据库,影响条数:" + num); // 模拟异常,用于测试事务
if (1 == 1) {
throw new RuntimeException();
} } catch(Exception e) {
// 处理异常:回滚事务后抛出异常
e.printStackTrace();
connection.rollback();
System.out.println("事务回滚");
throw e;
} finally {
JDBCTools.closeResource(connection, statement, resultSet);
} return num;
} }
成功加载驱动
成功获取连接
SQL : select * from t_balance t
成功查询数据库,查得数据:[{id=1, balance=10000, user_id=100}]
成功关闭资源 成功加载驱动
成功获取连接
SQL : update t_balance t set t.balance = 20000 where t.user_id = 100
成功操作数据库,影响条数:1
java.lang.RuntimeException
at JDBCTools.execute(JDBCTools.java:140)
at JDBCTools.main(JDBCTools.java:17)
成功关闭资源
Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Can't call rollback when autocommit=true
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
at com.mysql.jdbc.Util.getInstance(Util.java:387)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:917)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:896)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:885)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860)
at com.mysql.jdbc.ConnectionImpl.rollback(ConnectionImpl.java:4618)
at JDBCTools.execute(JDBCTools.java:146)
at JDBCTools.main(JDBCTools.java:17)
最简单的工具类
封装个简单的查询MySQL的工具类更方便使用。注:此实现非常简单,仅用于日常测试,不适合生产环境使用。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class JDBCTools { public static void main(String[] args) throws Exception {
JDBCTools.query("select * from t_balance t");
JDBCTools.execute("update t_balance t set t.balance = 20000 where t.user_id = 100");
JDBCTools.query("select * from t_balance t");
} public static String HOST = "localhost";
public static String PORT = "3306";
public static String DATABASE_NAME = "demo";
public static String USER_NAME = "root";
public static String PASSWORD = "123456"; /**
* 获取数据库连接
* @return 数据库连接
*/
public static Connection getConn() throws Exception {
Class.forName("com.mysql.jdbc.Driver");
System.out.println("成功加载驱动"); String url = "jdbc:mysql://" + HOST + ":" + PORT + "/" + DATABASE_NAME + "?user=" + USER_NAME + "&password=" + PASSWORD + "&useUnicode=true&characterEncoding=UTF8";
Connection connection = DriverManager.getConnection(url);
System.out.println("成功获取连接");
return connection;
} /**
* 关闭资源
*/
public static void closeResource(Connection conn, Statement st, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
if (st != null) {
try {
st.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
System.out.println("成功关闭资源");
} /**
* 查询SQL
* @param sql 查询语句
* @return 数据集合
* @throws SQLException
*/
public static List<Map<String, String>> query(String sql) throws Exception {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
List<Map<String, String>> resultList = null; try {
connection = JDBCTools.getConn(); statement = connection.createStatement();
resultSet = statement.executeQuery(sql); ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
int columnCount = resultSetMetaData.getColumnCount();
String[] columnNames = new String[columnCount + 1];
for (int i = 1; i <= columnCount; i++) {
columnNames[i] = resultSetMetaData.getColumnName(i);
} resultList = new ArrayList<Map<String, String>>();
Map<String, String> resultMap = new HashMap<String, String>();
resultSet.beforeFirst();
while (resultSet.next()) {
for (int i = 1; i <= columnCount; i++) {
resultMap.put(columnNames[i], resultSet.getString(i));
}
resultList.add(resultMap);
}
System.out.println("成功查询数据库,查得数据:" + resultList);
} catch(Throwable t) {
// TODO 处理异常
t.printStackTrace();
} finally {
JDBCTools.closeResource(connection, statement, resultSet);
} return resultList;
} /**
* 执行SQL
* @param sql 执行的SQL
* @return 操作条数
*/
public static int execute(String sql) throws Exception {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
int num = 0; try {
connection = JDBCTools.getConn();
connection.setAutoCommit(false); statement = connection.createStatement();
num = statement.executeUpdate(sql);
System.out.println("成功操作数据库,影响条数:" + num); // 模拟异常,用于测试事务
/*
if (1 == 1) {
throw new RuntimeException();
}
*/ connection.commit();
} catch(Exception e) {
// 处理异常:回滚事务后抛出异常
e.printStackTrace();
connection.rollback();
System.out.println("事务回滚");
throw e;
} finally {
JDBCTools.closeResource(connection, statement, resultSet);
} return num;
} }
【Java】JDBC连接MySQL的更多相关文章
- java jdbc 连接mysql数据库 实现增删改查
好久没有写博文了,写个简单的东西热热身,分享给大家. jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打 ...
- java jdbc 连接mysql 数据库
JDBC连接MySQL 加载及注册JDBC驱动程序 Class.forName("com.mysql.jdbc.Driver"); Class.forName("com. ...
- java jdbc连接mysql
JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口 ...
- JAVA使用jdbc连接MYSQL简单示例
以下展示的为JAVA使用jdbc连接MYSQL简单示例: import java.sql.DriverManager; import java.sql.ResultSet; import java.s ...
- java用JDBC连接MySQL数据库的详细知识点
想实现java用JDBC连接MySQL数据库.需要有几个准备工作: 1.下载Connector/J的库文件,下载Connector/J的官网地址:http://www.mysql.com/downlo ...
- Java编程学习之JDBC连接MySQL
JDBC连接MySQL 一.对JDBC连接数据库的步骤1.加载数据库驱动//加载驱动Class.forName(driverClass)-------------------------------- ...
- (Win10)Java,Maven,Tomcat8.0,Mysql8.0.15安装与环境配置,以及IDEA2019.3使用JDBC连接MySQL、创建JavaEE项目
之前用windows+linux的双系统,最近不怎么舒服就把双系统给卸了,没想到除了问题,导致有linux残余,于是就一狠心重装了电脑,又把Java及其相关的一些东西重新装了回来,还好当初存了网盘链接 ...
- ava基础MySQL存储过程 Java基础 JDBC连接MySQL数据库
1.MySQL存储过程 1.1.什么是存储过程 带有逻辑的sql语句:带有流程控制语句(if while)等等 的sql语句 1.2.存储过程的特点 1)执行效率非常快,存储过程是数据库的服 ...
- JDBC连接MySQL数据库代码模板
下面这个例子是最简单的JDBC连接MySQL数据库的例子. 一般步骤: 1.注册驱动: 2.建立连接: 3.创建语句: 4.处理结果: 5.释放资源. 注意: 1.软件开发环境:MyEclipse 8 ...
随机推荐
- 多屏复杂动画CSS技巧三则(转载)
本文转载自: 经验分享:多屏复杂动画CSS技巧三则
- paper 3:matlab中save,load使用方法小结
功能描述]存储文件[软件界面]MATLAB->File->Save Workspace As将变量存入硬盘中指定路径.[函数用法] save:该函数将所有workspace中变量用二进制格 ...
- zw版【转发·台湾nvp系列Delphi例程】HALCON CropPart
zw版[转发·台湾nvp系列Delphi例程]HALCON CropPart procedure TForm1.Button1Click(Sender: TObject);var ho_Egypt1 ...
- [经典php视频]构建正则表达式解析网页中的图像标记<img>
这是高洛峰php视频中的一段,视频中一边分析需要的功能,一边构建greg_match函数的参数,边讲解边实战,是非常好的一种构建功能的演示. 你不可能把浩瀚的IT资料都记在脑袋里,也不可能随时随地透过 ...
- 怎样查出SQLServer的性能瓶颈
怎样查出SQLServer的性能瓶颈 --王成辉翻译整理,转贴请注明出自微软BI开拓者[url]www.windbi.com[/url]--原帖地址 如果你曾经做了很长时间的DBA,那么你会了解到SQ ...
- D5转Xe点滴
1. VarIsNull 函数已经被 Variants 单元, 相应的 Var 相关都放在哪 2.原本在 SysUtils 下的部分格式函数或定义,例如 .DecimalSeparator: Sho ...
- 161114、websocket实现心跳重连
心跳重连缘由 在使用websocket过程中,可能会出现网络断开的情况,比如信号不好,或者网络临时性关闭,这时候websocket的连接已经断开, 而浏览器不会执行websocket 的 onclos ...
- React笔记_(1)_react概述
React概述 React是一种很好的前端技术. 它将应用打散成独立的小模块,然后进行组装,完成开发. react远比angularjs难学的多. react依赖的如webpack等各种工具得先学 ...
- git 用法
git init #创建仓库git add _filename #添加文件到缓冲区git commit -m "msg" #提交更新,从缓冲区提交到版本库git status #查 ...
- 测试过程中LR的关联报错
在测试过程中,录制的脚本会做一些关联.在测试的过程中,常常出现关联失败的情况. 如果最后的结果有检查点,检查点失败而事务失败. 每次出现这样的情况,我都不知道如何办.为了不出现错误,我都在关联函数里面 ...