Java JDBC基本操作

本文介绍了Java JDBC中Driver接口、DriverManager类和Connection接口的基本用法,特别是Connection接口的getMetaData()、createStatement()、prepareStatement(String sql)、getTransactionIsolation()等方法以及事务操作。讲解了如何开启事务、提交和回滚,并提供了事务处理的案例。最后提到了ResultSet接口在处理查询结果集中的应用。

目录

1.Driver接口

2.DriverManager类

3.Connection接口

3.1connection.getMetaData();

3.2connection.createStatement();

3.3connection.prepareStatement(String sql);

3.4connection.getTransactionIsolation()

3.5事务操作

4.ResultSet接口


JDBC API主要位于java.sql包中,该包定义了一系列访问数据库的接口和类(提供一套标准的执行SQL语句的Java API),JDBC是连接应用程序与数据库间的中间桥梁,所以不同数据库需要导入对应的JDBC驱动程序jar包

1.Driver接口

专门提供给数据库厂商实现的驱动接口,用来创建连接

/**
 * Driver实现类对象可以直接new创建,也可以使用反射创建
 *   Class clazz = Class.forName("com.mysql.jdbc.Driver");
 *   Driver driver = (Driver)clazz.newInstance();
 */
Driver driver = new com.mysql.jdbc.Driver();

/**
 * 创建一个连接
 */
String url = "jdbc:mysql://localhost:3306/mysql";
Properties info = new Properties();
info.setProperty("user", "root");
info.setProperty("password", "123456");
Connection connection = driver.connect(url, info);

2.DriverManager类

用于加载JDBC驱动并创建连接,上面是直接通过Driver来创建的连接,可以使用DriverManager类来替换

/**
 * 获取Driver实现类对象
 *   加载驱动,将com.mysql.jdbc.Driver加载到内存中,一加载就会执行其中的static静态代码块
 *   这两步可以省略,因为mysql的META-INF有个文件帮你加载到内存中了
 */
Class clazz = Class.forName("com.mysql.jdbc.Driver");
Driver driver = (Driver) clazz.newInstance();

/**
 * 注册驱动
 *   也可以省略这步,因为com.mysql.jdbc.Driver类中static静态代码块中已经做了
 */
DriverManager.deregisterDriver(driver);

/**
 * 获取连接
 */
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql", "root", "123456");

综合上面两种获取Connection连接的方式,推荐下面这种:

/**
 * 将数据库连接的基本信息,声明在配置文件中,通过读取配置文件的方式获取连接
 * 读取配置文件中信息
 */
InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties properties = new Properties();
properties.load(inputStream);
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
String driverClass = properties.getProperty("driverClass");

/**
 * 加载驱动
 */
Class.forName(driverClass);

/**
 * 获取连接
 */
Connection connection = DriverManager.getConnection(url, user, password);

3.Connection接口

代表Java程序与特定数据库的连接(会话),在连接上下文中执行 SQL 语句并返回结果

默认情况下,Connection 对象处于自动提交模式下,表示每条执行的SQL语句都是一个单独的事务,执行每个语句后都会自动提交更改,connection.setAutoCommit(false)表示开启事务

常用方法:

3.1connection.getMetaData();

​​​​​​​/**
 * 返回表示数据库的元数据的DatabaseMetaData对象
 */
DatabaseMetaData metaData = connection.getMetaData();
System.out.println("获取驱动版本:"+metaData.getDriverVersion());//mysql-connector-java-5.1.8

3.2connection.createStatement();

/**
 * Statement接口用于执行静态的SQL语句,并返回一个结果对象
 */
Statement statement = connection.createStatement();
/**
 * 如果返回true,则表示所执行的SQL语句有查询结果,比如像执行删除就返回flase
 */
boolean b = statement.execute("select * from dog");
/**
 * 获取查询结果,返回true才有结果
 */
ResultSet resultSet = statement.getResultSet();
while(resultSet.next()){
    int id = resultSet.getInt(1);
    String name = resultSet.getString(2);
    System.out.println("id = "+id+".name = "+name);
}
/**
 * 用于执行SQL中的增,删,改操作,返回受影响的行数
 */
int num = statement.executeUpdate("delete from dog where id = 2");


/**
 * 用于执行SQL中的查询操作,返回查询结果
 */
ResultSet resultSet = statement.executeQuery("select * from dog");

3.3connection.prepareStatement(String sql);

/**
 * PreparedStatement接口用于执行预编译的SQL语句
 */
PreparedStatement preparedStatement = connection.prepareStatement("select * from dog where id = ?");
preparedStatement.setInt(1,4); //设置占位符参数或通过preparedStatement.setObject(1,4)设置
ResultSet resultSet = preparedStatement.executeQuery();
//int num = preparedStatement.executeUpdate(); 该方法用于执行无返回内容的SQL语句,返回受影响的行数

