JDBC.

0. 相关知识

在一个接口或类中获取下一个接口或类的对象

0.0 jar包是什么?

别人写好的一些类,然后对这些类进行了打包就形成了:jar包。你可以将这些jar包导入你的项目中,然后就可以直接使用这些jar包中的类和属性以及方法。

0.1 统一资源定位符URL

url统一资源定位符:网络中某个资源的绝对路径

例子:https://www.baidu.com/ 这就是URL。

URL包括哪几部分?

  • 协议
  • IP地址
  • PORT
  • 资源名
		http://182.61.200.7:80/index.html
			http:// 通信协议
			182.61.200.7 服务器IP地址
			80 服务器上软件的端口号
			index.html 是服务器上某个资源名
------------------------------------------------------------------
		MySQL数据库的URL格式:jdbc:mysql://hostname:port/database
		oracle的URL格式:jdbc:oracle:thin:@localhost:1521:orcl
		
		jdbc:mysql://127.0.0.1:3306/bjpowernode
			jdbc:mysql:// 协议
			127.0.0.1 IP地址
			3306 mysql数据库端口号
			bjpowernode 具体的数据库名。
		
		说明:localhost和127.0.0.1都是本机的IP地址。

		jdbc:mysql://192.168.151.27:3306/bjpowernode
		
		什么是通信协议,有什么用?
			通信协议是通信之前就提前定好的数据传送格式。
			数据包具体怎么传数据,格式提前定好的。

0.2 数据源

  • 数据源其实是一套规范,JDK中也有这套规范,就是:javax.sql.DataSource,只要实现了javax.sql.DataSource接口的都是数据源

  • datasource数据源:为程序提供数据库连接对象Connection的都叫数据源

  • 数据库连接池提供了数据库连接对象Connection,所以数据库连接池也是数据源

  • 德鲁伊连接池,C3p0连接池,dbcp连接池都实现了DataSource接口

  • 自己编写一个数据源

    • 在数据源里面要定义连接数据库信息的4个变量,并提供这四个属性的set方法

package com.powernode.spring6.jdbc;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

/**
 * @author 动力节点
 * @version 1.0
 * @className MyDataSource
 * @since 1.0
 **/
public class MyDataSource implements DataSource {
    // 添加4个属性
    private String driver;
    private String url;
    private String username;
    private String password;

