Java--JDBC操作数据库

JDBC是一种可用于执行SQL语句的Java API,是连接数据库和Java程序的纽带。JDBC全称是Java Database Connectivity,是一套面向对象的应用程序接口,指定了统一的访问各种关系型数据库的标准接口。JDBC是一种底层的API,因此访问数据库时需要再逻辑层中嵌入SQL语句。

1.JDBC技术主要完成以下任务:

1.1.与数据库建立连接。

1.2.向数据库发送SQL语句。

1.3.处理从数据库返回的结果。

需要注意:JDBC并不能直接访问数据库,必须依赖数据库厂商提供的JDBC驱动程序。

2.JDBC驱动程序的类型

JDBC-ODBC桥

        依靠ODBC驱动器和数据库通信。这种连接方式必须将ODBC二进制代码加载到使用该驱动程序的每台客户机上。

JDBC网络驱动

        这种驱动程序将JDBC转换为与DBMS无关的网络协议,又被某个服务器转换为DBMS协议,是一种利用Java编写的JDBC驱动程序,也是最灵活的驱动程序。

本地协议驱动

        这是一种纯Java驱动程序。这种驱动程序将JDBC调用直接转换为DBMS所使用的网络协议,允许从客户机上直接调用DBMS服务器,是一种很使用的访问Internet的解决方法。

3.JDBC中常用的类和接口

常用的JDBC类和接口都在java.sql包中。

3.1 Connection接口

Connection接口代表与特定的数据库的连接,在连接上下文中执行SQL语句并返回结果。

Connection接口的常用方法
方法功能描述
createStatement()创建Statement对象
createStatement(int resultSetType, int resultSetConcurrency)创建一个Statement对象,该对象将生成具有给定类型、并发性和可保存性的ResultSet对象
preparedStatement()创建预处理对象preparedStatement
isReadOnly()查看当前Connection对象的 读取模式是否为只读模式
setReadOnly()设置当前Connection独享的读取模式为只读模式,默认为非只读模式
commit()使所有上一次提交/回滚后进行的更改成为持久更改,并释放此Connection对象所持有的所有数据库锁
roolback()取消当前事务中进行的所有更改,并释放此Connection对象所持有的所有数据库锁
close()立即释放此Connection对象所持有的数据库和JDBC资源

3.2 Statement接口

Statement接口用于在已经建立Connection连接的基础上向数据库发送SQL语句。

在JDBC中有3种Statement对象:

3.2.1 Statement接口

        Statement对象用于执行不带参数的简单SQL语句;

Statement接口中的常用方法
方法功能描述
execute(String sql)执行静态的SELECT语句,该语句可能返回多个结果集
executeQuery(String sql)执行给定的SQL语句,该语句返回单个resultSet对象
clearBatch()清空此Statement对象的当前SQL命令列表
executeBatch()将一组命令提交给数据库来执行,如果命令全部执行成功,则返回一个更新计数组成的数组,数组元素的排序与SQL语句的添加顺序对应
addBatch(String sql)将给定的SQL命令添加到此Statement对象的当前命令列表中,如果驱动程序不支持批量操作,将抛出异常
close()释放Statement对象占用的数据库和JDBC资源

3.2.2 PreparedStatement接口

        PreparedStatement继承了Statement,用来执行动态的SQL语句;通过PreparedStatement实例执行的动态SQL语句,将被预编译并保存到PreparedStatement实例中,从而可以反复地执行该SQL语句。

PreparedStatement接口提供的常用方法
方法功能描述
setInt(int index, int k)将指定位置的参数设置为int值
setFloat(int index, float f)
setLong(int index, long l)
setDouble(int index, double d)
setBoolean(int index, boolean b)
setDate(int index, date date)
setString(int index, String s)
setNull(int index, intsqlType)将指定位置的参数设置为SQL NULL
executeQuery()在此PreparedStatement对象中执行SQL查询,并返回该查询结果生成的ResultSet对象
executeUpdate()执行前面包含参数的动态INSERT,UPDATE,DELETE语句
clearParameters()清除当前所有参数的值

3.2.3 CallableStatement接口

        CallableStatement继承了PreparedStatement,用于执行对数据库的存储过程的调用。

3.3 PreparedStatement接口

        同3.2.2

3.4 DriverManager类

        DriverManager类用来管理数据库中的所有驱动程序。它是JDBC的管理层,作用于用户和驱动程序之间,跟踪可用的驱动程序,并在数据库和驱动程序之间建立连接。

DriverManager类的常用方法
方法功能描述
getConnection(String url, String user, String password)指定3个入口参数,来获取与数据库的连接
setLoginTimeout()设置驱动程序试图登录某数据库的最长等待时间,单位为秒
println(String message)将一条消息打印到当前JDBC日志流中

