首页 > 技术文章 > Java之JDBC

CoLo 2021-08-05 00:17 原文

Java之JDBC

JDBC简介

Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。我们通常说的JDBC是面向关系型数据库的。

数据库驱动

Java程序无法直接连接到数据库,所以中间需要一层数据库厂商提供的数据库驱动

sun公司为了简化开发人员对数据库的操作,提供了一个Java操作数据库的规范,俗称JDBC,实现对数据库的操作是数据库驱动去做。开发人员只需要掌握JDBC就可以了。

Java通过java.sql.DriverManager来管理所有数据库的驱动注册,所以如果想要建立数据库连接需要先在java.sql.DriverManager中注册对应的驱动类,然后调用getConnection方法才能连接上数据库。 JDBC定义了一个叫java.sql.Driver的接口类负责实现对数据库的连接,所有的数据库驱动包都必须实现这个接口才能够完成数据库的连接操作。java.sql.DriverManager.getConnection(xx)其实就是间接的调用了java.sql.Driver类的connect方法实现数据库连接的。数据库连接成功后会返回一个叫做java.sql.Connection的数据库连接对象,一切对数据库的查询操作都将依赖于这个Connection对象。

JDBC程序

  1. 创建一个普通项目

  2. 导入数据库驱动mysql-connector-java-5.1.47.jar

    右键 ==> Add As Library...

  3. 编写测试代码

     public static void main(String[] args) throws Exception{
        //加载数据库驱动
        Class.forName("com.mysql.jdbc.Driver");
    
        //用户信息+url获取数据库连接
        String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
        String username = "root";
        String password = "password";
    
        //DriverManager.getConnection(),驱动管理获取数据库连接对象
        Connection connection = DriverManager.getConnection(url, username, password);
    
        //获取执行sql语句的对象      statement
        Statement statement = connection.createStatement();
    
        //输入sql语句,并用statement执行sql,返回链表对象resultSet
        String sql = "SELECT * FROM people";
        ResultSet resultSet = statement.executeQuery(sql);
    
        //遍历元素,打印输出
        while (resultSet.next()){
            System.out.println("id= " + resultSet.getObject("id"));
            System.out.println("name= " + resultSet.getObject("name"));
            System.out.println("age= " + resultSet.getObject("age"));
            System.out.println("address= " + resultSet.getObject("address"));
    
        }
    
        //释放资源
        resultSet.close();
        statement.close();
        connection.close();
    
    }
    
  4. 基本步骤

    1. Class.forName(Driver) 加载数据库驱动
    2. 用户信息+url
    3. DriverManager.getConnection(url, username, password) 获取数据库连接对象
    4. connection.createStatement() 获取执行sql的对象
    5. sql+ statement执行sql语句,获取ResultSet执行结果链表
    6. 遍历处理结果
    7. 释放资源
  5. 关于加载驱动

    这里不需要返回一个class对象,这里只是激活这个类拿到Driver类的静态代码即可

    //加载数据库驱动
    Class.forName("com.mysql.jdbc.Driver");
    

    可以看Driver类的源码。最早注册加载数据库驱动的语句就是DriverManager.registerDriver(new Driver());,而这里Driver类的静态代码块已经帮我们做了这件事情了,我们只需要激活这个类,执行这段静态代码块即可。也不需要返回一个class对象。

  6. 数据库连接URL

    //MySQL
    // jdbc:mysql://主机名:端口号/数据库名?参数1&参数2&参数3
    String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
    
    //Oracle
    //Oracle没有数据库,只有各种表
    // jdbc:oracle:thin:@localhost:1521:sid
    
  7. connection对象

    connection对象代表数据库

    可以设置数据库自动提交。事务提交(connection.commit()),事务回滚(connection.rollback())。

  8. statement对象

    调用connnection.createStatement()方法会返回一个statement对象。

    是具体执行sql语句的对象。主要用statement.executeQuery()执行查询SQL语句statement.executeUpdate()方法执行增删改SQL语句

  9. ResultSet

    查询的结果集,封装了所有的查询结果。

    拿SQL语句执行结果的方式

    resultSet.getObject 不知道列类型的情况下使用

    resultSet.getString 知道列类型的情况下指定数据类型

    resultSet.getInt

    resultSet.getDate

    ...

    移动下标

    resultSet.beforeFirst();      //下标移动到列表最前面
    resultSet.afterLast();      //下标移动到列表最后面
    resultSet.next();        //移动到下一个数据
    resultSet.previous();   //移动到前一行
    resultSet.absolute(row);    //移动到指定行
    

