JAVA: JDBC入门教程(二) 通过JDBC进行简单的增删改查

对数据库的更新操作

数据库的更新包括:INSERT UPDATE DELETE

执行数据库更新操作需要用到 Statement类,该类通过Connection的createStatement()方法来获得,写好sql语句然后调用Statement对象的executeUpdate(sql) 方法来实现更新操作,很简单。

比如说我想在user表里加入一条记录,可以分为一下几个步骤

  1. 获取数据库连接
  2. 创建Statement对象
  3. 写sql语句
  4. 执行更新操作代码如下
@Test
    public void insertUser(){
        Connection conn = null;
        Statement statement = null;
        try {
            //获取数据库连接
            conn = DBTools.getConnection();
            //创建Statement对象
            statement = conn.createStatement();
            //写sql语句
            String sql = "INSERT INTO store.user (account,password,role) VALUES ('admin','123',1)";
            //执行更新操作
            statement.executeUpdate(sql);
        } catch (Exception e) {
            e.printStackTrace();
        }   
    }

测试一下方法 发现user表里已经多了一条记录,这里进行的是insert操作 update delete操作步骤完全相同,读者可以自己练习。

PS:凡是看见有@Test这个标志的方法 都是写在junit测试类里面的,直接在方法名上右键 run as --junit test 即可测试方法

好了,上面说了一个插入的操作,但是在一个程序里,肯定会有多次对数据库更新的操作,如果每更新一次都像上面那样按部就班的写,写出来的程序则会非常臃肿,不利于维护,所以我们应该把这个数据库更新的操作抽象成一个通用的方法,不管是插入,删除,还是修改,这些操作的步骤都是一样的,无非就是sql语句不一样而已。所以这个通用方法的形式参数就只有一个 那就是 String sql。

方法如下:

