JDBC(JAVA数据库连接)

1. 概述

JDBC(Java Data Base Connectivity):简单说,就是使用 Java 语言操作数据库。

JDBC是一套标准,它是由一些接口与类组成的。

学习中涉及到的类与接口,主要在两个包下:

  • java.sql

      • DriverManger

    • 接口

      • Connection

      • Statement

      • ResultSet

      • PreparedStatement

  • javax.sql

    • 接口

      • DataSource

2. JDBC入门

  • 创建初始表及数据

    create table user(
       id int primary key auto_increment,
       username varchar(20) unique not null,
       password varchar(20) not null,
       email varchar(40) not null
    );
    
    INSERT INTO user VALUES(NULL,'tom','123','tom@163.com');
    INSERT INTO user VALUES(NULL,'fox','123','fox@163.com');
  • 创建一个普通类,在类中创建JDBC连接并进行数据库操作

    import com.mysql.cj.jdbc.Driver;
    
    import java.sql.*;
    
    public class Test02 {
        public static void main(String[] args) throws SQLException {
            DriverManager.registerDriver(new Driver());
            Connection connection = DriverManager.getConnection("jdbc:mysql://ip-address:3306/codingfuture", "root", "root");
            Statement statement = connection.createStatement();
            String selectSql = "select * from user";
            ResultSet resultSet = statement.executeQuery(selectSql);
            while (resultSet.next()) {
                String username = resultSet.getString("username");
                String password = resultSet.getString("password");
                String email = resultSet.getString("email");
                System.out.println(username + "\t" + password + "\t" + email);
            }
            resultSet.close();
            statement.close();
            connection.close();
        }
    }

    3. JDBC操作详解

  • DriverManager

    • 注册驱动

      DriverManager.registerDriver(new Driver());

      DriverManager是java.sql包下的一个驱动管理的工具类,可以理解成是一个容器(Vector),可以装入很多数据库驱动。

      上述代码存在一点问题,会在驱动管理器中会装入两个mysql驱动,因为在com.mysql.jdbc.Driver类中有一段静态代码块:

      static {
          try {
              DriverManager.registerDriver(new Driver());
          } catch (SQLException var1) {
              throw new RuntimeException("Can't register driver!");
          }
      }

      解决方案是使用反射来加载该类,在Class.forName加载完驱动类,开始执行静态初始化代码时,会自动新建一个Driver的对象,并调用DriverManager.registerDriver(new Driver())把自己注册到DriverManager中去。

      使用反射的方式来加载驱动,使得com.mysql.jdbc.Driver只加载一次,装入一个驱动对象,并且可以降低耦合,不依赖于驱动。

      Class.forName("com.mysql.cj.jdbc.Driver");
    • 在java 6中,引入了service provider的概念,即可以在配置文件中配置service(可能是一个interface或者abstract class)的provider(即service的实现类)。配置路径是:/META-INF/services/下面。

      而java.sql.DriverManager也添加了对此的支持,因此,在JDK6中,DriverManager的查找Driver的范围为:

      因此,在jdk6中,其实是可以不用调用Class.forName来加载mysql驱动的,因为mysql的驱动程序jar包中已经包含了java.sql.Driver配置文件,并在文件中添加了com.mysql.cj.jdbc.Driver。但在JDK6之前版本,还是要调用这个方法。

      1. system property "jdbc.drivers" 中配置的Driver值;

      2. 用户调用Class.forName()注册的Driver

      3. service provider配置文件java.sql.Driver中配置的Driver值。

    • 通过DriverManager来获取连接对象

      Connection connection = DriverManager.getConnection(String url, String username, String password);

    • url的作用是用于确定使用哪一个驱动

      url格式

      localhost:3306为默认值,因此该url可省略为jdbc:mysql:///mysql1

      url后面可以带参数,比如:jdbc:mysql:///mydb1?useUnicode=true&characterEncoding=UTF-8

      • mysql:jdbc:mysql://localhost:3306/数据库名

      • oracle:jdbc:oracle:thin:@localhost:1521:sid

      • 主协议:子协议://主机:端口/数据库

      • jdbc:mysql://localhost:3306/mydb1

    • Connection

      java.sql.Connection代表的是程序与数据库之间的连接对象。

      Connection作用:

      • 可以通过Connection获取操作sql的Statement对象

        Statement statement = connection.createStatement();
      • 可以获取执行预处理的PreparedStatement对象。

        PreparedStatement ps = connection.prepareStatement(sql);
        
      • 操作事务

        connection.setAutoCommit(boolean flag); // 开启事务
        connection.rollback(); // 事务回滚
        connection.commit(); // 事务提交