/**
 * PreparedStatement接口实现批量添加
 *   mysql服务器默认是关闭批处理的,我们需要通过一个参数,让mysql开启批处理的支持
 *   ?rewriteBatchedStatements=true 写在配置文件的url后面
 */
String sql = "insert into user(username,password) values('张三',?)";
PreparedStatement statement = connection.prepareStatement(sql);
//设置不允许自动提交数据
connection.setAutoCommit(false);
for (int i = 1; i <= 20000; i++) {
    statement.setObject(1, i);
    //将一组参数添加到此PreparedStatement对象的批处理命令中
    statement.addBatch();
    //不要马上执行
    if (i == 500) {
    //攒到500的时候执行一次,将一批命令提交给数据库执行
        statement.executeBatch();
    //清空当前对象SQL命令列表
        statement.clearBatch();
    }
}
//提交数据
connection.commit();

以前批量执行

connection.setAutoCommit(false);
PreparedStatement statement = connection.prepareStatement("insert into dog(name) values(?)");
for(int i = 0;i<1000;i++){
    statement.setString(1,i+"");
    //执行
    statement.execute();
}
connection.commit();

3.4connection.getTransactionIsolation()

/**
 * 获取数据库的隔离级别
 */
connection.getTransactionIsolation()
/**
 * 更改此Connection对象的事务隔离级别
 * TRANSACTION_READ_COMMITTED
 * TRANSACTION_READ_UMCOMMITTED
 * TRANSACTION_REPEATABLE_READ
 * TRANSACTION_SERIALIZABLE
 */
connection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);

3.5事务操作

什么是提交: 开启事务或者设置不自动提交后,再更新数据的话,数据库中的真实数据是不会有变化的,只是将记录更新到事务日志中,如果想要同步更新到数据库中,我们就需要进行事务提交操作

什么是回滚: 执行回滚,将开启事务之后的一系列操作清空

回滚与不提交区别:  未提交事务都是处于一个临时库中进行,这些临时操作会持续到这个connection结束或提交为止,这些操作虽然看不到,但不同的隔离级别可能会读取到,回滚就是取消这个临时库中的操作

事务结束:  提交,回滚,出现执行错误,或者断电事务结束, 注意如果在同一个Connection连接开启一个新事务,那么新开的事务会将该连接中其他未提交的事务提交,相当于commit

事务案例1:

public class Main {
    public static void main(String[] args){       
            Connection connection = null;
            PreparedStatement preparedStatement = null;
        try {
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456");
            //取消数据自动提交功能
            connection.setAutoCommit(false);

            preparedStatement = connection.prepareStatement("update dog set name = 200 where id = ?");
            preparedStatement.setInt(1,1005);
            preparedStatement.execute();

            //模拟网络异常
            int i = 1/0;

            preparedStatement = connection.prepareStatement("update dog set name = 100 where id = ?");
            preparedStatement.setInt(1,1006);
            preparedStatement.execute();

            System.out.print("转账成功!");
            //提交数据
            connection.commit();
        } catch (Exception e) {
            e.printStackTrace();
            /*
             * 出现异常 回滚数据,回滚也代表事务结束了,如果不回滚数据表中真实数据也没发生改变,因为没有提交,但是未提交事务的部分操作处于临时库中,可能会被其他事务读取到
             */
            try {
                connection.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            //关闭操作,关闭时可能会执行rollback()操作,具体看源码
            try {
                connection.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

事务案例2:

public class Main {
    public static void main(String[] args) throws Exception {
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456");
        connection.setAutoCommit(false);
        try{
            PreparedStatement preparedStatement = connection.prepareStatement("update dog set name = ? where id = ?");
            preparedStatement.setString(1,"aa");
            preparedStatement.setInt(2,1021);
            preparedStatement.execute();
            System.out.println("更新完成1");
            connection.commit();
            //再次执行: 如在同一个Connection中,执行回滚提交等操作,表示当前事务已经结束了,再执行SQL语句表示开启了一个新的事务
            PreparedStatement preparedStatement2 = connection.prepareStatement("update dog set name = ? where id = ?");
            preparedStatement.setString(1,"aa");
            preparedStatement.setInt(2,1022);
            preparedStatement.execute();
            System.out.println("更新完成2");
            connection.commit();

        }catch (Exception e){
            //这里回滚也是回滚上一个提交之后的所有操作
            connection.rollback();
            e.printStackTrace();
        }
    }
}

4.ResultSet接口

用于保存JDBC执行查询时返回的结果集,该结果集封装在一个逻辑表格中

通常在while循环中判断resultSet.next()迭代读取结果集,但ResultSet结果集中的数据也可以指定取出哪行数据

            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery("select * from dog");
            //逐行遍历
            while(resultSet.next()){
                int id = resultSet.getInt(1);
                String name = resultSet.getString(2);
                System.out.println(id+","+name);
            }
            //定位到指定行
            resultSet.absolute(3);
            System.out.println(resultSet.getInt(1)+","+resultSet.getString(2));

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值