3.5 ResultSet接口

        ResultSet接口类似一个临时表,用来暂时存储数据库查询操作所获取的结果集。ResultSet实例具有指向当前数据行的指针,指针开始的位置在第一条记录的前面,通过next()方法可将指针向下移动。

ResultSet接口提供的常用方法
方法功能描述
getInt()以int的形式获取此ResultSet对象的当前行的指定列的值。如果列值是NULL,则返回值是0
getFloat()
getDate()
getBoolean()
getString()
getObject()
first()将指针移动到当前记录的第一行
last()将指针移动到当前记录的最后一行
next()将指针向下移动一行
beforeFirst()将指针移动到集合的开头(第一行位置)
afterLast()将指针移动到集合的尾部(最后一行位置)
absolute(int index)将指针移动到ResultSet给定编号的行
isFirst()判断指针是否位于当前记录的第一行
isLast()
updateInt()用int值更新指定列
updateFloat()
updateLong()
updateString()
updateObject()
updateNull()
updateDate()
updateDouble()
getrow()查看当前行的索引号
insertRow()将插入行的内容插入到数据库中
updateRow()将当前行的内容更新到数据库表
deleteRow()删除当前行,但不同步到数据库,而是执行close()方法后同步到数据库中

4.数据库操作

4.1 连接数据库步骤:

        4.1.1 下载数据库驱动类,并加载到程序中

        详见JDBC | mysql-connector jar包的加载_mysql-connector-java.jar-CSDN博客

        4.1.2 通过java.lang包的静态方法forName()来加载JDBC驱动程序

        4.1.3 通过java.lang包中类DriverManager的静态方法getConnection(String url, String user, String pwd)建立数据库连接

package db;

import java.sql.*;          //导入java.sql包

public class Conn {
    Connection con;     //声明Connection对象