Statement

java.sql.Statement用于执行sql语句。

Statement作用:

  1. 执行sql

    • int executeUpdate(String sql)

      执行DML(增删改),返回值代表更新条数,利用返回值判断非0来确定sql语句是否执行成功。

    • ResultSet executeQuery(String sql)

      执行DQL(查询),返回结果集。

    • execute(String sql)

      用于向数据库发送任意sql语句

  2. 批处理操作

    addBatch(String sql); // 将sql语句添加到批处理
    executeBatch(); // 批量执行
    clearBatch(); // 清空批处理

    PreparedStatement

    sql注入:由于没有对用户输入进行充分检查,而SQL又是拼接而成,在用户输入参数时,在参数中添加一些SQL关键字,达到改变SQL运行结果的目的,完成恶意攻击。

  3. 示例:

    在输入用户名时 tom' or '1'='1

    这时就不会验证密码了。

  4. 解决方案:

    PreparedStatement

    它是一个预处理的Statement,它是java.sql.Statement接口的一个子接口。

  5. PreparedStatement使用:

    1. 在sql语句中,使用"?"占位

String sql="select * from user where username=? and password=?";

             2.得到PreparedStatement对象

PreparedStatement ps = con.prepareStatement(String sql);

            3.对占位符赋值

ps.setXxx(int index, Xxx obj);

            4. 执行sql

                DML:ps.executeUpdate()

                DQL:ps.executeQuery()

  • ResultSet
    • java.sql.ResultSet它是用于封装select语句执行后查询的结果。

      常用API:

    • getXxx()

      常用:

      • getInt()

      • getString()

      • getDate()

      • getDouble()

      参数有两种

      • getInt(int columnIndex)

      • getInt(String columnName)

      如果列的类型不知道,可以通过下面的方法来操作

      • getObject(int columnIndex)

      • getObject(String columnName)

    • boolean next()

      用于判断是否有下一条记录。

      如果有返回true,并且让游标向下移动一行。

      如果没有返回false。

    • 关闭资源

      Jdbc程序运行完后,切记要释放程序在运行过程中,创建的那些与数据库进行交互的对象,这些对象通常是ResultSet、Statement和Connection对象。

      特别是Connection对象,它是非常稀有的资源,用完后必须马上释放,如果Connection不能及时、正确的关闭,极易导致系统宕机。

      Connection的使用原则是尽量晚创建,尽量早的释放。

      为确保资源释放代码能运行,资源释放代码也一定要放在finally语句中。

4. JDBC中的事务

在jdbc中处理事务,都是通过Connection完成的。

同一事务中所有的操作,需要同一个Connection对象。

Connection的三个方法与事务相关:

setAutoCommit(boolean)

默认值就是true,表示自动提交,也就是每条执行的SQL语句都是一个单独的事务。

如果设置false,即关闭自动提交,改为手动提交事务,也就相当于开启了事务。

con.setAutoCommit(false);
  • commit()

      提交事务

con.commit();

  • rollback()

        回滚事务

con.rollback();

        jdbc处理事务的代码格式:

try {
    con.setAutoCommit(false); // 开启事务
    // …
    con.commit(); // try的最后提交事务
} catch() {
    con.rollback(); // 回滚事务
}

5. 抽取 JDBC 工具类

  • JDBCUtils.java

package com.codingfuture;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public class JDBCUtils {
    private static final String URL;
    private static final String USERNAME;
    private static final String PASSWORD;

    static {
        InputStream resource = ClassLoader.getSystemResourceAsStream("jdbc.properties");
        Properties properties = new Properties();
        try {
            properties.load(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }

        URL = properties.getProperty("url");
        USERNAME = properties.getProperty("username");
        PASSWORD = properties.getProperty("password");
    }

    public static Connection getConnection() {
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
        } catch (SQLException e) {
            System.err.println("数据库连接参数错误,Connection获取失败!");
            System.err.println(e.getMessage());
        }
        return connection;
    }

}
  • jdbc.properties
    url=jdbc:mysql:///mydb06
    username=root
    password=root

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值