//通用的更新方法
    public static void update(String sql){
        Connection conn = null;
        Statement statement = null;
        try {
            //获取数据库连接
            conn = DBTools.getConnection();
            //创建Statement对象
            statement = conn.createStatement();
            //执行更新操作
            statement.executeUpdate(sql);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

这样的话所有的更新操作,都可以用调用这个方法来实现了。不过这个方法还比较低级,还存在一个严重的缺陷。大家都知道数据库的连接数是有限的,而我们的程序是在数据库获取到连接然后执行完操作以后就结束了,这样做是很不合适的,因为原来我们获取的连接没有断开,我们的程序始终与数据库保持着连接,如果执行完操作断开连接的话,会造成资源的浪费,若有多个操作执行的话,很容易就把数据库连接数给占满了,所以我们每次执行完操作的时候一定要记住释放资源。

释放资源操作很简单 只需要调用对象的close()方法即可

所以完整的操作步骤应该是

1. 获取数据库连接

 2. 创建Statement对象

 3. 写sql语句

 4. 执行更新操作

 5. 释放资源

下面我们进一步改造一下我们的通用方法

//通用的更新方法
    public static void update(String sql){
        Connection conn = null;
        Statement statement = null;
        try {
            //获取数据库连接
            conn = DBTools.getConnection();
            //创建Statement对象
            statement = conn.createStatement();
            //执行更新操作
            statement.executeUpdate(sql);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

这样这个代码才初步成型。现在就可以在自己的测试类里测试一下这个方法了。

2. 对数据库的查询操作

上面讲到了对数据库的更新操作,有五个步骤,对数据库的查询操作也差不太多就是多了一步。

程序要查询数据库的数据,数据库就会返回程序要查询的数据, 不过数据库并不是直接返回的字符串,而是对数据进行了封装,返回了一个特定的类型。这时候就需要一个对象来专门对这种类型进行操作,这个对象就是 ResultSet 。

查询数据库的步骤可以分为:

  1. 获取数据库连接
  2. 创建Statement对象和 ResultSet 对象
  3. 写sql语句
  4. 执行查询操作(调用Statement对象的executeQuery(sql)操作)并且接收从数据库返回的数据
  5. 释放资源

我们把刚刚插入user表的那条记录查询出来

@Test
    public void selectUser(){
        Connection conn = null;
        Statement statement = null;
        ResultSet rs = null;
        try {
            //获取数据库连接
            conn = DBTools.getConnection();
            //创建Statement对象
            statement = conn.createStatement();
            //写sql语句
            String sql ="SELECT * FROM store.user";
            //接收数据库返回的数据
            rs = statement.executeQuery(sql);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            //释放资源
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

现在所有的数据都在这个 rs 里面了,下面来看看如何对 rs 里面的数据进行操作。

步骤:

  1. 判断rs里面有没有数据
  2. 取出rs里面字段的值

代码

方式一:

//若查询的仅有一条记录
if(rs.next){
    //获取字段 account,password,role 的值
    String account = rs.getString("account");//参数是数据库表的字段名
    String password = rs.getString ("password");
    int role = rs.getInt("role");
}
//若查询有多条数据
while(rs.next){//循环
    //获取字段 account,password,role 的值
    String account = rs.getString("account");//参数是数据库表的字段名
    String password = rs.getString ("password");
    int role = rs.getInt("role");
}

方式二

//若查询的仅有一条记录
if(rs.next){
    //获取字段 account,password,role 的值
    String account = rs.getString(2);//参数是数据库表的第几列
    String password = rs.getString (3);
    int role = rs.getInt(4);
}
//若查询有多条数据
while(rs.next){//循环
    //获取字段 account,password,role 的值
    String account = rs.getString(2);//参数是数据库表的第几列
    String password = rs.getString (3);
    int role = rs.getInt(4);
}

现在我们就可以把刚刚取出来的user表里的数据取出来了。
同更新操作一样,我们也可以把这个查询操作抽象成一个通用方法放到DBTools工具类里。

public ResultSet get(String sql){
        Connection conn = null;
        Statement statement = null;
        ResultSet rs = null;
        try {
            //获取数据库连接
            conn = DBTools.getConnection();
            //创建Statement对象
            statement = conn.createStatement();
            //接收数据库返回的数据
            rs = statement.executeQuery(sql);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            //释放资源
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return rs;
    }

好了,到现在我们已经把更新和查询的通用方法都写完了,不过版本很低,后续会不断完善的。不知道你们有没有发现 update() 方法和 get()方法释放资源的那个步骤很相似,我们完全可以把这一步再进行抽取,写一个释放资源的方法。这个方法的逻辑大概是这样的,如果有 ResultSet 的连接先关闭它,如果没有则判断有没有 Statement 的连接,有就关闭没有就判断有没有 Connection 的连接,做同样的操作,所以这个方法就可以写成

//  释放资源
    public static void release(ResultSet rs,Statement statement,Connection conn){
        if (rs != null) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (statement != null) {
            try {
                statement.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

现在的DBTools 就初步成型了

package com.ikeepstudying.utils;

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

public class DBTools {
//  数据库的用户名
    private static final String user = "root";
//  数据库的密码
    private static final String password ="";
//  要访问的数据库的地址
    private static final String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8";
//  数据库的驱动信息
    private static final String driver = "com.mysql.jdbc.Driver";
//  定义数据库的连接
    private static Connection conn;
//  定义一个Statement对象
    private static Statement statement;
//  定义查询返回的结果集
    private static ResultSet rs;

    public DBTools(){
        try{
            Class.forName(driver);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

//  获取数据库的连接
    public static Connection getConnection(){
        try{
            conn = DriverManager.getConnection(url,user,password);
        }catch(Exception e){
            e.printStackTrace();
        }
        return conn;
    }

//  释放资源
    public static void release(ResultSet rs,Statement statement,Connection conn){
        if (rs != null) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (statement != null) {
            try {

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

    //通用的更新方法
    public static void update(String sql){
        Connection conn = null;
        Statement statement = null;
        try {
            //获取数据库连接
            conn = DBTools.getConnection();
            //创建Statement对象
            statement = conn.createStatement();
            //执行更新操作
            statement.executeUpdate(sql);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            release(null,statement,conn);
        }
    }

    //通用的查询方法
    public ResultSet get(String sql){
        Connection conn = null;
        Statement statement = null;
        ResultSet rs = null;
        try {
            //获取数据库连接
            conn = DBTools.getConnection();
            //创建Statement对象
            statement = conn.createStatement();
            //接收数据库返回的数据
            rs = statement.executeQuery(sql);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            release(rs,statement,conn);
        }
        return rs;
    }
}

想进一步改善这个工具类 请继续往下阅读

JAVA: JDBC入门教程(一): 连接数据库

JAVA: JDBC入门教程(二) 通过JDBC进行简单的增删改查

JAVA:JDBC入门教程(三) PreparedStatement的使用

 

本文:JAVA: JDBC入门教程(二) 通过JDBC进行简单的增删改查