1.JDBC的由来
2.JDBC规范
3.JDBC操作步骤
4.JDBC快速入门
5.JDBC相关API详解
注册驱动(DriverManager)
Connection
Statement
ResultSet(执行原理)
6.JDBC实现单表的增删改查
7.JDBC事务
8.JDBC工具类抽取(获得连接和释放资源)
9.JDBC实现登录案例
10.SQL注入(预编译对象引入)
11.使用PreparedStatement对象改写登录案例
12.PreparedStatement的执行原理
13.使用PreparedStatement完成增删改查
14.连接池(原理)
15.DRUID连接池
16.连接池工具类
=======================================================================================================================================================================
- JDBC的由来!
-
JDBC规范
见图解! -
JDBC入门程序!
第一步:创建一个工程(今天是Java工程,明天开始是Web工程)
第二步:导入数据库驱动包!(在模块下面创建一个目录,名称为lib,复制MySQL驱动包,不要忘记右键添加!)
第三步:创建一个类(HelloWorld),里面定义一个方法!
具体步骤才,参考类中的注释!// 1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");// 准备连接数据库的三个参数!
// 连接地址(指定连接哪台电脑里面的MySQL数据库的哪个库)
String url = "jdbc:mysql://localhost:3306/day30_db";
// 连接MySQL用户名
String username = "root";
// 连接MySQL的密码
String password = "root";// 2. 获得连接对象
Connection conn = DriverManager.getConnection(url, username, password);// 3.编写SQL语句
String sql = "insert into category values(null,'床上用品')";// 4. 获得执行SQL语句对象
Statement stmt = conn.createStatement();// 5. 执行SQL语句
int rows = stmt.executeUpdate(sql);
System.out.println(rows);// 6.释放资源
stmt.close();
conn.close(); -
JDBC相关的API学习
★ 注册驱动方式一:Class.forName("com.mysql.jdbc.Driver"); // 加载驱动类!
上面的代码,将类Driver加载到内存,生成字节码对象!【类中的静态代码块,类加载的时候就会执行!】// 查看源码: public class Driver extends NonRegisteringDriver implements java.sql.Driver { public Driver() throws SQLException { } // Driver类一旦加载,此静态代码块就会被执行! static { try { // 注册创建的驱动类! DriverManager.registerDriver(new Driver()); } catch (SQLException var1) { throw new RuntimeException("Can't register driver!"); } } }
★ 注册驱动方式二:DriverManager.registerDriver(new Driver()); // 不推荐!!!
注册驱动====>>>registerDriver方法完成!而此处的方法里面有一个new Driver(),它会进入Driver类的静态代码块(2次注册驱动!)不推荐使用! 1. 注册2次! 2. 驱动类Driver(mysql)与注册驱动方法的代码耦合度高,不方便切换其它数据库的驱动类!
★ DriverManager类
在java.sql包下的类!
核心功能:
注册驱动:registerDriver(Driver driver); // 不推荐使用!
获得连接:getConnection(String url,String username,String password);获得连接对象的参数url: String url = "jdbc:mysql://localhost:3306/day30_db"; jdbc:协议 mysql:子协议 localhost: 主机(ip地址) 3306:端口号 day30_db:库名 上面参数url还可以写成:String url = "jdbc:mysql:///day30_db";
★ Connection接口
在java.sql包下的接口!代表一个与数据库连接的对象!
核心功能:
获得执行SQL语句对象:Statment stmt = conn.createStatement();
获得执行SQL语句的预编译对象:PreparedStatement pstmt = conn.prepareStatement(String sql); // 稍后讲解!
操纵与事务相关的方法: // 稍后讲解!
设置事务提交方式:conn.setAutoCommit(boolean autoCommit); // true:自动提交;flase:手动提交
提交事务:conn.commit();
回滚事务:conn.rollback();
设置回滚点:conn.setSavepoint(String name);★ Statment接口
在java.sql包下的接口!用于执行静态SQL语句并返回其生成的结果的对象。
核心功能:
用于执行更新sql语句:int rows = stmt.executeUpdate(String sql); // 对数据库表记录影响的行数!
用于执行查询sql语句:ResultSet rs = stmt.executeQuery(String sql); // 将查询的结果封装到ResultSet对象中!(结果集对象!)★ ResultSet接口
在java.sql包下的接口!表示数据库结果集的数据表,简言之:执行查询语句得到的结果封装到这个对象中去了!
核心功能:
判断结果集中是否有数据: boolean flag = rs.next(); // 有的话就可以获取里面的数据了!
获取数据:
提供了很多的getXxx(Object obj)方法!
// 获得cname的值!
String cname = rs.getString(2); //参数是2,代表cname在数据库里面是第几列(从1开始)。getXxx方法名是根据要获得数据所在列的数据类型决定!
String cname = rs.getString("cname");// 参数cname代表字段名称。getXxx方法名是根据要获得数据所在列的数据类型决定!
5.JDBC的增删改查
JDBCTest类!
6.JDBC的工具类抽取
JDBCUtils
7.ResultSet执行原理
见图解!
8.JDBC的事务处理
模板代码:
Connection conn = JDBCUtils.getConnection();
try{
// 设置手动提交
conn.setAutoCommit(false);
// 编写多个更新操作的代码!【作为一个整体!】
。。。。。。
。。。。。。
// 程序能执行到这里,说明转账操作没有问题,提交事务!
conn.commit();
}catch(Exception e){
// 程序执行到这里,说明转账操作失败,回滚事务!
conn.rollback();
}
代码演示:TestTransaction
9.登录功能
创建数据库表 user
10.SQL注入问题
我们在编写代码的时候,由于SQL拼接(改变SQL语句的结构),导致错误的数据也能够正常的执行程序!
String sql = "select * from user where username='"+username+"' and password='"+password+"'";
如何解决呢?
我们只需要将SQL语句的结构给它固定了!我们可以使用JDBC规范提供的另外一个接口PreparedStatement对象!
11.PreaparedStatement对象改写登录案例
PreaparedStatement它也是一个接口,是Statment的子接口!
它在编写SQL语句的时候,哪些可以变动的值,使用占位符占据!
String sql = "select * from user where username=? and password=?";
然后获得预编译对象PreparedStatement,需要将sql语句作为传输传递进来【预编译对象与sql语句的结构就绑定了】
PreparedStatement pstmt = conn.prepareStatement(sql);
紧接着为sql语句的占位符赋值【参数是什么类型,就set什么类型的方法,方法的第一个参数带表为第几个?赋值,第二个参数就是具体的值】
pstmt.setString(1,username);
pstmt.setString(2,password);
最后执行SQL语句的时候,不要传递sql语句了
ResultSet rs = pstmt.executeQuery();
int rows = pstm.executeUpdate();
12.PreaparedStatement对象执行原理
预编译对象的强大之处:
- 它只编译一次,效率高!PreparedStatement pstmt = conn.prepareStatement(sql);
- 它将SQL语句的结构固定了,能够防止SQL注入问题!
13.PreaparedStatement对象的增删改查
PreparedStatementTest类
14.连接池原理
连接池:主要解决的是频繁创建与数据的连接造成的效率低下问题!
原理:我们需要连接对象,从连接池(容器)中获得,使用完毕,不是将其释放(关闭),而是将其归还到连接池中!
15.DRUID连接池
市面上有很多优秀的外置连接池,比如:德鲁伊、c3p0、dbcp、jndi等等。。。。。
而现在使用居多的是druid(阿里巴巴)!
外置连接池=======>>> 就是一个jar包!druid-1.0.9.jar
如何使用?
导入druid核心jar包!
然后为数据库源(DataSource)提供连接需要的参数! 【所有的连接池都实现了该接口!接口中有一个方法用于获得连接对象 getConnection()】
DataSource它是一个接口,具体的实现由数据库连接池厂商提供实现!