掌握JDBC这一篇文章就够用了

文章介绍了JDBC的本质,即一套由SUN定制的数据库连接接口,强调了面向接口编程的优势。详细阐述了JDBC编程六部曲,并提出了三个改进点:通过IO流读取配置文件,使用PreparedStatement防止SQL注入,以及编写JDBC工具类简化编程。此外,还讨论了事务管理和悲观锁与乐观锁的概念。

目录

1.JDBC的本质

2. JDBC语法(编程六部曲)

改进1:通过IO流获取配置文件信息,进行数据库的连接:

         改进二:使用PreparedStatement解决SQL注入问题:

改进三:编写JDBC的工具类 简化JDBC编程

3.事务

4. 悲观锁or乐观锁:

5.补充:什么是统一资源定位符 URL


1.JDBC的本质:

Java DataBase Connection(java语言连接数据库)

一个由SUN公司定制的,各大数据库厂商负责实现的一套接口;

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

为什么要面向接口编程? 解耦合:降低程序的耦合度,提高程序的扩展力。 多态机制就是非常典型的:面向抽象编程。(不要面向具体编程)

JDBC的出现极大地降低了连接数据库的成本,程序员们通过JDBC进行数据库连接的时候不再需要考虑到各数据库的不同,直接使用相同的语法进行连接操作即可;

JDBC本质上是一套接口;

JDBC接口实现中的各角色及其作用

 

 

2. JDBC语法(编程六部曲)

