1.数据库驱动 驱动:声卡、显卡
在这里插入图片描述
我们的程序会通过 数据库驱动 和数据库打交道
2.JDBC sun 公司为了简化开发 人员的(对数据库的统一)操作,提供一个(Java操作数据库的)规范,俗称JDBC这些规范的实现由具体的厂商去做~
没有什么是加一层解决不了的
在这里插入图片描述
java.sql javax.sql 还需要导入一个数据库驱动包 mysql-connector-java-x.x.xx.jar
3、第一个JDBC程序 创建数据库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 create database jdbcstudy; use jdbcstudy;create table users( `id` int primary key , `name ` varchar (40 ), `password ` varchar (40 ), `email` varchar (40 ), `birthday` date );insert into users values (1 ,"闲言博客","321","123@163.com","2000-12-15") ,(2 ,"闲言","123","123@qq.com","2000-12-31") ,(3 ,"csdn闲言_","456","123@qq.com","2001-2-27")123456789101112131415 JAVA
1、创建一个普通项目 2、添加数据库驱动到项目中
在这里插入图片描述
在这里插入图片描述
现在lib 目录 可以展开了
在这里插入图片描述
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 package cn.bloghut.lesson01;import java.sql.*;public class JdbcFirstDemo { public static void main (String[] args) { try { Class.forName("com.mysql.jdbc.Driver" ); String url = "jdbc:mysql://localhost:3306/jdbcstudy" ; String username = "root" ; String password = "123" ; Connection connection = DriverManager.getConnection(url,username , password); String sql = "select * from users" ; Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(sql); while (resultSet.next()){ System.out.println("id:" +resultSet.getString("id" )+" name:" + resultSet.getString("name" ) +" password: " +resultSet.getString("password" )); } resultSet.close(); statement.cancel(); connection.close(); } catch (Exception e) { } } }12345678910111213141516171819202122232425262728293031323334353637383940414243444546 JAVA
步骤总结
加载驱动
创建连接 DriverManager
获取数据库对象 Statement
执行SQL
[获取结果集]
释放连接
DriverManager
1 2 3 4 5 6 7 8 // DriverManager.registerDriver(new com.mysql.jdbc.Driver()); Class.forName("com.mysql.jdbc.Driver" );// 固定写法,加载驱动// Connection 代表数据库// 数据库设置自动提交12345 JAVA
URL
1 2 3 4 5 6 7 8 9 String url = "jdbc:mysql://localhost:3306/jdbcstudy" ; jdbc:mysql:// 主机名:端口号/数据库名?参数1 &参数2 &参数3 // oracle --1521 jdbc:oracle:thin:@localhost:1521 :sid 123456 JAVA
Connection
1 2 3 4 5 6 connection.commit(); // 设置提交事务 connection.isReadOnly();// 是否只读 connection.setAutoCommit(true);// 设置事务自动提交123 JAVA
Statement(执行SQL的对象) prepareStatement()(执行SQL的对象)
1 2 3 4 5 6 statement.executeQuery(sql);// 执行查询,返回一个结果集 statement.execute();// 执行任何SQL statement.executeUpdate();// 执行更新操作:插入、修改、删除,返回受影响的行数123 JAVA
ResultSet 查询的结果集:封装了程序结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 --- 在不知道类型的情况下使用getObject类型 resultSet.getObject() -- 在知道类型的情况下使用对应类型 resultSet.getString() resultSet.getBigDecimal() resultSet.getFloat() resultSet.getDate() resultSet.getDouble() resultSet.getInt() resultSet.getLong()1234567891011 JAVA
遍历,指针
1 2 3 4 5 6 7 8 resultSet.next ();// 移动到下一个 resultSet.beforeFirst();// 移动到第一个 resultSet.afterLast();// 移动到最后面 resultSet.previous();// 移动到前一行 resultSet.absolute(row);// 移动到指定行12345 JAVA
释放资源
1 2 3 4 5 6 resultSet.close ();statement .cancel();connection .close ();123 JAVA
4、Statement 对象详解 jdbc中的statement 用于向数据库发送SQL语句,想要完成对数据库的增、删、改、查,只需要通过这个对象向数据库发送增删改查语句即可
Statement 对象的 executeUpdate方法,用于向数据库 发送增、删、改的SQL语句,executeUpdate执行完后,将会返回一个整数(即增删改语句导致数据库几行数据发生了变化)
Statement. executeQuery()方法用于向数据库发送 查询语句,executeQuery()方法返回代表查询结果的ResultSet对象。
CRUD操作–insert 使用statement.executeUpdate(String sql)方法完成数据添加操作
1 2 3 4 5 6 7 8 9 Statement statement = connection .createStatement(); String sql = "insert into user(...) values(...)"int num = statement .executeUpdate(sql );if (num > 0 ){ System .out .println("插入成功"); }123456 JAVA
CRUD操作–delete 加粗样式 使用statement.executeUpdate(String sql)方法完成数据删除操作
1 2 3 4 5 6 7 8 9 Statement statement = connection .createStatement(); String sql = "delete from user where id = 1"int num = statement .executeUpdate(sql );if (num > 0 ){ System .out .println("删除成功"); }123456 JAVA
CRUD操作–update 使用statement.executeUpdate(String sql)方法完成数据修改操作
1 2 3 4 5 6 7 8 9 Statement statement = connection .createStatement(); String sql = "update user set name='' where id = 1"int num = statement .executeUpdate(sql );if (num > 0 ){ System .out .println("修改成功"); }123456 JAVA
CRUD操作–select 使用statement.executeQuery(String sql) 完成查询操作
1 2 3 4 5 6 7 8 9 Statement statement = connection .createStatement(); String sql = "select * from user"; ResultSet rs = statement .executeQuery(sql );while (rs.next()){ //根据获取列的数据类型,分别调用rs的相应方法映射到java对象中 }123456 JAVA
代码实现: 1.提取工具类
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 package cn.bloghut.lesson02.utils;import java.io.InputStream;import java.sql.*;import java.util.Properties;public class JdbcUtils { private static String driver; private static String url; private static String username; private static String password; static { try { InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties" ); Properties properties = new Properties (); properties.load(in); driver = properties.getProperty("driver" ); url = properties.getProperty("url" ); username = properties.getProperty("username" ); password = properties.getProperty("password" ); Class.forName(driver); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection () throws SQLException { return DriverManager.getConnection(url, username, password); } public static void release (Connection connection, Statement statement, ResultSet resultSet) { if (connection != null ) { try { connection.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } if (statement != null ) { try { statement.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } if (resultSet != null ) { try { resultSet.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } } }123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 JAVA
2.增
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 package cn.bloghut.lesson02;import cn.bloghut.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class TestInsert { public static void main (String[] args) { Connection connection = null ; Statement statement = null ; ResultSet resultSet = null ; try { connection = JdbcUtils.getConnection(); statement = connection.createStatement(); String sql = "insert into users(id,name,password,email,birthday) values(4,'闲言','123','123@qq.com',null) " ; int num = statement.executeUpdate(sql); if (num > 0 ) { System.out.println("插入成功" ); } } catch (SQLException throwables) { throwables.printStackTrace(); } finally { JdbcUtils.release(connection, statement, resultSet); } } }1234567891011121314151617181920212223242526272829303132333435363738 JAVA
3.删
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 package cn.bloghut.lesson02;import cn.bloghut.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class TestDelete { public static void main (String[] args) { Connection connection = null ; Statement statement = null ; ResultSet resultSet = null ; try { connection = JdbcUtils.getConnection(); statement = connection.createStatement(); String sql = "delete from users where id = 4" ; int num = statement.executeUpdate(sql); if (num > 0 ) { System.out.println("删除成功" ); } } catch (SQLException throwables) { throwables.printStackTrace(); } finally { JdbcUtils.release(connection, statement, resultSet); } } }1234567891011121314151617181920212223242526272829303132333435363738 JAVA
4.改
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 package cn.bloghut.lesson02;import cn.bloghut.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class TestUpdate { public static void main (String[] args) { Connection connection = null ; Statement statement = null ; ResultSet resultSet = null ; try { connection = JdbcUtils.getConnection(); statement = connection.createStatement(); String sql = "update users set name='update闲言' where id = 2" ; int num = statement.executeUpdate(sql); if (num > 0 ) { System.out.println("修改成功" ); } } catch (SQLException throwables) { throwables.printStackTrace(); } finally { JdbcUtils.release(connection, statement, resultSet); } } }12345678910111213141516171819202122232425262728293031323334353637383940 JAVA
5.查
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 package cn.bloghut.lesson02;import cn.bloghut.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class TestQuery { public static void main (String[] args) { Connection connection = null ; Statement statement = null ; ResultSet resultSet = null ; try { connection = JdbcUtils.getConnection(); statement = connection.createStatement(); String sql = "select * from users" ; resultSet = statement.executeQuery(sql); while (resultSet.next()) { System.out.println(resultSet.getString(2 )); } } catch (SQLException throwables) { throwables.printStackTrace(); } finally { JdbcUtils.release(connection, statement, resultSet); } } }12345678910111213141516171819202122232425262728293031323334353637383940 JAVA
5.PreparedStatement 对象 SQL注入 问题 sql 存在漏洞,会被攻击,导致数据泄漏。SQL会被拼接
preparedStatement 可以防止SQL 注入,效率更好!
5.1、新增 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 package cn.bloghut.lesson03;import cn.bloghut.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.Date;import java.sql.PreparedStatement;public class TestInsert { public static void main (String[] args) { Connection connection = null ; PreparedStatement pst = null ; try { connection = JdbcUtils.getConnection(); String sql = "insert into users(id,name,password,email,birthday) values(?,?,?,?,?)" ; pst = connection.prepareStatement(sql); pst.setInt(1 , 4 ); pst.setString(2 , "闲言" ); pst.setString(3 , "123" ); pst.setString(4 , "123@qq.com" ); pst.setDate(5 , new Date (new java .util.Date().getTime())); int num = pst.executeUpdate(); if (num > 0 ) { System.out.println("插入成功!" ); } } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtils.release(connection, pst, null ); } } }123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 JAVA
5.2、删除 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 package cn.bloghut.lesson03;import cn.bloghut.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.Date;import java.sql.PreparedStatement;public class TestDelete { public static void main (String[] args) { Connection connection = null ; PreparedStatement pst = null ; try { connection = JdbcUtils.getConnection(); String sql = "delete from users where id = ?" ; pst = connection.prepareStatement(sql); pst.setInt(1 , 4 ); int num = pst.executeUpdate(); if (num > 0 ) { System.out.println("删除成功!" ); } } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtils.release(connection, pst, null ); } } }12345678910111213141516171819202122232425262728293031323334353637383940414243 JAVA
5.3、修改 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 package cn.bloghut.lesson03;import cn.bloghut.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.Date;import java.sql.PreparedStatement;public class TestUpdate { public static void main (String[] args) { Connection connection = null ; PreparedStatement pst = null ; try { connection = JdbcUtils.getConnection(); String sql = "update users set name=? where id = ?" ; pst = connection.prepareStatement(sql); pst.setString(1 , "闲言碎语" ); pst.setInt(2 , 1 ); int num = pst.executeUpdate(); if (num > 0 ) { System.out.println("修改成功!" ); } } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtils.release(connection, pst, null ); } } }12345678910111213141516171819202122232425262728293031323334353637383940414243 JAVA
5.4、查询 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 package cn.bloghut.lesson03;import cn.bloghut.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;public class TestExecuteQuery { public static void main (String[] args) { Connection conn = null ; PreparedStatement pst = null ; ResultSet rs = null ; try { conn = JdbcUtils.getConnection(); String sql = "select * from users where id = ?" ; pst = conn.prepareStatement(sql); pst.setInt(1 , 1 ); rs = pst.executeQuery(); while (rs.next()) { System.out.println(rs.getString("name" )); System.out.println(rs.getString("password" )); } } catch (SQLException throwables) { throwables.printStackTrace(); } finally { JdbcUtils.release(conn, pst, rs); } } }12345678910111213141516171819202122232425262728293031323334353637383940 JAVA
5.5、防止SQL注入 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 package cn.bloghut.lesson03;import cn.bloghut.lesson02.utils.JdbcUtils;import java.sql .Connection ;import java.sql .PreparedStatement;import java.sql .ResultSet;import java.sql .Statement ;public class SqlIn { public static void main(String[] args) { login ("闲言碎语", "123"); // login ("'or' 1=1","12133 'or'1=1"); } //登录业务 public static void login (String username, String password ) { Connection connection = null ; PreparedStatement pst = null ; ResultSet resultSet = null ; try { connection = JdbcUtils.getConnection(); //preparedStatement 防止sql 注入的本质,把传递进来的参数当做字符 //假设其中出现转义字符,就直接忽略了 String sql = "select * from users where name = ? and password = ?"; pst = connection .prepareStatement(sql ); pst.setString(1 ,username); pst.setString(2 ,password ); resultSet = pst.executeQuery(); while (resultSet.next()) { System .out .println(resultSet.getString("name")); System .out .println(resultSet.getString("password")); System .out .println("==================="); } } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtils.release (connection , pst, resultSet); } } }12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 JAVA
6、使用IDEA 连接数据库
在这里插入图片描述
在这里插入图片描述
连接
在这里插入图片描述
连接成功后可以选择数据库
在这里插入图片描述
勾选需要连接的数据库
在这里插入图片描述
双击表名即可查看表信息
在这里插入图片描述
7、事务 要么都成功,要么失败!
ACID原则
原子性:要么全部完成,要么都不完成
一致性:总数不变
持久性:一旦提交不可逆了,持久化到数据库了
隔离性:多个线程互不干扰
隔离性问题:
脏读:一个事务读取另一个没有提交的事务
不可重复读:在同一个事务内,重复读取表中的数据,表数据发生了变化
虚读(幻读):在一个事务内,读取到别人插入的数据,导致前后读出来的结果不一致
代码实现
开启事务
一组业务执行完成,提交事务
可以在catch语句中 显示的定义 回滚语句,但默认失败就会回滚
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 package cn.bloghut.lesson04;import cn.bloghut.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;public class TestTransaction_error { public static void main (String[] args) { Connection connection = null ; PreparedStatement pst = null ; try { connection = JdbcUtils.getConnection(); connection.setAutoCommit(false ); String sql1 = "update account set money = money-100 where name = 'A'" ; pst = connection.prepareStatement(sql1); pst.executeUpdate(); String sql2 = "update account set money = money+100 where name = 'B'" ; pst = connection.prepareStatement(sql2); pst.executeUpdate(); connection.commit(); System.out.println("成功!" ); } catch (Exception e) { try { connection.rollback(); } catch (SQLException throwables) { throwables.printStackTrace(); } e.printStackTrace(); } finally { JdbcUtils.release(connection, pst, null ); } } }12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 JAVA
数据库连接——执行完毕——释放 (连接—释放 :十分浪费系统资源)
池化技术:准备一些预先的资源,过来就连接预先准备好的
最小连接数:10 最大连接数:15 等待超时: 100ms
开源数据库实现
dbcp
c3p0
druid:阿里巴巴
使用了这些数据库连接池之后,我们在项目开发中就不需要编写连接数据库的代码了。
DBCP
需要用到的jar包
commons-dbcp-1.4
commons-pool-1.6
C3P0
需要用到的jar包
c3p0-0.9.5.5
mchange-commons-java-0.2.19
结论:无论使用什么数据源,本质还是一样,DataSource接口不会变,方法就不会变。