JDBC【PreparedStatment、批处理、处理二进制、自动主键、调用存储过程、函数】(二)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: PreparedStatement对象继承Statement对象,它比Statement对象更强大,使用起来更简单 Statement对象编译SQL语句时,如果SQL语句有变量,就需要使用分隔符来隔开,如果变量非常多,就会使SQL变得非常复杂。PreparedStatement可以使用占位符,简化sql的编写 Statement会频繁编译SQL。PreparedStatement可对SQL进行预编译,提高效率,预编译的SQL存储在PreparedStatement对象中 PreparedStatement防止SQL注入。【Statement通过分隔符'++',编写永等式,可以不需要密码就

Oracle

下面用JDBC连接Oracle数据库去操作大文本数据和二进制数据

//使用JDBC连接Oracle数据库操作二进制数据
/*
* 对于Oracle数据库和Mysql数据库是有所不同的。
* 1.Oracle定义了BLOB字段,但是这个字段不是真正地存储二进制数据
* 2.向这个字段存一个BLOB指针,获取到Oracle的BLOB对象,把二进制数据放到这个指针里面,指针指向BLOB字段
* 3.需要事务支持
*
* */
public class Demo7 {
    @Test
    public void add() {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            connection = UtilsDemo.getConnection();
            //开启事务
            connection.setAutoCommit(false);
            //插入一个BLOB指针
            String sql = "insert into test4(id,image) values(?,empty_blob())";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1, 1);
            preparedStatement.executeUpdate();
            //把BLOB指针查询出来,得到BLOB对象
            String sql2 = "select image from test4 where id= ? for update";
            preparedStatement = connection.prepareStatement(sql2);
            preparedStatement.setInt(1, 1);
            resultSet = preparedStatement.executeQuery();
            if (resultSet.next()) {
                //得到Blob对象--当成是Oracle的Blob,不是JDBC的,所以要强转[导的是oracle.sql.BLOB包]
                BLOB  blob = (BLOB) resultSet.getBlob("image");
                //写入二进制数据
                OutputStream outputStream = blob.getBinaryOutputStream();
                //获取到读取文件读入流
                InputStream inputStream = Demo7.class.getClassLoader().getResourceAsStream("01.jpg");
                int len=0;
                byte[] bytes = new byte[1024];
                while ((len = inputStream.read(bytes)) > 0) {
                    outputStream.write(bytes, 0, len);
                }
                outputStream.close();
                inputStream.close();
                connection.setAutoCommit(true);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            UtilsDemo.release(connection, preparedStatement, null);
        }
    }
    @Test
    public void find() {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            connection = UtilsDemo.getConnection();
            String sql = "SELECT * FROM test4 WHERE id=1";
            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();
            if (resultSet.next()) {
                //获取到BLOB对象
                BLOB blob = (BLOB) resultSet.getBlob("image");
                //将数据读取到磁盘上
                InputStream inputStream = blob.getBinaryStream();
                FileOutputStream fileOutputStream = new FileOutputStream("d:\\zhongfucheng.jpg");
                int len=0;
                byte[] bytes = new byte[1024];
                while ((len = inputStream.read(bytes)) > 0) {
                    fileOutputStream.write(bytes, 0, len);
                }
                inputStream.close();
                fileOutputStream.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            UtilsDemo.release(connection, preparedStatement, null);
        }
    }
}

对于JDBC连接Oracle数据库操作CLOB数据,我就不再重复了,操作跟BLOB几乎相同


4.获取数据库的自动主键列

为什么要获取数据库的自动主键列数据?

应用场景:

有一张老师表,一张学生表。现在来了一个新的老师,学生要跟着新老师上课。

我首先要知道老师的id编号是多少,学生才能知道跟着哪个老师学习【学生外键参照老师主键】。

    @Test
    public void test() {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            connection = JdbcUtils.getConnection();
            String sql = "INSERT INTO test(name) VALUES(?)";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1, "ouzicheng");
            if (preparedStatement.executeUpdate() > 0) {
                //获取到自动主键列的值
                resultSet = preparedStatement.getGeneratedKeys();
                if (resultSet.next()) {
                    int id = resultSet.getInt(1);
                    System.out.println(id);
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, preparedStatement, null);
        }

5.调用数据库的存储过程

调用存储过程的语法:

    {call <procedure-name>[(<arg1>,<arg2>, ...)]}

调用函数的语法:

    {?= call <procedure-name>[(<arg1>,<arg2>, ...)]}

如果是Output类型的,那么在JDBC调用的时候是要注册的。如下代码所示:

/*
    jdbc调用存储过程
    delimiter $$
        CREATE PROCEDURE demoSp(IN inputParam VARCHAR(255), INOUT inOutParam varchar(255))
        BEGIN
            SELECT CONCAT('zyxw---', inputParam) into inOutParam;
        END $$
    delimiter ;
*/
//我们在JDBC调用存储过程,就像在调用方法一样
public class Demo9 {
    public static void main(String[] args) {
        Connection connection = null;
        CallableStatement callableStatement = null;
        try {
            connection = JdbcUtils.getConnection();
            callableStatement = connection.prepareCall("{call demoSp(?,?)}");
            callableStatement.setString(1, "nihaoa");
            //注册第2个参数,类型是VARCHAR
            callableStatement.registerOutParameter(2, Types.VARCHAR);
            callableStatement.execute();
            //获取传出参数[获取存储过程里的值]
            String result = callableStatement.getString(2);
            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                connection.close();
                callableStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

参考资料:

----------------------------------------------------------------------------------过程
#修改mysql语句的结果符为//
mysql > delimiter //
#定义一个过程,获取users表总记录数,将10设置到变量count中
create procedure simpleproc(out count int)
begin
    select count(id) into count from users;
end
//
#修改mysql语句的结果符为;
mysql > delimiter ;
#调用过程,将结果覆给变量a,@是定义变量的符号
call simpleproc(@a);
#显示变量a的值
select @a;
//以下是Java调用Mysql的过程
    String sql = "{call simpleproc(?)}";
    Connection conn = JdbcUtil.getConnection();
    CallableStatement cstmt = conn.prepareCall(sql);
    cstmt.registerOutParameter(1,Types.INTEGER);
    cstmt.execute();
    Integer count = cstmt.getInt(1);
    System.out.println("共有" + count + "人");
----------------------------------------------------------------------------------函数
#修改mysql语句的结果符为//
mysql > delimiter //
#定义一个函数,完成字符串拼接
create function hello( s char(20) ) returns char(50) 
return concat('hello,',s,'!');
//
#修改mysql语句的结果符为;
mysql > delimiter ;
#调用函数
select hello('world');
//以下是Java调用Mysql的函数
    String sql = "{? = call hello(?)}";
    Connection conn = JdbcUtil.getConnection();
    CallableStatement cstmt = conn.prepareCall(sql);
    cstmt.registerOutParameter(1,Types.VARCHAR);
    cstmt.setString(2,"zhaojun");
    cstmt.execute();
    String value = cstmt.getString(1);
    System.out.println(value);
    JdbcUtil.close(cstmt);
    JdbcUtil.close(conn);
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
SQL Java 关系型数据库
[Mysql]JDBC篇, DAO, DBUtils, 批处理, 数据库池
面向接口编程是一种抽象的, 高效的编程思想 (就像Java里面的多态的思想. 解耦合) 解耦合 : 降低程序的耦合度(乐高坏了只需要换一个零件, 不香?), 提高程序的扩展力(比如多态) SUN公司写了一个接口 各大厂商对这个接口进行实现 这个接口实现了"多态"的编程思想 面向接口编程的程序员只需要调用JDBC即可 底层的实现是厂商写的代码, 程序员也不用去关心 厂商写的实现接口的.class文件, 也是驱动(Driver) 数据库驱动都是以.jar包的形式存在, .jar包当中有很多.class文件, 它们实现了JDBC接口
|
SQL Java 数据库连接
Java JDBC中的批处理SQL语句的详解
Java JDBC中的批处理SQL语句的详解
155 0
|
SQL Java 关系型数据库
JDBC 事务和批处理 详解(通俗易懂)
JDBC 第四节 事务和批处理详解!
312 0
|
存储 Java 关系型数据库
Java使用JDBC向数据库存取二进制数据(如图片,视频,音频等)
Java使用JDBC向数据库存取二进制数据(如图片,视频,音频等)
392 0
Java使用JDBC向数据库存取二进制数据(如图片,视频,音频等)
|
SQL Java 数据库连接
【JDBC】连接数据库,执行批处理操作。
学习连接数据库,执行批处理操作。
264 0
【JDBC】连接数据库,执行批处理操作。
|
SQL 缓存 Java
【JDBC】事务,批处理
1.JDBC事务概述 开启事务的关键代码是conn.setAutoCommit(false),表示关闭自动提交。提交事务的代码在执行完指定的若干条SQL语句后,调用conn.commit()。要注意事务不是总能成功,如果事务提交失败,会抛出SQL异常(也可能在执行SQL语句的时候就抛出了),此时我们必须捕获并调用conn.rollback()回滚事务。最后,在finally中通过conn.setAutoCommit(true)把Connection对象的状态恢复到初始值。
111 0
|
1月前
|
Java 关系型数据库 MySQL
mysql5.7 jdbc驱动
遵循上述步骤,即可在Java项目中高效地集成MySQL 5.7 JDBC驱动,实现数据库的访问与管理。
171 1
|
1月前
|
SQL 分布式计算 关系型数据库
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
87 0
|
1月前
|
SQL 分布式计算 关系型数据库
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
40 0
|
1月前
|
SQL 分布式计算 关系型数据库
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
48 0
下一篇
无影云桌面