    // 提供4个setter方法
    public void setDriver(String driver) {
        this.driver = driver;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    // 重点写怎么获取Connection对象就行。其他方法不用管。
    @Override
    public Connection getConnection() throws SQLException {
        try {
            Class.forName(driver);
            Connection conn = DriverManager.getConnection(url, username, password);
            return conn;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
}

1. JDBC概述

1、Java DataBase Connectivity(Java数据库连接)

JDBC是sun公司提供的一套 用于数据库操作的接口,java程序员面向这套接口编程即可。

不同的数据库厂商 对这套接口 提供了不同实现。不同的实现的集合,即为不同数据库的驱动。 ————面向接口编程

2、JDBC的本质:sun公司提供的一套 用于数据库操作的接口,然后各大数据库厂商分别实现这套接口(interface) java.sql.*; (这个软件包下有很多接口。)

MySQL驱动:其实就是MySQL厂商对JDBC的实现,用于操作MySQL数据库的

接口都有调用者和实现者。
面向接口调用、面向接口写实现类,这都属于面向接口编程。

为什么要面向接口编程(面向抽象编程)?
	解耦合:降低程序的耦合度,提高程序的扩展能力。
	多态机制就是非常典型的:面向抽象编程。(不要面向具体编程)
		建议:
			Animal a = new Cat();
			Animal a = new Dog();
			// 喂养的方法
			public void feed(Animal a){ // 面向父类型编程。
			
			}
		不建议:
			Dog d = new Dog();
			Cat c = new Cat();

思考:为什么SUN制定一套JDBC接口呢?
	因为每一个数据库的底层实现原理都不一样。
	Oracle数据库有自己的原理。
	MySQL数据库也有自己的原理。
	MS SqlServer数据库也有自己的原理。
	....
	每一个数据库产品都有自己独特的实现原理。

JDBC的本质到底是什么?
	一套接口。

2. JDBC开发前的准备工作:先从官网下载对应的jar包驱动,然后将其配置到环境变量classpath当中。

2.1 文本编辑器的方式

以下配置是针对于文本编辑器的方式开发,使用IDEA工具的时候,不需要配置以下的环境变量。

classpath=.;D:\course\06-JDBC\resources\MySql Connector Java 5.1.23\mysql-connector-java-5.1.23-bin.jar

2.1 idea的配置方式

①在模块上右键,然后选择Open Modeul Settings

②然后进入到此界面,进行如下操作

然后找到要导入的jar驱动包,再选择jar包要导入哪些模块中

3. JDBC编程六步(1)

第一步:调用DriverManager接口中的registerDriver静态方法注册指定的驱动程序(或是通过反射机制注册指定的驱动程序)(作用:告诉Java程序,要连接哪个品牌的数据库)

第二步:调用DriverManager接口中的getConnection静态方法:获取数据库连接对象Connection(让java连接数据库)

第三步:通过Connection对象调用Connection接口中的方法:获取数据库操作对象Statement或preparedStatement(专门执行sql语句的对象)

第四步:通过数据库操作对象调用其中的方法执行SQL语句(DQL DML....)

第五步:(处理)打印查询结果集(只有第四步执行select语句时,才需处理查询结果集。)

第六步:关闭连接,释放资源(使用完资源之后一定要关闭资源。Java和数据库属于进程间的通信,开启之后一定要关闭。)

3.JDBC编程六步(2)

第一步:注册指定的JDBC驱动程序(有三种方法)

方法一:
Driver driver = new com.mysql.jdbc.Driver(); //先实例化mysql的驱动
DriverManager.registerDriver(driver);      //向 DriverManager接口注册指定的JDBC驱动程序

方法二:
//调用DriverManager接口中的registerDriver静态方法注册指定的JDBC驱动程序
 DriverManager.registerDriver(new com.mysql.jdbc.Driver());

方法三:
Class.forName("com.mysql.jdbc.Driver");   //通过Java反射机制注册指定的JDBC驱动程序

第二步:调用DriverManager接口中的getConnection静态方法获取数据库连接对象Connection

String url = "jdbc:mysql://localhost:3306/bjpowernode";
String user = "root";
String pwd = "123456";
connection = DriverManager.getConnection(url,user,pwd);

第三步:通过Connection对象调用Connection接口中的方法获取数据库操作对象Statement(它专门执行sql语句的对象)

statement = connection.createStatement();  //方法一:获取用于执行静态SQL语句的数据库操作对象
preparedStatement = connection.prepareStatement(sql);  //方法二:先获取预编译的数据库操作对象,sql语句已预先编译好了

第四步:通过数据库操作对象 调用 Statement接口或PreparedStatement接口中的方法:执行SQL语句(有多种方法)(如果是使用PreparedStatement对象,则需要调用设置占位符的方法给占位符设置值)

第五步:打印查询结果集(处理查询结果集,将里面的数据取出来)(只有第四步执行select语句的时候,才有这第五步处理查询结果集。)

while (resultSet.next()){
	String empno = resultSet.getString("empno");
    String enmae = resultSet.getString("ename");
    int salary = resultSet.getInt("sal");
    System.out.println(empno + "," + enmae +"," + salary);
}

第六步:关闭连接,释放资源(使用完资源之后一定要关闭资源。Java和数据库属于进程间的通信,开启之后一定要关闭。)

3. JDBC 编程六步(3)

//第一步:通过DriverManager接口中的 static void registerDriver(Driver driver) 静态方法注册指定的JDBC驱动程序
		DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 

//第二步:通过riverManager接口中的 static Connection getConnection(String url,String user,String pwd) 静态方法获取数据库连接对象
        connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","123456");

//第三步:Connection接口中的方法获取数据库操作对象
        statement = conn.createStatement();

//第四步:调用Statement对象中的方法执行SQL语句
            String sql = "insert into dept(DEPTNO,DNAME,LOC) values(50,'人事部','北京')";
            int count = statement.executeUpdate(sql);
//第五步:

//第六步:释放资源:释放资源时,后开的资源先关闭
            if (statement != null){        //习惯:如果不为空,才关闭
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                try {
                    if(conn != null){
                        conn.close();
                    }
                }catch (SQLException e){
                    e.printStackTrace();
                }

4、实现JDBC程序

案例1:用JDBC向数据表中添加数据

package jdbctest1;

import java.sql.*;

public class JDBCTest1 {
    public static void main(String[] args) {
        Statement statement = null;
        Connection conn = null;
        try {
            Driver driver = new com.mysql.jdbc.Driver(); //实例化mysql的驱动
            //oracle的驱动: Driver driver = new oracle.jdbc.driver.OracleDriver();

            //      1、DriverManager接口注册驱动
            DriverManager.registerDriver(driver);      //向 DriverManager注册指定的JDBC驱动程序

            //      2、DriverManager接口获取数据库连接对象
            String url = "jdbc:mysql://127.0.0.1:3306/bjpowernode";
            String user = "root";
            String pwd = "123456";
            conn = DriverManager.getConnection(url,user,pwd); //获取数据库连接对象Connection
            System.out.println("数据库连接对象为:"+conn);

            //     3、Connection接口获取数据库操作对象
            statement = conn.createStatement();
            
            //     4、使用Statement对象执行SQL语句
            String sql = "insert into dept(DEPTNO,DNAME,LOC) values(50,'人事部','北京')";
            int count = statement.executeUpdate(sql);
            if (count == 1){
                System.out.println("修改成功");
            }else {
                System.out.println("修改失败");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //6、   释放资源:释放资源时,后开的资源先关闭
            if (statement != null){        //习惯:如果不为空,才关闭
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                try {
                    if(conn != null){
                        conn.close();
                    }
                }catch (SQLException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

案例2:用JDBC删除表中的数据行

package jdbctest1;

import com.mysql.jdbc.Driver;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCTest2 {                                //执行DML的 delete form 表名 命令
    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;

        try {

            //      1、用DriverManager接口中的registerDriver方法注册指定的JDBC驱动程序
            DriverManager.registerDriver(new com.mysql.jdbc.Driver()); //向 DriverManager注册指定的JDBC驱动程序
            Class.forName("com.mysql.jdbc.Driver");        //通过反射机制注册数据库驱动
            
            //      2、调用DriverManager接口中的getConnection静态方法获取数据库连接对象
            String url = "jdbc:mysql://localhost:3306/bjpowernode";
            String user = "root";
            String pwd = "123456";
            connection = DriverManager.getConnection(url,user,pwd);
            
            //     3、调用Connection接口中的方法获取数据库操作对象
            statement = connection.createStatement();
            
            //     4、调用Statement接口中的方法执行SQL语句
            String sql = "delete from dept where deptno = 50";
            int count = statement.executeUpdate(sql);
            if (count == 1){
                System.out.println("执行成功");
            }else if (count == 0){
                System.out.println("执行失败");
            }

        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            
            //6、释放资源:释放资源时,后开的资源先关闭
            try {
                if (statement != null){
                    statement.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }

            try {
                if (connection != null) {
                    connection.close();
                }
            }catch(SQLException e){
                   e.printStackTrace();
                }


        }

    }
}

案例3:使用java连接数据库查询数据表中的数据

package jdbctest1;

import java.sql.*;

public class JDBCTest3 {
    public static void main(String[] args) throws ClassNotFoundException {
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;

        try {
            //1.注册数据库驱动
            Class.forName("com.mysql.jdbc.Driver");

            //2.获取数据库连接对象,表示和数据库创建了连接
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","123456");

            //3.获取数据库操作对象
            statement = connection.createStatement();

            //4.执行SQL语句
            String sql = "select * from emp";
            resultSet = statement.executeQuery(sql);

            //5.处理查询结果集
            while (resultSet.next()){
                String empno = resultSet.getString("empno");
                String enmae = resultSet.getString("ename");
                int salary = resultSet.getInt("sal");
                System.out.println(empno + "," + enmae +"," + salary);
            }

        }catch (SQLException e) {

            e.printStackTrace();
            
        }finally {
            //6.在finally代码块中关闭资源
            if (resultSet != null){
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if (statement != null){
                try {
                    statement.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }

            if (connection != null){
                try {
                    connection.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }

        }
    }
}

案例4:PreparedStatement完成增删改

5、JDBC中常用的接口及其常用方法

注册,连接,获取操作对象,执行,处理查询结果集,关闭资源

JDBC的接口主要在java.sql包中

1、Driver接口:所有JDBC驱动程序必须实现的接口,这个接口是提供给数据库厂商使用的,不同数据库厂商提供不同的实现。

MySQL的Driver接口的实现类是:com.mysql.jdbc.Driver(全类名)

2、DriverManager接口(有两个重要的静态方法):管理JDBC驱动程序的

主要方法:可以用于注册JDBC驱动程序和获取数据库连接对象Connection

                                                DriverManager接口常用方法

方法名功能
static void registerDriver(Driver driver)注册指定的JDBC驱动程序,接收一个数据库驱动实例
static Connection getConnection(String url,String user,String pwd)获取数据库连接对象Connection,表示和数据库创建了连接(建立和数据库的连接)

3、Connection接口:用于建立和数据库的连接,一个连接就是一个会话,建立连接后可以执行SQL语句

主要方法:建立连接后就可以获取数据库操作对象(Statement或PreparedStatement)(专门执行sql语句的对象)

                                                Connction接口常用方法

方法名
Statement createStatement()获取数据库操作对象Statement(这个对象用于执行静态SQL语句),将SQL语句发送到数据库
PrepareStatement prepareStatement(String sql)参数化的SQL语句发到数据库,获取一个预编译的数据库操作对象PrepareStatement

4、Statement接口:执行静态的SQL语句,并返回一个结果对象。

                                                       Statement接口中的方法

方法名功能
boolean execute(String sql)能够执行所有的SQL语句,如果执行的SQL有查询结果,则返回true,否则返回false。通过getStatementSet()可以获得查询结果
int executeUpdate(String sql)用于执行 修改数据表中数据的 SQL语句(INSERT,DELETE,UPDATE),返回的int值代表受影响的行数
ResultSet executeQuery(String)执行SQL中的查询语句(如select),返回一个存储 查询结果集 的ResultSet对象

5、PreparedStatement接口: Statement的子接口执行预编译的SQL语句

  • 这个接口的SQL语句中的具体值可以用 ?来代替,然后通过其提供的setter()方法为 ?传值

                                                PreparedStatement接口中的方法

方法名功能
int executeUpdate()在PreparedStatement对象中执行SQL语句,如DML、DDL,返回的int值代表受影响的行数
ResultSet executeQuery()在PreparedStatement对象中执行SQL的select语句,返回一个存储查询结果集 的ResultSet对象
void setInt(int parameterIndex,int x)将指定索引处的参数(占位符)  设置为  int类型x
void setString(int parameterIndex,String x)将指定索引处的参数(占位符)  设置为  字符串类型x

6、ResultSet接口:用来存储JDBC的查询结果集,通过结果集对象中的方法完成对数据库的访问。

(①这个查询结果集封装在一个表格中②ResultSet接口中有一个游标,当ResultSet对象初始化时游标会指向表格的第一行之前。)

                                                        Result接口常用的方法

方法名功能描述
String getString(int columnIndex)获取 游标所在行的String类型的值,根据字段的索引来获取
String getString(String columnName)获取 游标所在行的String类型的值,根据列名来获取
int getInt(int columnIndex)根据 字段索引 获取 游标所在行中int类型的值
int getInt(String columnName)根据 字段名 获取 游标所在行的int类型值
boolean next()将游标向下移动一行,从当前位置,如果没有数据了则返回false

JDBC中的所有下标从1开始,不是从0

7、CallableStatement接口:用于执行SQL的存储过程。

数据库中特殊的数据类型:

8、Data类:标准的Date的一个子集,用于表示数据库中的日期类型,用于表示日期类型(不包含时间)

  • java.util.Date如何转化为java.sql.Date类型

    • 先把日期字符串转化为java.util.Date类型

    • 再把java.util.Date类型转化为java.sql.Date类型

9、TimeStamp类:标准的Date的一个扩展,用于表示sql中的时间戳,增加了一个关于纳秒的时间域

14、Time:标准的Date的一个子集,用于表示数据库的时间类型,用于表示时分秒(不包含其他的)

10、DatabaseMetaData:跟ResultSetMetaData一起访问数据库的元信息

11、DataTruncation:出现数据库异常时,报告异常或警告

12、SQLException:数据库异常

13、SQLWarming:数据库警告

14、DriverPrepertyInfo:驱动属性的所有信息

15、Types: 常量

6、SQL注入

  • 导致SQL注入的根本原因:

    • 用户输入的信息中含有sql语句的关键字,并且sql语句的关键字参与了sql语句的编译过程,导致sql语句的原意被扭曲,进而达到sql注入。

  • 如何解决SQL注入

    • 只要用户输入的信息不参与SQL语句的编译过程问题就解决了

    • 要想使用户输入的信息不参与SQL语句的编译,那么必须使用java.sql.PreparedStatement接口,它继承了java.sql.Statement接口

    • PreparedStatement属于预编译的数据库操作对象

8.Statement和PreparedStatement的对比

  • Statement的原理是:先拼接SQL语句,然后再编译SQL语句

  • PreparedStatement的原理是:预先编译SQL语句,然后再给SQL语句传“值”。

  • Statement和PreparedStatement的对比

    • 1、Statement存在SQL注入问题,而PreparedStatement解决了SQL注入

    • 2、Statement编译一次执行一次,PreparedStatement是编译一次,可执行多次(效率较高)

    • 3、PreparedStatement在编译阶段做类型的安全检查

9.JDBC工具类封装

除了操作数据库的内容,其他都是重复的

一般工具类中的构造方法都是私有的,因为工具类中的方法都是静态的,不需要创建对象来使用,直接用类名调用即可

package utils;

import java.sql.*;

/**
 * JDBC工具类,封装JDBC代码,简化JDBC编程
 */
public class DBUtil {
    private DBUtil(){

    }

    //注册驱动只需要注册一次就可以,所以把它放到静态代码块中
    //静态代码块在类加载的时候执行,且只执行一次
    static {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取数据库连接对象
     * @return
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
            Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/bjpowernode","root","123456");
            return connection;
    }

    /**
     * 关闭数据库连接资源
     * @param connection 数据库连接对象
     * @param statement 数据库操作对象
     * @param resultSet 查询结果集对象
     */
    public static void close(Connection connection, Statement statement, ResultSet resultSet){
        if(resultSet != null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(statement != null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(connection != null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

}

  • 26
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值