文章目录
- 1.原理深度解析
-
- 1.1注册驱动
- 1.2获取连接
- 1.3 获取数据库操作对象
- 1.4执行sql语句
- 1.5处理查询结果
- 1.6释放资源
- 2.账户转账
- 3.JDBC工具类包装
-
- 3.1包装工具类
- 3.2使用工具类实现模糊查询
【Mysql】JDBC从放弃到入门(上)
【Mysql】JDBC从放弃到入门(中)
【Mysql】JDBC从放弃到入门(下)
1.原理深度解析
1.1注册驱动
从驱动程序的源码中也可以看出com.mysql.cj.jdbc.Driver实现了java.sql.Driver这个接口。
registerDriver方法:
1.2获取连接
url:
getConnection方法:
1.3 获取数据库操作对象
Statement stmt = conn.createStatement();
1.4执行sql语句
int count = stmt.executeUpdate(sql);
1.5处理查询结果
1.6释放资源
2.账户转账
我们在数据库中并发操作的时候可能导致丢失修改,比如下面的例子。
sql脚本
drop table if exists t_act;
CREATE TABLE t_act(
actno int,
balance double(7, 2)
);
insert into t_act(actno, balance) values(111,20000);
insert into t_act(actno,balance) values(222,0);
commit;
select * from t_act;
package com.sdnu;
import java.sql.*;
/**
* @author Beyong
* @Description bank
* @date 2021/07/21 16:07
*/
public class bank {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
try{
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mydatabase?" +
"useUnicode=true&characterEncoding=utf-8&zeroDate" +
"TimeBehavior=convertToNull&allowMultiQueries=true&ser" +
"verTimezone=Asia/Shanghai&useSSL=false";
String user = "root";
String passWord = "123";
conn = DriverManager.getConnection(url,user,passWord);
String sql = "UPDATE t_act SET balance=? WHERE actno=?";
ps = conn.prepareStatement(sql);
ps.setDouble(1,10000);
ps.setInt(2,111);
int count = ps.executeUpdate();
String s = null;
s.toString();
ps = conn.prepareStatement(sql);
ps.setDouble(1,10000);
ps.setInt(2,222);
count += ps.executeUpdate();
}catch(SQLException e){
e.printStackTrace();
}catch(ClassNotFoundException e){
e.printStackTrace();
}finally{
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(ps != null){
try{
ps.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
}
我们专门设置一个异常在两个事务之间:
String s = null;
s.toString();
我们发现少了1000元。
于是我们修改我们的代码为如下:
package com.sdnu;
import java.sql.*;
/**
* @author Beyong
* @Description bank
* @date 2021/07/21 16:07
*/
public class bank {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
try{
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mydatabase?" +
"useUnicode=true&characterEncoding=utf-8&zeroDate" +
"TimeBehavior=convertToNull&allowMultiQueries=true&ser" +
"verTimezone=Asia/Shanghai&useSSL=false";
String user = "root";
String passWord = "123";
conn = DriverManager.getConnection(url,user,passWord);
//将自动提交事务改为手动
conn.setAutoCommit(false);//开启事务
String sql = "UPDATE t_act SET balance=? WHERE actno=?";
ps = conn.prepareStatement(sql);
ps.setDouble(1,10000);
ps.setInt(2,111);
int count = ps.executeUpdate();
String s = null;
s.toString();
ps = conn.prepareStatement(sql);
ps.setDouble(1,10000);
ps.setInt(2,222);
count += ps.executeUpdate();
System.out.println(count == 2 ? "转账成功" : "转账失败");
//程序走到这个说明程序没有错误,可以提交,手动提交,事务结束。
conn.commit();
}catch(Exception e){
if(conn != null){
try{
conn.rollback();//回滚
}catch(SQLException e1){
e1.printStackTrace();
}
}
} finally{
if(ps != null){
try{
ps.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
}
三行重要代码:
(1)conn.setAutoCommit(false);//开启事务
(2) conn.commit();//提交事务
(3) conn.rollback();//回滚
3.JDBC工具类包装
3.1包装工具类
为了以后使用方便我们可以将JDBC包装成工具类。以后直接调用即可。
package com.sdnu.utils;
import java.sql.*;
/**
* @author Beyong
* @Description JDBC工具类
* @date 2021/07/21 18:26
*/
public class DBUtil {
/**
*工具类中的方法都是私有的
* 工具类中的方法都是静态的
*/
private DBUtil(){};
static{
try{
Class.forName("com.mysql.cj.jdbc.Driver");
}catch(ClassNotFoundException e){
e.printStackTrace();
}
}
/**
* @author: Beyong
* @description:获取连接对象
* @param: []
* @return: java.sql.Connection
* @date: 2021/7/21 18:38
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase?" +
"useUnicode=true&characterEncoding=utf-8&zeroDate" +
"TimeBehavior=convertToNull&allowMultiQueries=true&ser" +
"verTimezone=Asia/Shanghai&useSSL=false","root","123");
}
/**
* @author: Beyong
* @description: 关闭资源
* @param: [java.sql.Connection, java.sql.Statement, java.sql.ResultSet]
* @return: void
* @date: 2021/7/21 18:45
*/
public static void close(Connection conn, Statement ps, ResultSet rs){
if( conn != null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(ps != null){
try{
ps.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if( rs != null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
3.2使用工具类实现模糊查询
package com.sdnu;
import com.sdnu.utils.DBUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @author Beyong
* @Description 测试JDBC工具
* @date 2021/07/21 18:54
*/
public class DBUtilTest {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
//获取连接
conn = DBUtil.getConnection();
String sql = "SELECT loginName FROM t_user WHERE realName like ?";
ps = conn.prepareStatement(sql);
ps.setString(1,"x%");
rs = ps.executeQuery();
while(rs.next()){
System.out.println(rs.getString("loginName"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
DBUtil.close(conn, ps, rs);
}
}
}
作者:Beyong
出处:Beyong博客
github地址:https://github.com/beyong2019
本博客中未标明转载的文章归作者Beyong有,欢迎转载,但未经作者同意必须保留此段声明,且在文章明显位置给出原文连接,否则保留追究法律责任的权利。