JDBC 原理(不建议看,本人自己也看不懂)
- jdbc 是一套标准,本质上就是一堆接口
- 每个数据库厂商提供了jdbc接口的实现类,并且在jar包里,只要把jar包导入工程就可以操作数据库了。
概述
什么是jdbc
- jdbc 是简称,全称 Java Database Connectivity :java数据库连接。专门用来通过一段 Java 代码操作数据库的一门技术
如何使用jdbc
需求:
- 通过 jdbc 技术,查询 account 表中的所有数据
开发步骤
- 注册驱动
- 获取数据库连接
- 获取传输器
- 执行 SQL
- 遍历结果集
- 释放资源
1.注册驱动
语法: DriverManager.registerDriver(new Driver());
缺点
- 驱动名和程序产生了紧耦合的关系
com.mysql.idbc.Driver.Driver() throws SQLException
- 使得驱动器被注册两次
解决方案
Class.forName("com.mysql.jdbc.Driver");
2.数据库连接对象 Connection
- 作用:通过三个数据库的连接参数,连接到数据库进行数据库的管理。
Connection conn = JDBCUtils.getConnection();
3.传输器对象 Statement
常用方法:
- createStatement() ---- 获取传输器对象
- prepareStatement() — 获取带有预编译效果的传输器对象
Statement st = conn.createStatement();
PrepareStatement ps = coon.prepareStatement();
4.执行SQL语句
- 作用:用来执行 SQL 语句
- 常用方法:
- ExecuteQuery(sql语句) — 执行查询的 SQL 语句
- executeUpdate(sql语句) — 执行增删改的 SQL 语句
5.结果集对象 ResultSet
- 作用:用来封装 SQL 执行完的数据
- 常用方法:
- Next() 查询结果集中是否有数据,指针的效果
- getString(String column) 根据指定列名获取数据
- getString(int index) 根据列的索引获取数据
- getInt(String column) 根据指定列名获取数据
- getInt(int index) 根据列的索引获取数据
- getLong(String column) 根据指定列名获取数据
- getLong(int index) 根据列的索引获取数据
6.关闭资源
- 作用:在 jdbc 开发中,资源是十分稀缺的,需要我们每次使用完之后必须释放资源。当我们在释放资源时,有可能会发生异常,为了保证资源释放一定会被执行,需要把释放资源的代码放入 finally 中
- 使用:释放资源,正着开,倒着关
finally{
JDBCUtils.close(null,st,conn);
}
JDBCUtils 工具类
1.需求:
在 jdbc 的开发中,存在大量重复的代码,将这些代码提取出来,封装起来,提高代码的复用性,简化开发。
2.开发步骤
- 私有化构造函数
- 提供静态方法 getConnection,用来对外提供数据库连接对象
- 提供静态方法close,用来释放资源
配置文件开发形式
1.需求
让程序中写死的可以配置的参数,提取到属性文件中
格式:key=value,如果想要获取value,可以通过get(key)
2.创建属性文件 (位置在src下,名称 XX.properties)
PreparedStatement 对象
1.需求
模拟用户登录过程,查询用户表。
2.开发步骤
- 创建 web 工程
- 创建 LoginUser 类
- 创建 main 方法,用来提示用户登录的信息
- 创建 login 方法,取数据库查询信息
- 测试
3.sql注入攻击
- 当用户名输入的值为 chenzs’# 或者 chenzs’ or ’ 1=1, 我们只需要输入用户名,不需要输入密码就可以访问系统
- 本质上时因为 SQL 语句中包含了
SQL 关键字 # or 1=1
, 造成了系统的安全漏洞。
优势:
4. 防止SQL注入攻击:
- 就是把输入的所有值,当做普通一个串串来处理
//3.获取传输器
String sql = "select * from where username=? and password=?";
ps = conn.prepareStatement(sql);
//设置参数
ps.setString(1,name);
ps.setString(2,pwd);
//4.执行SQL
rs = ps.executeQuery();
5.省略参数拼接的过程
- 把参数用一个问号来代替,?叫做占位符
- 把带有问好?的 SQL (SQL骨架) 先发给服务器,服务器先编译。
- 设置参数的时候, setString(index, value); index 的值必须要和问号?出现的顺序保持一致。
- ps.executeQuery();使用这个无参的方法
6.提高程序的访问效率
- 首先服务器收到了 SQL 骨架,并缓存起来。当下次要查询相同 SQL 骨架时,直接取缓存中取,而不用操作数据库了。
批处理
什么是批处理
- 当需要向数据库中插入大量数据时才用
- 在没有使用批处理之前,100条记录,需要打开数据库连接和关闭数据库连接100次。
- 批处理可以将一部分 SQL 打成一个批次 addBatch(),统一发送给数据库服务器 excuteBatch(), 当服务器收到 SQL 之后,依次打开批,执行批里面的 SQL。
实现
- 方式1:Statement 对象
- 方式2:PrepareStatement 对象
- 把SQL打成一个批次:at.addBatch(sql);
- 统一发送给数据库服务器:st.executeBatch();
事务优化
- jdbc 默认是开启事务管理的。1000条 SQL 就需要开启事务1000次,SQL 执行完成后,需要提交事务1000次。
- 关闭 jdbc 自动管理事务:conn.setAutoCommit(false);
- 手动提交事务:conn.commit();
区别
1.Statement
- 优点:再一次批处理中,SQL的表现形式灵活
- 缺点:不能防止 SQL 注入,执行效率低
2.PreparedStatement
- 优点:防止 SQL 注入(把所有的参数值都当作一个普通的字符串来处理的),效率高(将 SQL 骨架先发服务器)
- 缺点:完成一次批处理的过程中,SQL 表现不灵活(先定义的 SQL 骨架是不变的)
连接池
- 连接池:在程序中,存在一个容器,可用的代表了数据库连接的对象,在整个程序中共享
- 实现数据库的复用,减少数据库连接的开、关次数
- 实现:
- 定义 一个类 实现 DataSource 接口
- 创建容器,用来存放数据库连接对象
- 初始化容器
- 提供 getConnection(), 对外提供数据库连接
- 提供自定义 retrunConnection() 方法, 还回池里