JDBC
JDBC
概念
Java DataBase Connectivity Java 数据库连接, Java语言操作数据库。
JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
步骤
-
导入驱动jar包
mysql-connector-java-5.1.37-bin.jar
-
复制
mysql-connector-java-5.1.37-bin.jar
到项目的libs目录下 -
右键-->Add As Library
-
-
注册驱动
-
获取数据库连接对象 Connection
-
定义sql
-
获取执行sql语句的对象 Statement
-
执行sql,接受返回结果
-
处理结果
-
释放资源
代码实现
1 public class Demo01 { 2 public static void main(String[] args) throws Exception { 3 // 注册驱动 4 Class.forName("com.mysql.jdbc.Driver"); 5 // 获取数据库连接对象 6 Connection coon = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root"); 7 // 定义sql语句 8 String sql = "update student set age=55 where id = 1"; 9 // 获取执行sql的对象 Statement 10 Statement stem = coon.createStatement(); 11 // 执行sql 12 int i = stem.executeUpdate(sql); 13 // 处理结果 14 System.out.println(i); 15 // 释放资源 16 stem.close(); 17 coon.close(); 18 } 19 }
详解各个对象
DriverManager:驱动管理对象
功能
-
注册驱动:告诉程序该使用哪一个数据库驱动jar
static void registerDriver(Driver driver)
:注册与给定的驱动程序 DriverManager 。写代码使用:
Class.forName("com.mysql.jdbc.Driver");
通过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块
1 static { 2 try { 3 DriverManager.registerDriver(new Driver()); 4 } catch (SQLException var1) { 5 throw new RuntimeException("Can't register driver!"); 6 } 7 }
注意:mysql5之后的驱动jar包可以省略注册驱动的步骤。
获取数据库连接:
方法:static Connection getConnection(String url, String user, String password)
参数:
-
url:指定连接的路径
-
语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
-
例子:jdbc:mysql://localhost:3306/db3
-
细节:如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称
-
-
user:用户名
-
password:密码
Connection:数据库连接对象
功能
-
获取执行sql 的对象
-
Statement createStatement()
-
PreparedStatement prepareStatement(String sql)
-
-
管理事务
-
开启事务:
setAutoCommit(boolean autoCommit)
:调用该方法设置参数为false,即开启事务 -
提交事务:
commit()
-
回滚事务:
rollback()
-
Statement:执行sql的对象
执行sql
-
boolean execute(String sql)
:可以执行任意的sql 了解 -
int executeUpdate(String sql)
:执行DML(insert、update、delete)语句、DDL(create,alter、drop)语句
返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功 返回值>0的则执行成功,反之,则失败。
ResultSet executeQuery(String sql)
:执行DQL(select)语句
ResultSet:结果集对象,封装查询结果
boolean next()
: 游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),如果是,则返回false,如果不是则返回true
getXxx(参数):获取数据
-
Xxx:代表数据类型 如: int getInt() , String getString()
参数:
-
int:代表列的编号,从1开始 如: getString(1)
-
String:代表列名称。 如: getDouble("balance")
注意:
-
游标向下移动一行
-
判断是否有数据
-
获取数据
//循环判断游标是否是最后一行末尾。
1 while(rs.next()){ 2 //获取数据 3 int id = rs.getInt(1); 4 String name = rs.getString("name"); 5 double balance = rs.getDouble(3); 6 7 System.out.println(id + "---" + name + "---" + balance); 8 }
抽取JDBC工具类 : JDBCUtils
目的:简化书写
分析:
-
注册驱动也抽取
-
抽取一个方法获取连接对象
-
需求:不想传递参数(麻烦),还得保证工具类的通用性。
-
解决:配置文件
url=
user=
password= -
-
抽取一个方法释放资源
1 public class JdbcUtils { 2 // 定义静态成员变量 3 private static String url; 4 private static String user; 5 private static String password; 6 private static String driver; 7 8 static { 9 // 读取资源文件,获取值 10 try { 11 // 创建Properties集合类 12 Properties pro = new Properties(); 13 // 加载文件 14 ClassLoader classLoader = JdbcUtils.class.getClassLoader(); 15 URL resource = classLoader.getResource("jdbc.properties"); 16 String path = resource.getPath(); 17 // System.out.println(path); 18 19 pro.load(new FileReader(path)); 20 // pro.load(new FileReader("src/jdbc.properties")); 21 // 获取数据,赋值 22 url = pro.getProperty("url"); 23 user = pro.getProperty("user"); 24 password = pro.getProperty("password"); 25 driver = pro.getProperty("driver"); 26 // 注册驱动 27 Class.forName(driver); 28 29 } catch (IOException e) { 30 e.printStackTrace(); 31 } catch (ClassNotFoundException e) { 32 e.printStackTrace(); 33 } 34 35 } 36 37 38 public static Connection getConnection() throws SQLException { 39 return DriverManager.getConnection(url, user, password); 40 } 41 42 public static void close(Statement statement, Connection connection) { 43 if (statement != null) { 44 try { 45 statement.close(); 46 } catch (SQLException e) { 47 e.printStackTrace(); 48 } 49 } 50 if (connection != null) { 51 try { 52 connection.close(); 53 } catch (SQLException e) { 54 e.printStackTrace(); 55 } 56 } 57 } 58 59 public static void close(ResultSet resultSet, Statement statement, Connection connection) { 60 if (resultSet != null) { 61 try { 62 resultSet.close(); 63 } catch (SQLException e) { 64 e.printStackTrace(); 65 } 66 } 67 if (statement != null) { 68 try { 69 statement.close(); 70 } catch (SQLException e) { 71 e.printStackTrace(); 72 } 73 } 74 if (connection != null) { 75 try { 76 connection.close(); 77 } catch (SQLException e) { 78 e.printStackTrace(); 79 } 80 } 81 } 82 }
JDBC控制事务:
-
事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。
-
操作:
-
开启事务
-
提交事务
-
回滚事务
-
-
使用Connection对象来管理事务
-
开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
-
在执行sql之前开启事务
-
-
提交事务:commit()
-
当所有sql都执行完提交事务
-
-
回滚事务:rollback()
-
在catch中回滚事务
-
-
1 public class JDBCDemo10 { 2 3 public static void main(String[] args) { 4 Connection conn = null; 5 PreparedStatement pstmt1 = null; 6 PreparedStatement pstmt2 = null; 7 8 try { 9 //1.获取连接 10 conn = JDBCUtils.getConnection(); 11 //开启事务 12 conn.setAutoCommit(false); 13 14 //2.定义sql 15 //2.1 张三 - 500 16 String sql1 = "update account set balance = balance - ? where id = ?"; 17 //2.2 李四 + 500 18 String sql2 = "update account set balance = balance + ? where id = ?"; 19 //3.获取执行sql对象 20 pstmt1 = conn.prepareStatement(sql1); 21 pstmt2 = conn.prepareStatement(sql2); 22 //4. 设置参数 23 pstmt1.setDouble(1, 500); 24 pstmt1.setInt(2, 1); 25 26 pstmt2.setDouble(1, 500); 27 pstmt2.setInt(2, 2); 28 //5.执行sql 29 pstmt1.executeUpdate(); 30 // 手动制造异常 31 int i = 3 / 0; 32 33 pstmt2.executeUpdate(); 34 //提交事务 35 conn.commit(); 36 } catch (Exception e) { 37 //事务回滚 38 try { 39 if (conn != null) { 40 conn.rollback(); 41 } 42 } catch (SQLException e1) { 43 e1.printStackTrace(); 44 } 45 e.printStackTrace(); 46 } finally { 47 JDBCUtils.close(pstmt1, conn); 48 JDBCUtils.close(pstmt2, null); 49 } 50 } 51 52 }