1、jdbc连接数据库
1.1、步骤
-
加载数据库驱动
- mysql驱动:com.mysql.jdbc.Driver
- oracle驱动:oracle.jdbc.driver.OracleDriver
Class.forName("com.mysql.jdbc.Driver")
-
获取连接
- mysql:jdbc:mysql://mysql主机IP:端口号(一般是3306)/数据库名?userUnicode=true&characterEncoding=utf8&useSSL=false
- oracle:jdbc:oracle:thin:@主机IP:端口号(一般是1521):数据库名
DriverManager.getConnection(url, user, password)
-
执行sql
使用预编译PreparedStatement,防止sql注入问题
-
获取结果集
-
关闭连接
不要忘了关闭连接
1.2、示例代码
package org.jdbc.util;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JdbcUtil {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;
static {
try {
InputStream in = JdbcUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties properties = new Properties();
properties.load(in);
driver = properties.getProperty("jdbc.driver");
url = properties.getProperty("jdbc.url");
username = properties.getProperty("jdbc.username");
password = properties.getProperty("jdbc.password");
// 加载驱动,只需要加载一次
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取连接
* @return
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
/**
* 释放连接
* @param conn
* @param stat
* @param rs
*/
public static void release(Connection conn, Statement stat, ResultSet rs){
try {
if(rs!=null) {
rs.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if(stat != null) {
stat.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if(conn != null) {
conn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
jdbc.properties文件
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/mine?userUnicode=true&characterEncoding=utf8&useSSL=false
jdbc.username = root
jdbc.password = root
2、事务
2.1、概述
要么都成功,要么都失败
ACID原则
-
原子性
事务是一个不可分割的工作单位,要么都成功,要么都失败
-
一致性
总数不变
-
隔离性
多个进程互不干扰,一个事务内部的操作及使用的数据对并发的其他事务是隔离的
-
持久性
一个事务一旦被提交,它对数据库中数据的改变就是 永久性的,接下来的其他操作和数据库故障不应该对其有任何影响,
持久化到了数据库了
隔离性的问题:
脏读:一个事务读取到了另一个没有提交的事务
不可重复读:在同一个事务内,重复读取表中的数据,表数据发生了改变
虚读:在同一个事务内,读取到了别人插入的数据,导致前后读取的结果不一致
2.2、示例代码:
@Test
public void testTransaction(){
Connection conn = null;
PreparedStatement ptst = null;
try {
// 获取连接
conn = JdbcUtil.getConnection();
conn.setAutoCommit(false); // 关闭自动提交,开启事务
String sql1 = "update account set money = money - 100 where name='A'";
// 预编译sql
ptst = conn.prepareStatement(sql1);
ptst.executeUpdate();
// 测试事务
int x = 1 / 0;
String sql2 = "update account set money = money + 100 where name='B'";
ptst = conn.prepareStatement(sql2);
ptst.executeUpdate();
// 业务完毕,提交事务
conn.commit();
System.out.println("成功");
} catch (SQLException e) {
// 出现异常,默认会自动调用rollback,回滚数据
e.printStackTrace();
} finally {
JdbcUtil.release(conn, ptst, null);
}
}