Java登陆第十一天——JDBC(三)PreparedStatement、CLOB、BLOB

PreparedStatement

为了避免SQL注入,Java提供了PreparedStatement接口。

PreparedStatement继承Statement。

PreparedStatement通过占位符、预处理SQL的方式比Statement更安全,更效率。

select *  from pon where p_age = ?
//占位符?

常用方法如下:

方法 类型 描述
ResultSet executeQuery() throws SQLException 普通方法 执行DQL操作,返回查询的结果集
int executeUpdate() throws SQLException 普通方法 执行DML操作,返回更新的行数
void setInt(int parameterIndex, int x) throws SQLException 普通方法 为某个占位符设置int值
void setString(int parameterIndex, String x) throws SQLException 普通方法 为某个占位符设置String值

image
可以设置各种值,常用方法仅展示部分。

栗子:查询pon表中年龄等于18岁的所有信息

代码如下:

    public static void main(String[] args) {
        String user = "root";
        String password = "0000";

        try {
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/UserTest?useSSL=false", user, password);
            PreparedStatement statement = connection.prepareStatement("select *  from pon where p_age = ?");
            statement.setInt(1,18);//第 1 个占位符,值为18

            ResultSet resultSet = statement.executeQuery();
            while (resultSet.next()){
                System.out.println(resultSet.getString(1)+","+resultSet.getInt(2));//输出第1、2列的行
            }

            resultSet.close();
            statement.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

程序运行结果:

李四,18

实际开发中,必须要使用PreparedStatement而非statement。

CLOB和BLOB

实际开发中,数据库不可能仅是存储小数据,总是要存储大数据的。

在java.sql包下提供了两个接口:CLOB和BLOB。专门用来对应Mysql中大对象的数据。
(大对象:大数据对象)

Java					Mysql中数据类型
CLOB:处理字符数据。			LONGTEXT:大文本数据(最大保存4G)。
BLOB:处理二进制数据。			LONGBLOB:二进制数据(最大保存4G)。

在Java程序中,如果想要处理这样的大对象,必须要使用PreparedStatement完成。

PreparedStatement提供了以下方法,专门用来写入大数据对象。

方法 类型 描述
void setAsciiStream(int parameterIndex, java.io.InputStream x) throws SQLException 普通方法 将指定的输入流写入到数据库的LONGTEXT字段
void setBinaryStream(int parameterIndex, java.io.InputStream x,long length) throws SQLException; 普通方法 将指定的输入流写入到数据库的LONGBLOB字段

大数据存储到数据库中后,查询时需要用到ResultSet读取数据。

ResultSet中提供了以下方法,专门用来读取大数据对象。

方法 类型 描述
Clob getClob(String columnLabel) throws SQLException 普通方法 根据列名返回CLOB数据
Blob getBlob(String columnLabel) throws SQLException 普通方法 根据列名返回BLOB数据

准备tt表

--usertest库

create table tt(
name varchar(32),
note longtext,
picture longblob
);

处理CLOB数据

CLOB表示大文本数据,在Mysql中用LONGTEXT表示大文本数据。最大数据保存量为4GB。

写入大文本数据

栗子:将本地文件D:\IOtest\xuezhong.txt存储到tt表中,name雪中悍刀行

代码如下:

    public static void main(String[] args) {
        File file = new File("D:" + File.separator + "IOtest" + File.separator + "xuezhong.txt");
        String user = "root";
        String password = "0000";
        try {
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/UserTest?useSSL=false", user, password);
            PreparedStatement statement = connection.prepareStatement("insert into tt values (?,?,?) ");
            //name varchar(32),note longtext,picture longblob
            statement.setString(1,"雪中悍刀行");
            statement.setAsciiStream(2,new FileInputStream(file),file.length());
            statement.setBinaryStream(3,null);
            statement.executeUpdate();
            System.out.println("1");//证明运行到了这里而已,无意义

            statement.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

程序运行结果:

1

读取LONGTEXT数据需要使用ResultSet.getClob()方法。

读取大文本数据

CLOB接口提供了以下常用方法处理大文本数据。

方法 类型 描述
String getSubString(long pos, int length) throws SQLException 普通方法 获取指定范围的字符串(pos从1开始)
void truncate(long len) throws SQLException 普通方法 截取指定长度的大文本

栗子:读取name雪中悍刀行的note

代码如下:

    public static void main(String[] args) {
        File file = new File("D:" + File.separator + "IOtest" + File.separator + "xuezhong.txt");
        String user = "root";
        String password = "0000";
        try {
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/UserTest?useSSL=false", user, password);
            PreparedStatement statement = connection.prepareStatement("select name,note from tt where name = ?");
            //name varchar(32),note longtext,picture longblob
            statement.setString(1,"雪中悍刀行");
            ResultSet resultSet = statement.executeQuery();
            while (resultSet.next()){
                String name = resultSet.getString("name");
                Clob clob = resultSet.getClob("note");
                String str1 = clob.getSubString(1, (int) clob.length());
                System.out.println(name+" ,内容:"+str1);
                System.out.println("===========================================");
                clob.truncate(5);//截取指定长度
                String str2 = clob.getSubString(1, (int) clob.length());//此时大文本长度只有5了
                System.out.println("截取长度后:"+str2);
            }

            resultSet.close();
            statement.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

程序运行结果:

雪中悍刀行 ,内容:北凉王府龙盘虎踞于清凉山,千门万户,极土木之盛。
//...省略
===========================================
截取长度后:北凉王府龙

处理BLOB数据

BLOB表示二进制数据,在Mysql中用LONGBLOB表示二进制数据。最大数据保存量为4GB。

写入二进制数据

栗子:将本地图片D:\IOtest\finger.jpg存储到表tt中,name手指

代码如下:

    public static void main(String[] args) {
        File file = new File("D:" + File.separator + "IOtest" + File.separator + "finger.jpg");
        String user = "root";
        String password = "0000";
        try {
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/UserTest?useSSL=false", user, password);
            PreparedStatement statement = connection.prepareStatement("insert into tt values (?,?,?)");
            //name varchar(32),note longtext,picture longblob
            statement.setString(1,"手指");
            statement.setAsciiStream(2,null);
            statement.setBinaryStream(3,new FileInputStream(file),file.length());
            statement.executeUpdate();
            System.out.println("1");//证明运行到了这里而已,无意义

            statement.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

程序运行结果:

1

读取LONGBLOB数据需要使用ResultSet.getBlob()方法。

读取二进制数据

BLOB接口提供了以下常用方法处理二进制数据。

方法 类型 描述
byte[] getBytes(long pos, int length) throws SQLException 普通方法 获取指定范围的字节数组(pos从1开始)

栗子:读取name手指的picture并保存至本地D:\IOtest\fake-finger.jpg

代码如下:

    public static void main(String[] args) {
        File file = new File("D:" + File.separator + "IOtest" + File.separator + "fake-finger.jpg");
        String user = "root";
        String password = "0000";
        try {
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/UserTest?useSSL=false", user, password);
            PreparedStatement statement = connection.prepareStatement("select name,picture from tt where name=?");
            //name varchar(32),note longtext,picture longblob
            statement.setString(1,"手指");
            ResultSet resultSet = statement.executeQuery();

            if (resultSet.next()){
                Blob blob = resultSet.getBlob("picture");

                FileOutputStream stream = new FileOutputStream(file);//获取文件输出流
                byte[] bytes = blob.getBytes(1, (int) blob.length());//获取字节数组
                stream.write(bytes,0,bytes.length);
                System.out.println("1");

                stream.close();
                resultSet.close();
            }


            statement.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

程序运行结果:
image

CLOB=LONGTEXT总是处理字符大对象。(小说)

BLOB=LONGBLOB总是处理二进制大对象。(图片、影视)

posted @ 2023-11-21 17:21  rowbed  阅读(32)  评论(0编辑  收藏  举报