黑马程序员技术交流社区

标题: [石家庄校区]JDBC [打印本页]

作者: Black_Y    时间: 2018-5-21 15:12
标题: [石家庄校区]JDBC
本帖最后由 小石姐姐 于 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));
    }


```




















欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2