引言:
把Java和数据库联系起来
这就是JDBC
JDBC 概念:Java DataBase Connectivity Java数据库连接
本质:官方定义的一套操作所有关系型数据库的规则,即接口。
各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口编程,真正执行的代码是驱动jar包中的实现类
快速入门 步骤:
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Class.forName("com.mysql.cj.jdbc.Driver" ); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/database?serverTimezone=UTC" ,"root" ,"root" ); String sql = "update deliver set bank = 500 where id = 1" ; Statement statement = conn.createStatement(); int count = statement.executeUpdate(sql);System.out.println(count); statement.close(); conn.close();
详解JDBC各个对象 概览:
DirverManager:驱动管理对象
Connection:数据库连接对象
Statement:执行SQL对象
ResultSet:结果集对象
PreparedStatement:执行SQL对象(是Statement的子接口,但功能更加强大)
DirverManager DirverManager是驱动管理类
功能:
注册驱动
获取数据库连接包路径
注册驱动 现在大部分的jar包都可以直接的注册,只要jar包内含有 META-INF/services/java.sql.Dirver
这个文件,这个文件内已经有 com.mysql.cj.jdbc.Driver
这条信息, 所以可以自动的注册驱动,如果不能自动注册驱动,再来手动的注册驱动
mysql5.0 版本后注册驱动的代码可以省略,jar包会自动注册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 static void registerDriver (Driver driver) Class.forName ("com.mysql.cj.jdbc.Driver" ) ;
获取数据库连接 sql语句中使用了类似URL的相似语法来描述数据源, url的MySQL语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
1 2 3 4 5 static Connection getConnection (String url, String user, String password)
如果连接的是本机127.0.0.1
的mysql服务器,并且myql服务端默认为3306,则url可以简化为
Connection Connection数据库连接对象
功能:
获取执行SQL的对象statement
管理事务
包路径
获取执行sql的对象 1 2 3 4 5 Statement createStatement () PreparedStatement prepareStatement (String sql)
管理事务 1 2 3 4 5 6 7 8 9 10 # 开启事务 void setAutoCommit (boolean autoCommit) # 提交事务 void commit () # 回滚事务 void rollback ()
Statement 用于执行静态SQL语句 并返回其生成的结果的对象
功能:
执行sql
包路径
执行sql 1 2 3 4 5 6 7 8 9 10 11 12 boolean execute (String sql) int executeUpdate (String sql) ResultSet executeQuery (String sql)
ResultSet
数据库的列表就是一个结果集,一开始结果集的光标在最上方,表头的部分,我们需要先将它移动至下一行 才能读取数据next()
获取数据getXxx(参数)
Xxx代表数据类型,参数可以写int型的列编号 从1开始 ,可以写String型的字段
例如:这样的一张表
1 2 3 4 5 6 7 +----+------+----------+ | id | name | PASSWORD | +----+------+----------+ | 1 | 李 | 123 | | 2 | 王 | 456 | | 3 | 张 | 789 | +----+------+----------+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 while (resultSet.next()){ System.out.print( resultSet.getInt(1 ) + "-" + resultSet.getString(2 ) + "-" + resultSet.getInt(3 )+"\r\n" ); } while (resultSet.next()){ System.out.print( resultSet.getInt("id" ) +"-" + resultSet.getString("name" ) +"-" + resultSet.getInt("password" )+"\r\n" ); }
ResultSet结果集方法 1 2 3 4 5 6 7 8 boolean next () ;Xxx getXxx () void close () ;
管理连接、语句、结果集 每个Connection对象都可以创建一个或者多个Statement语句,同一个Statement对象可以用于多个不相关的命令和查询,但是 一个Statement对象最多只能有一个打开的结果集
这就是说,如果我们要进行多组插入或者删除,只需要一个Statement对象即可
但是如果需要执行多个查询操作,并且要同时分析查询结果,我们要创建多个Statement对象
但实际上,我们不需要同时处理多个结果集,对数据库进行组合查询比使用java遍历结果集要高效的多
PreparedStatement
prepared statement 预备语句:一个带有宿主变量的查询语句,可以进行动态的查找
优点:
安全,防止代码注入问题
高效,改进了查询的性能
通过连接获得预备语句 1 PreparedStatement Connection.prepareStatement(String sql)
构造完成后,我们还不能直接的执行sql语句,我们必须先进行一下绑定
与变量?绑定
注意: 只有查询涉及变量时,才应该使用预备语句
如果想要重用已经执行过的sql语句,必须先使用setXxx()
或者clearParameters
方法重新设置宿主变量和绑定,否则这些绑定关系都不会改变
示例 原本
1 2 String sql = "select * from user where name = ? and password = ?" ;
现在
1 2 3 4 5 6 7 String sql = "select * from user where name = ? and password = ?" ; preStat = conn.prepareStatement(sql); preStat.setString(1 ,name); preStat.setString(2 ,pass); rs = preStat.executeQuery();
预备语句方法 1 2 3 4 5 6 7 8 9 10 11 void serXxx (int n, Xxx x) void clearParameters () ResultSet executeQuery () int executeUpdate ()
demo示例 1. 简单的demo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 public class JdbcDemo2 { public static void main (String[] args) { Statement stat = null ; Connection conn =null ; try { Class.forName("com.mysql.cj.jdbc.Driver" ); String sql = "insert into deliver values(null,'李',3000)" ; conn = DriverManager.getConnection("jdbc:mysql:///database?serverTimezone=UTC" , "root" , "root" ); stat = conn.createStatement(); int i = stat.executeUpdate(sql); if (i>0 ){ System.out.println("添加成功" ); }else { System.out.println("添加失败" ); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); }finally { if (stat!=null ){ try { stat.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn!=null ){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
2. 完整的demo 创建了Jdbcutils的工具类JdbcUtils
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 public class JdbcUtils {private static String url;private static String user;private static String password;private static String driver;static { try { Properties pro = new Properties(); ClassLoader cl = JdbcUtils.class.getClassLoader(); URL res = cl.getResource("jdbc.properties" ); String path = res.getPath(); pro.load(new FileReader(path)); url = pro.getProperty("url" ); user = pro.getProperty("user" ); password = pro.getProperty("password" ); driver = pro.getProperty("driver" ); Class.forName(driver); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection () throws SQLException { return DriverManager.getConnection(url,user,password); } public static void close (Statement stat, Connection conn) { if (stat != null ) { try { stat.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null ) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } public static void close (ResultSet rs, Statement stat, Connection conn) { if (stat != null ) { try { stat.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null ) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } if (rs != null ) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
配置文件jdbc.properties
1 2 3 4 url = jdbc:mysql:///database?serverTimezone=UTC user = root password = root driver = com.mysql.cj.jdbc.Driver
保存的类对象Person
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public class JdbcDemo4 { public static void main (String[] args) { List<Person> list = new JdbcDemo4().findAll(); System.out.println(list); } public List<Person> findAll () { Connection conn = null ; Statement stat = null ; ResultSet rs = null ; List<Person> list = null ; try { conn = JdbcUtils.getConnection(); String sql = "select * from deliver" ; stat = conn.createStatement(); rs = stat.executeQuery(sql); Person p = null ; list = new ArrayList<Person>(); while (rs.next()){ int id = rs.getInt(1 ); String name = rs.getString(2 ); int bank = rs.getInt(3 ); p = new Person(); p.setId(id); p.setName(name); p.setBank(bank); list.add(p); } }catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.close(rs,stat,conn); } return list; } }
3. 登录的demo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public class JdbcDemo5 { public static void main (String[] args) { Scanner sc = new Scanner(System.in); String name = sc.next(); String password = sc.next(); if (new JdbcDemo5().login(name, password)) { System.out.println("登陆成功" ); } else { System.out.println("登录失败" ); } } public boolean login (String name, String pass) { Connection conn = null ; PreparedStatement preStat = null ; ResultSet rs = null ; if (name != null && pass != null ) { try { conn = JdbcUtils.getConnection(); String sql = "select * from user where name = ? and password = ?" ; preStat = conn.prepareStatement(sql); preStat.setString(1 ,name); preStat.setString(2 ,pass); rs = preStat.executeQuery(); return rs.next(); } catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.close(rs, preStat, conn); } return false ; } else { return false ; } } }
支付操作的demo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public class JdbcDemo6 {public static void main (String[] args) { Connection conn = null ; PreparedStatement preStat1 = null ; PreparedStatement preStat2 = null ; ResultSet rs = null ; try { conn = JdbcUtils.getConnection(); conn.setAutoCommit(false ); String sql1 = "update deliver set bank = bank -? where id = ?" ; String sql2 = "update deliver set bank = bank +? where id = ?" ; preStat1 = conn.prepareStatement(sql1); preStat2 = conn.prepareStatement(sql2); preStat1.setString(1 ,"500" ); preStat1.setString(2 ,"3" ); preStat2.setString(1 ,"500" ); preStat2.setString(2 ,"2" ); preStat1.executeUpdate(); preStat2.executeUpdate(); conn.commit(); } catch (Exception e) { e.printStackTrace(); if (conn!=null ){ try { conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } } }finally { JdbcUtils.close(rs,preStat1,conn); JdbcUtils.close(null ,preStat2,null ); } } }