    public Connection getConnection() {         //建立返回值为Connection对象的方法
        try {
//            Class.forName("com.mysql.jdbc.Driver");           //deprecated
            Class.forName("com.mysql.cj.jdbc.Driver");      //加载数据库驱动类
            System.out.println("数据库驱动加载成功");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        
        try {
            //通过访问数据库的url,获取数据库连接对象con
            con = DriverManager.getConnection("jdbc:mysql:" + "//127.0.0.1:3306/debug", "root", "12345678");
            System.out.println("数据库连接成功");
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return con;     //返回Connection对象
    }

    public static void main(String[] args) {
        Conn c = new Conn();        //创建类对象
        c.getConnection();          //调用连接数据库的方法
    }
}

输出:
        数据库驱动加载成功
        数据库连接成功

4.2 创建Statement对象向数据库发送SQL语句

        DriverManager中的getConnection()方法只是获取与数据库的连接,要执行SQL语句首先要获得Statement类对象,通过创建的数据库连接对象con的createStatement()方法可获得Statement对象

4.2.1 创建Statement对象

try{

        Statement statement = con.createStatement();

}catch(SQLException e){

        e.printStackTrace();

}

4.3 处理查询结果

        有了Statement对象,就可以调用这个对象的相应方法实现对象数据库的查询和修改,并将查询的结果放在ResultSet类的对象中:

String sql = "select * from xxx where  xxx;";

ResultSet resultset = Statement.executeQuery(sql)

        运行结果为返回的一个ResultSet对象,ResultSet对象一次只可以看到结果集中的一行数据,使用该对象的next()方法可以将光标从当前位置移动到下一行,返回一个boolean类型的数据,当游标移动到最后一行之后会返回false。 

4.4 顺序查询

package db;

import java.sql.*;

public class Gradation {
    static Connection con;
    static Statement statement;
    static ResultSet resultSet;

    public Connection getConnection() throws ClassNotFoundException, SQLException {     //连接数据库的方法
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection con = DriverManager.getConnection("jdbc:mysql:" + "//localhost:3306/debug", "root", "12345678");
        return con;
    }

    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        Gradation gra = new Gradation();
        con = gra.getConnection();          //建立与数据库的连接
        statement = con.createStatement();      //实例化一个用于执行SQL语句的Statement对象
        String sql = "select * from results limit 10;";
        resultSet = statement.executeQuery(sql);   //执行sql语句

        while (resultSet.next()) {
            String id = resultSet.getString("id");
            String createTime = resultSet.getString(2);     //createTime位于表中第二列,可以以这种方式获取对应字段值
            String endTime = resultSet.getString("end_time");
            String ProjectId = resultSet.getString("project_id");
            String receive_msg_count = resultSet.getString(5);
            String send_msg_count = resultSet.getString(6);
            String status = resultSet.getString(7);
            String strike = resultSet.getString(8);
            String suite_id = resultSet.getString(9);
            String suite_name = resultSet.getString(10);

            System.out.println("id:" + id + "; " + "createTime:" + createTime + "; " + "endTime:" + endTime + "; " + "ProjectId:" + ProjectId
                    + "; " + "receive_msg_count:" + receive_msg_count + "; " + "send_msg_count:" + send_msg_count + "; " + "status:"
                    + status + "; " + "strike:" + strike + "; " + "suite_id:" + suite_id + "; " + "suite_name:" + suite_name + "; ");
        }
    }
}

输出:
        id:1234; createTime:2023-09-27 03:45:00; endTime:2023-09-27 03:51:41; ProjectId:1; receive_msg_count:12; send_msg_count:12; status:1; strike:SYSTEM; suite_id:20; suite_name:巡检;
        id:2582; createTime:2023-09-14 12:15:00; endTime:2023-09-14 12:17:09; ProjectId:1; receive_msg_count:3; send_msg_count:3; status:1; strike:SYSTEM; suite_id:19; suite_name:行情;
        id:2583; createTime:2023-09-14 12:30:00; endTime:2023-09-14 12:32:15; ProjectId:1; receive_msg_count:3; send_msg_count:3; status:1; strike:SYSTEM; suite_id:19; suite_name:行情;
        id:2584; createTime:2023-09-14 12:45:00; endTime:2023-09-14 12:47:14; ProjectId:1; receive_msg_count:3; send_msg_count:3; status:1; strike:SYSTEM; suite_id:19; suite_name:行情;
        id:2585; createTime:2023-09-14 13:00:00; endTime:2023-09-14 13:02:20; ProjectId:1; receive_msg_count:3; send_msg_count:3; status:1; strike:SYSTEM; suite_id:19; suite_name:行情;
        id:2586; createTime:2023-09-14 13:00:00; endTime:2023-09-14 13:07:01; ProjectId:1; receive_msg_count:9; send_msg_count:9; status:1; strike:SYSTEM; suite_id:20; suite_name:巡检;
        id:2587; createTime:2023-09-14 13:15:00; endTime:2023-09-14 13:17:15; ProjectId:1; receive_msg_count:3; send_msg_count:3; status:1; strike:SYSTEM; suite_id:19; suite_name:行情;
        id:2588; createTime:2023-09-14 13:30:00; endTime:2023-09-14 13:32:23; ProjectId:1; receive_msg_count:3; send_msg_count:3; status:1; strike:SYSTEM; suite_id:19; suite_name:行情;
        id:2589; createTime:2023-09-14 13:45:00; endTime:2023-09-14 13:47:20; ProjectId:1; receive_msg_count:3; send_msg_count:3; status:1; strike:SYSTEM; suite_id:19; suite_name:行情;
        id:2590; createTime:2023-09-14 14:00:00; endTime:2023-09-14 14:02:18; ProjectId:1; receive_msg_count:3; send_msg_count:3; status:1; strike:SYSTEM; suite_id:19; suite_name:行情; 

4.5 模糊查询

statement = con.createStatement();      //实例化一个用于执行SQL语句的Statement对象
String sql = "select * from results where suite_name like '巡%' limit 10;";
resultSet = statement.executeQuery(sql);   //执行sql语句

4.6 预处理语句

        通过Connection对象的preparedStatement(String sql)方法对SQL语句进行预处理,生成数据库底层的内部命令,并将命令封装在PreparedStatement对象中,通过调用PreparedStatement对象相应的方法可以执行底层数据库命令,减轻数据库负担,提高性能。

4.6.1 对SQL进行预处理时可使用通配符【?】来代替任何的字段值,如

sql = con.prepareStatement("select * from xx where id = ?");

4.6.2 在执行预处理语句前,要使用相应方法来设置通配符【?】所表示的值,如

sql.setInt(1,2);

1表示从左向右的第一个通配符,2表示设置的通配符的值,将通配符值设置为2后,功能等同于:

sql = con.prepareStatement("select * from xx where id = 2");

由上可知,使用预处理语句可以让程序动态地改变SQL语句中关于字段值的设定。

package db;

import java.sql.*;

public class Prep {
    static Connection con;
    static PreparedStatement preparedState;
    static ResultSet resultSet;