Connection conn=null;
Statement stmt=null;
Resultset rs=null;
try{
    //第一步 注册驱动 
    DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver()) 
    //----------------------------------------    
    Class.forName(“com.mysql.cj.jdbc.Driver”);
    //第二步:获取数据库连接 通过url user password进行数据的连接
    String url="jdbc:mysql://localhost:3306/wangye"(你需要连接的数据库名);
    String user="root";
    String password="123456";
    conn=DriverManager.getConnection(url,user,password);
    //3.第三步 获取数据库操作对象
    stmt=conn.createStatement();
    //4.执行SQL语句
    String sql="SQL语句"
        //SQL语句不同,执行语句不同    
    int count=stmt.executeUpdate(sql);
    rs=stmt.executeUpdate(sql);
    //5.处理查询结果集(如果第四步为Select,需要使用这一步进行处理)
    while(rs.next( )){
        String xx=rs.getString("");
        String XX=rs.getString(" ");
    }
}catch(SQLException e){
    抛出注册驱动时的异常
    e.printStackTrace();
}finally{
    //6.释放资源 
    //因为JDBC服从于main方法,所以我们在java编写jdbc会自动关闭;
    //但是如果我们在服务器中进行编写的话,就需要主动释放资源了,
    //我们先释放ResultSet、再释放Statement,最后关闭Connection;
    if(rs!=null){
        try{
        rs.close();
    }catch(SQLException e){
        e.printStackTrace();
    }
    if(stmt!=null){
        try{
        stmt.close();
    }catch(SQLException e){
        e.printStackTrace();
    }
    }
    if(conn!=null){
      try{
        conn.close();
    }catch(SQLException e){
        e.printStackTrace();
    }
}

改进一:通过IO流获取配置文件信息,进行数据库的连接:

读取属性配置文件:

在配置文件中直接书写键值对的格式即可;

driver url use password

 

    // 属性资源文件绑定
    private static ResourceBundle bundle = ResourceBundle.getBundle("resources.jdbc");
    // 根据属性配置文件key获取value
    private static String driver = bundle.getString("driver");
    private static String url = bundle.getString("url");
    private static String user = bundle.getString("user");
    private static String password = bundle.getString("password");

改进二:使用PreparedStatement解决SQL注入问题:

SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法

如何解决SQL注入,用户提供的信息,不参与SQL语句的编译即可;

SQL注入过程变现为:先进行字符串的拼接,然后再进行编译;

java.sql.Statement接口的特点:先拼接后编译

  • 优点:使用Statement可以进行sql语句的拼接

  • 缺点:因为拼接的存在,导致SQL注入

java.sql.PrepareStatement接口的特点是先编译后进行是sql语句的传值。

  • 优点:避免的SQL注入

  • 缺点:没有办法进行sql语句的拼接,只能给sql语句传值;

Statement与PrepareStatement并不存在好坏之分,他们两个有各自的应用场景;

一般我们选择PrepareStatement 因为它解决了SQL注入的问题;编译一次执行N次,效率较高;在编译阶段会进行安全检查,会报错;

在需要进行SQL拼接的时候,我们使用Statement,例如进行升序和降序的排列,如果此时使用PreparedStatement,那么我们的SQL语句往往是错误的,带着引号的;

在排序中PrepareStatement预编译的错误示范

使用PreparedStatement,传统的3,4步骤改变

//第三步:获取预编译数据库操作对象
String sql="select account,password from log where account=?and password=?";
ps = conn.prepareStatement(sql);
//记住,JDBC中所有的下标都是从1开始的
ps.setString(1,value);
ps.setString(2,value);
//先进行sql语句的编写,再进行预编译,之后对 占位符 进行传参
//第四步:执行预编译对象,空参
rs=stmt.executeQuery();
  1. 我们先书写sql语句的大致框架,需要进行判断和数据处理的地方用?进行占位

  2. 处理查询结果集 prepareStatement.executeQuery() 无须在括号中填写内容,否则会进行处理SQL语句的覆盖

改进三:编写JDBC的工具类 简化JDBC编程

1.注册驱动 静态代码块 只在类加载的时候加载

2.封装获取连接

3.释放资源

为什么类的方法一般都是静态化的?

构造方法静态化是为了防止new对象,为什么要防止new对象?

因为工具类中的方法都是静态的,不需要new对象,直接使用类名的方式调用,创建工具类就是为了方便使用,能少写代码就少写代码

以下为工具类中的Java代码

package DBunit;
import java.sql.*;
import java.util.ResourceBundle;

public class jdbc {
    private static ResourceBundle bundle = ResourceBundle.getBundle("resource.jdbc");
    private static String driver = bundle.getString("driver");
    private static String url = bundle.getString("url");
    private static String user = bundle.getString("user");
    private static String password = bundle.getString("password");

    //构造方法私有化,防止new对象
    private jdbc() {
    };

    static {
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static Connection connection() throws Exception {
        return DriverManager.getConnection(url, user, password);
    }

    public static void close(Connection conn, Statement ps, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

以下为使用IO流读取配置文件和使用工具类编写的JDBC,代码及其简洁

        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            //1.注册驱动
            //2.获取数据库连接
            conn=connection();
            //3.获取数据库操作对象
            stmt = conn.createStatement();
            //4.编写SQL执行SQL
            String sql ="select * from student";
            rs=stmt.executeQuery(sql);
            //5.处理查询结果集
            while (rs.next()){
                String name=rs.getString("name");
                String age=rs.getString("age");
                System.out.println(name+" "+age);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            //6.释放资源
            close(conn,stmt,rs);
        }

3.事务

JDBC默认事务是自动提交,执行任意一条SQL语句,就会更改数据库中的数据

而我们在实际开发中,通常都是多条DML语句共同联合才算完成,必须保证他们同时成功或者同时失败;

因此,如果我们要想实现事务,就需要关闭默认提交机制。而我们在实际开发中也必须将自动提交机制关闭掉,改成手动提交,当一个完整的事务结束之后,再提交;

修改自动提交的方法:

开启事务:Connecton.setAutoCommit(false);

提交事务:Connecton.commit();

回滚事务:Connection.rollback();写到catch{}中,表示遇到异常就进行回滚;

4. 悲观锁or乐观锁:

本质上就是sql语法,在select语句后面加上for update;

表示所查询的数据被锁住了,在当前事务还没结束的时候,不能对已经锁定的行进行操作;

乐观锁:多线程,都可以进行修改,但是有版本号记录,可以进行回滚;

5.补充:什么是统一资源定位符 URL

URL是用表示资源所在的唯一位置

组成:通信协议+IP地址+端口号port+资源名

其中:通信协议包含很多,不仅仅是http,https,还包括一些数据库连接规范,是一系列数据交互的协议

IP地址,用来定位某台计算机,相当于服务器/计算机的身份证

端口号:用来标识服务器上该服务所在位置

资源名:资源的唯一位置

如果我们连接的是orcle数据库的话:

oracle:jdbc:thin:@localhost:1521:bjpowernode oracle:jdbc:thin:@ 这是oracle和java的通信协议

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值