Statement

statement对象是具体执行SQL语句的对象。上面也提到了主要有两个方法statement.executeQuery()执行查询SQL语句statement.executeUpdate()方法执行增删改SQL语句

executeQuery()方法用于执行查询的SQL语句,调用之后会返回一个ResultSet查询结果集,里面封装了所有的查询结果。

executeUpdate()方法用于执行增删改的SQL语句,调用之后会返回一个int类型的值,代表一共几行数据发生了变动。

CURD操作

crud是指在做计算处理时的增加(Create)、检索(Retrieve)、更新(Update)和删除(Delete)几个单词的首字母简写。crud主要被用在描述软件系统中数据库或者持久层的基本操作功能。我们这里后面指到的就是对数据库的增删改查操作。

关于utils和db.properties

后面会涉及到写一个工具类来进行SQL的执行,以及将配置内容写入配置文件。这些操作都是为了降低程序耦合。

比如可以讲连接数据库时所需要的信息写入db.properties资源文件放在src目录下或者resources目录,通过反射调用类加载器去读取src下的资源文件。工具类则用来专门负责封装对数据库的操作。

自定义JDBC工具类

jdbc01#main

@Test
public static void main(String[] args) {

    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;

    try {
        connection = JdbcUtils.getConnection();

        //增加一条数据
        String sqlU = "insert into people(id, name, age, address) VALUES (10, 'azh19', 10, 'ha10g')";
        int i = JdbcUtils.executeU(connection, sqlU, statement);
        if (i>0){
            System.out.println("数据插入成功!改变了" + i + "行数据");
        }


        //查询数据
        String sqlQ = "SELECT * FROM people";
        resultSet = JdbcUtils.executeQ(connection, sqlQ, statement, resultSet);

        while (resultSet.next()){
            System.out.println("id = " + resultSet.getInt("id"));
            System.out.println("name = " + resultSet.getString("name"));
            System.out.println("age = " + resultSet.getInt("age"));
            System.out.println("address = " + resultSet.getString("address"));
            System.out.println("============================");
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        //  释放资源
        boolean flag = JdbcUtils.closeResources(connection, statement, resultSet);
        if (flag){
            System.out.println("资源释放完成!");
        }else {
            System.out.println("资源释放失败!");
        }
    }

}

JdbcUtils

public class JdbcUtils {

    private static String driver = null;
    private static String url = null;
    private static String username = null;
    private static String password = null;

    static {

        try {
            //获取资源文件流
            InputStream resourceAsStream = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");

            //加载资源文件
            Properties properties = new Properties();
            properties.load(resourceAsStream);

            //获取资源文件中指定内容
            driver = properties.getProperty("driver");
            username = properties.getProperty("username");
            password = properties.getProperty("pwd");
            url = properties.getProperty("url");
						//加载驱动
            Class.forName(driver);


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取数据库连接
    public static Connection getConnection(){
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(url, username, password);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return connection;
    }

    //查询方法
    public static ResultSet executeQ(Connection connection, String sql, Statement statement, ResultSet resultSet) throws SQLException {
        statement = connection.createStatement();
        resultSet = statement.executeQuery(sql);
        return resultSet;
    }

    //增删改方法
    public static int executeU(Connection connection, String sql, Statement statement) throws SQLException {
        statement = connection.createStatement();
        int row = statement.executeUpdate(sql);
        return row;
    }

    //释放资源
    public static boolean closeResources(Connection connection, Statement statement, ResultSet resultSet){
        boolean flag = true;
        if (connection!=null){
            try {
                connection.close();
                flag = true;
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }

        if (statement!=null){
            try {
                statement.close();
                flag = true;
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }

        if (resultSet!=null){
            try {
                resultSet.close();
                flag = true;
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }

        return flag;
    }

}

db.properties

driver=com.mysql.jdbc.Driver
username=root
pwd=password
url=jdbc:mysql://localhost:3306/test?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai

CRUD-Create

public class TestInsert {
    public static void main(String[] args) {

        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;

        try {
            connection = JdbcUtils.getConnection();

            //增加一条数据
            String sqlU = "insert into people(id, name, age, address) VALUES (11, 'azh11', 11, 'ha11g')";
            int i = JdbcUtils.executeU(connection, sqlU, statement);

            if (i>0){
                System.out.println("数据插入成功!改变了" + i + "行数据");
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //  释放资源
            boolean flag = JdbcUtils.closeResources(connection, statement, resultSet);
            if (flag){
                System.out.println("资源释放完成!");
            }else {
                System.out.println("资源释放失败!");
            }
        }

    }
}

CRUD-Delete

public class TestDelete {
    public static void main(String[] args) {

        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;

        try {
            connection = JdbcUtils.getConnection();

            //删除一条数据
            String sqlU = "DELETE FROM people where id = 11;";
            int i = JdbcUtils.executeU(connection, sqlU, statement);

            if (i>0){
                System.out.println("数据删除成功!改变了" + i + "行数据");
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //  释放资源
            boolean flag = JdbcUtils.closeResources(connection, statement, resultSet);
            if (flag){
                System.out.println("资源释放完成!");
            }else {
                System.out.println("资源释放失败!");
            }
        }

    }
}

CRUD-Update

public class TestUpdate {
    public static void main(String[] args) {

        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;

        try {
            connection = JdbcUtils.getConnection();

            //增加一条数据
            String sqlU = "update people set name = 'asdasd' where id = 6";
            int i = JdbcUtils.executeU(connection, sqlU, statement);

            if (i>0){
                System.out.println("数据更新成功!改变了" + i + "行数据");
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //  释放资源
            boolean flag = JdbcUtils.closeResources(connection, statement, resultSet);
            if (flag){
                System.out.println("资源释放完成!");
            }else {
                System.out.println("资源释放失败!");
            }
        }

    }
}

CRUD-Retrieve

public class TestSelect {
    public static void main(String[] args) {

        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;

        try {
            connection = JdbcUtils.getConnection();

            //查询一条数据
            String sqlQ = "SELECT * FROM people";
            resultSet = JdbcUtils.executeQ(connection, sqlQ, statement, resultSet);

            while (resultSet.next()){
                System.out.println("id = " + resultSet.getInt("id"));
                System.out.println("name = " + resultSet.getString("name"));
                System.out.println("age = " + resultSet.getInt("age"));
                System.out.println("address = " + resultSet.getString("address"));
                System.out.println("============================");
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //  释放资源
            boolean flag = JdbcUtils.closeResources(connection, statement, resultSet);
            if (flag){
                System.out.println("资源释放完成!");
            }else {
                System.out.println("资源释放失败!");
            }
        }

    }
}

PreparedStatement

预编译,防止SQL注入。与statement对象的区别是,不直接放入sql语句,先用?作为占位符进行预编译,等预编译完成后,对?进行赋值,之后调用execute等方法不需要添加参数即可完成执行SQL语句。

//使用?占位符
String sqlU = "insert into people(id, name, age, address) VALUES (?, ?, ?, ?)";
connection = JdbcUtils.getConnection();
//获得preparedStatement对象,并进行预编译
preparedStatement = connection.prepareStatement(sqlU);

//对?进行赋值,第1个参数为?的下标,从1开始;第2个参数为对该?赋什么值
preparedStatement.setInt(1,12); //第1个? , 赋值为12
preparedStatement.setString(2,"qdwewq12");  //第2个? , 赋值为qdwewq12
preparedStatement.setInt(3,12);     //第3个? , 赋值为12
preparedStatement.setString(4, "ads1234");      //第4个? , 赋值为ads1234

//执行SQL
preparedStatement.executeUpdate();

//注意Date类型的需要进行转换
//例如
preparedStatement.setDate(5, new java.sql.Date(new Date().getTime()));
  1. public static void main(String[] args) {
    
            Connection connection = null;
            PreparedStatement preparedStatement = null;
    
            try {
                //使用?占位符
                String sqlU = "insert into people(id, name, age, address) VALUES (?, ?, ?, ?)";
                connection = JdbcUtils.getConnection();
                //获得preparedStatement对象,并进行预编译
                preparedStatement = connection.prepareStatement(sqlU);
    
                //对?进行赋值
                preparedStatement.setInt(1,12); //第1个? , 赋值为12
                preparedStatement.setString(2,"qdwewq12");  //第2个? , 赋值为qdwewq12
                preparedStatement.setInt(3,12);     //第3个? , 赋值为12
                preparedStatement.setString(4, "ads1234");      //第4个? , 赋值为ads1234
    
                //执行SQL
                int i = preparedStatement.executeUpdate();
    
                if (i>0){
                    System.out.println("数据插入成功");
                }
    
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //  释放资源
                boolean flag = JdbcUtils.closeResources(connection, null,null,preparedStatement);
                if (flag){
                    System.out.println("资源释放完成!");
                }else {
                    System.out.println("资源释放失败!");
                }
            }
    
        }
    
  2. public static void main(String[] args) {
    
            Connection connection = null;
            PreparedStatement preparedStatement = null;
    
            try {
                //使用?占位符
                String sqlU = "DELETE FROM people where id = ?";
                connection = JdbcUtils.getConnection();
                //获得preparedStatement对象,并进行预编译
                preparedStatement = connection.prepareStatement(sqlU);
    
                //对?进行赋值
                preparedStatement.setInt(1,10); //第1个? , 赋值为12
                //执行SQL
                int i = preparedStatement.executeUpdate();
    
                if (i>0){
                    System.out.println("数据删除成功");
                }
    
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //  释放资源
                boolean flag = JdbcUtils.closeResources(connection, null,null,preparedStatement);
                if (flag){
                    System.out.println("资源释放完成!");
                }else {
                    System.out.println("资源释放失败!");
                }
            }
    
        }
    
  3. public static void main(String[] args) {
    
            Connection connection = null;
            PreparedStatement preparedStatement = null;
    
            try {
                //使用?占位符
                String sqlU = "update people set name = 'asdasd' where id = ?";
                connection = JdbcUtils.getConnection();
                //获得preparedStatement对象,并进行预编译
                preparedStatement = connection.prepareStatement(sqlU);
    
                //对?进行赋值
                preparedStatement.setInt(1,12); //第1个? , 赋值为12
    
                //执行SQL
                int i = preparedStatement.executeUpdate();
    
                if (i>0){
                    System.out.println("数据修改成功");
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //  释放资源
                boolean flag = JdbcUtils.closeResources(connection, null,null,preparedStatement);
                if (flag){
                    System.out.println("资源释放完成!");
                }else {
                    System.out.println("资源释放失败!");
                }
            }
    
        }
    
  4. public static void main(String[] args) {
    
            Connection connection = null;
            PreparedStatement preparedStatement= null;
            ResultSet resultSet = null;
    
            try {
                connection = JdbcUtils.getConnection();
                //查询一条数据
                String sqlQ = "SELECT * FROM people where id = ?";
    
                //获取preparedStatement对象
                preparedStatement = connection.prepareStatement(sqlQ);
                //给?赋值
                preparedStatement.setInt(1,12);
                //获得查询结果集
                resultSet = preparedStatement.executeQuery();
                //循环遍历输出
                while (resultSet.next()){
                    System.out.println(resultSet.getInt("id"));
                    System.out.println(resultSet.getString("name"));
                    System.out.println(resultSet.getInt("age"));
                    System.out.println(resultSet.getString("address"));
                    System.out.println("==============================");
    
                }
    
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //  释放资源
                boolean flag = JdbcUtils.closeResources(connection, null, resultSet, preparedStatement);
                if (flag){
                    System.out.println("资源释放完成!");
                }else {
                    System.out.println("资源释放失败!");
                }
            }
        }
    

推荐阅读