    public Connection getcon() throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        con = DriverManager.getConnection("jdbc:mysql:" + "//127.0.0.1:3306/debug", "root", "12345678");
        return con;
    }

    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        Prep prep = new Prep();
        con = prep.getcon();
        preparedState = con.prepareStatement("select * from results where id=?");   //使用通配符
        preparedState.setInt(1, 1234);       //设置参数
        resultSet = preparedState.executeQuery();       //执行预处理语句
        //如果当前记录不是结果集中最后一行,则进入循环
        while (resultSet.next()) {
            String id = resultSet.getString("id");
            String createTime = resultSet.getString(2);     //createTime位于表中第二列,可以以这种方式获取对应字段值
            String endTime = resultSet.getString("end_time");
            String ProjectId = resultSet.getString("project_id");
            String receive_msg_count = resultSet.getString(5);
            String send_msg_count = resultSet.getString(6);
            String status = resultSet.getString(7);
            String strike = resultSet.getString(8);
            String suite_id = resultSet.getString(9);
            String suite_name = resultSet.getString(10);

            System.out.println("id:" + id + "; " + "createTime:" + createTime + "; " + "endTime:" + endTime + "; " + "ProjectId:" + ProjectId
                    + "; " + "receive_msg_count:" + receive_msg_count + "; " + "send_msg_count:" + send_msg_count + "; " + "status:"
                    + status + "; " + "strike:" + strike + "; " + "suite_id:" + suite_id + "; " + "suite_name:" + suite_name + "; ");
        }
    }
}

输出:
        id:1234;createTime:2023-09-27 03:45:00;endTime:2023-09-27 03:51:41;ProjectId:1;receive_msg_count:12;send_msg_count:12;status:1;strike:SYSTEM;suite_id:20;suite_name:巡检; 

4.7 添加、修改、删除记录

        通过PreparedStatement类的指定参数,动态地对数据表中原有数据进行修改,并通过executeUpdate()方法执行更新语句操作;

package db;

import java.sql.*;

public class Renewal {
    static Connection con;
    static PreparedStatement preparedState;
    static ResultSet resultSet;

    public Connection getCon() throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        con = DriverManager.getConnection("jdbc:mysql:" + "//127.0.0.1:3306/debug", "root", "12345678");
        return con;
    }

    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        Renewal renewal = new Renewal();
        con = renewal.getCon();
        preparedState = con.prepareStatement("select * from modules");
        resultSet = preparedState.executeQuery();
        System.out.println("执行增删改查前的数据=========;");
        while (resultSet.next()) {
            String id = resultSet.getString(1);
            String name = resultSet.getString(2);
            String project_id = resultSet.getString(3);
            System.out.println("id:" + id + "; " + "name:" + name + "; " + "project_id:" + project_id + ";");
        }

        //预处理插入数据
        preparedState = con.prepareStatement("insert into modules values(?,?,?)");
        preparedState.setInt(1, 9);  //数据已有数据的id最大为8,从9开始插入
        preparedState.setString(2, "jeanet测试");
        preparedState.setInt(3, 99);
        //执行插入数据到表
        preparedState.executeUpdate();

        //预处理更新数据
        preparedState = con.prepareStatement("update modules set name=? where id = ?");
        preparedState.setString(1, "春田");
        preparedState.setInt(2, 9);
        //执行更新数据到表
        preparedState.executeUpdate();

        //预处理删除数据
        preparedState = con.prepareStatement("delete from modules where id= ?");
        preparedState.setInt(1, 8);
        //执行表数据删除数据操作
        preparedState.executeUpdate();

        //查询增删改后的表数据
        preparedState = con.prepareStatement("select * from modules");
        resultSet = preparedState.executeQuery();
        System.out.println("执行增删改查后的数据=========;");
        while (resultSet.next()) {
            String id = resultSet.getString(1);
            String name = resultSet.getString(2);
            String project_id = resultSet.getString(3);
            System.out.println("id:" + id + "; " + "name:" + name + "; " + "project_id:" + project_id + ";");
        }
    }
}

输出:
        执行增删改查前的数据=========;
        id:1; name:首页; project_id:1;
        id:2; name:个人中心; project_id:1;
        id:3; name:行情; project_id:1;
        id:4; name:xx交易; project_id:1;
        id:5; name:xx交易; project_id:1;
        id:6; name:资产; project_id:1;
        id:7; name:特殊模块; project_id:1;
        id:8; name:公共元素; project_id:1;
        执行增删改查后的数据=========;
        id:1; name:首页; project_id:1;
        id:2; name:个人中心; project_id:1;
        id:3; name:行情; project_id:1;
        id:4; name:xx交易; project_id:1;
        id:5; name:xx交易; project_id:1;
        id:6; name:资产; project_id:1;
        id:7; name:特殊模块; project_id:1;
        id:9; name:春田; project_id:99;

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chuntian_tester

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值