本帖最后由 小石姐姐 于 2018-5-23 14:44 编辑
JDBC
#JDBC
JABC(Java Data Base Connectivity,java数据库连接)
数据库驱动
驱动:两个设备(应用)之间通信的桥梁.
```java
环境准备:
1.创建数据库和表
2.创建项目,引入jar包
```
##DriverManager驱动管理类
####作用一:注册驱动
方法:registerDriver(Driver driver) 注册驱动,实际开发中一般不会使用这个方法完成驱动的注册
原因:源代码中有一段静态代码块已经调用了注册驱动的方法.如果再手动调用该方法注册驱动,就会导致驱动被注册两次.
实际开发中一般会采用
```
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
```
####作用二:获得连接
方法: getConnection(String url,String user,String password)
这个方法用来获得与数据库连接的方法:有三个参数
**url :与数据库连接的路径(重点)**
user :与数据库连接的用户名
password :与数据库连接的密码
```
jdbc:mysql://localhost:3306/web_test3
```
jdbc :连接数据库的协议
mysql :jdbc的子协议
localhost :连接的MySQL数据库服务器的主机地址.(连接本机可以写成localhost),如果连接不是本机的,就需要协商连接主机的IP地址.
3306 :MySQL数据库服务器的端口号
web_test3 :数据库名称
url如果连接的是本机的路径,可以简化为:
```
jdbc:mysql:///web_test3
```
##Connection:与数据库连接对象
#### 作用一:创建执行SQL语句的对象
执行SQL语句对象:
Statement :执行SQL
CallableStatement :执行数据库中存储过程
**PreparedStatement :执行SQL对SQL进行预处理,解决SQL注入漏洞(重点)**
####作用二:管理事务
##Statement:执行SQL
####作用一: 执行SQL
方法:
boolean execute(String sql);//执行SQL语句
ResultSet executeQuery(String sql);//执行查询的SQL语句
int executeUpdate(String sql);//执行添加,修改,删除的SQL语句
##ResultSet:结果集
通过select语句的查询结果
```
结果集的遍历:next()方法
while(rs.next()){
}
```
```
结果集的获取
getXXX(...)
```
##资源的释放
JDBC程序执行结束后,将与数据库进行交互的对象释放掉,通常是ResultSet,Statement,Connection.
这几个对象中尤其是Connection对象是非常稀有的.这个对象一定要做到尽量晚创建,尽量早释放.
所以:
###JDBC的开发步骤
```java
第一步:加载驱动(抽取工具类)
第二步:获得连接(抽取工具类)
第三步:基本操作
第四步:释放资源(抽取工具类)
Class.forName("com.mysql.jdbc.Driver");//注册驱动
conn=DriverManager.getConnection("jdvc:mysql:///web_test3","root","abc");//获得连接
//创建可执行sql语句的对象
//编写sql语句
//执行sql语句
//
```
###开发原则
```java
对扩展是开放的
对修改源码是关闭的
```
###配置文件(prepares)
属性文件:
格式:扩展名是properties
内容:key=value
XML文件
###提取信息到配置文件
```java
定义一个配置文件
1driverClassName=com.mysql.jdbc.Driver
2url=jdvd:mysql:///web_test3
3username=root
4password=adc
```
### 在工具类中解析配置文件 ###
```java
工具类
static{
//获取属性文件中的内容:
Properties.load(new FileInputStream("src/db.properties"));
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
driverClassName=properties.getProperty("driverClassName");
url=properties.getProperty("url");
username=properties.getProperty("username");
password=properties.getProperty("password");
}
```
##Statement的漏洞
第一种: "aaa"改为"aaa' or '1=1"
第二种: "aaa"改为"aaa' -- "
原因:在变量中存在SQL中的关键字or,--
##
SQL注入漏洞解决
需要采用PreparedStatement对象解决漏洞.这个对象将SQL预先进行编译,使用?作为占位符. ? 所代表内容是SQL所固定.再次传入变量(包含SQL关键字).这个时候也不会识别这些关键字.
步骤分析:
1.获得连接.
2.编写SQL语句
3.预编译SQL
4.设置参数
5.执行SQL语句
6.释放资源
```
package web_test001;
import java.sql.Connection;
import java.sql.PreparedStatement;
import org.junit.Test;
public class Demo8 {
@Test
public void demo8(){
Connection conn=null;
PreparedStatement pstmt=null;
try {
//1.获得连接
conn=JDBCUtils.getConnection();
//2.编写语句
String sql="update user set id=? where username=?";
//3.预编译语句
pstmt=conn.prepareStatement(sql);
//4.设置参数
pstmt.setInt(1, 5);
pstmt.setString(2,"eee");
//5.执行语句
int num =pstmt.executeUpdate();
if (num>0) {
System.out.println("修改成功");
}else{
System.out.println("修改失败");
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
//6.释放资源
JDBCUtils.release(pstmt, conn);
}
}
}
```
##批处理(使用PreparedStatement)
####作用二: 执行批处理
addBatch(String sql)//添加到批处理
clearBatch()//清空批处理
executeBatch()//执行批处理
```
@Test
/**
* 批量插入记录:
* * 默认情况下MySQL批处理没有开启的,需要在url后面拼接一个参数即可。
*/
public void demo2(){
// 记录开始时间:
long begin = System.currentTimeMillis();
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写SQL语句:
String sql = "insert into user values (null,?)";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
for(int i=1;i<=10000;i++){
pstmt.setString(1, "name"+i);
// 添加到批处理
pstmt.addBatch();
// 注意问题:
// 执行批处理
if(i % 1000 == 0){
// 执行批处理:
pstmt.executeBatch();
// 清空批处理:
pstmt.clearBatch();
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(pstmt, conn);
}
long end = System.currentTimeMillis();
System.out.println((end-begin));
}
```
|
|