Logo

郎哥编程

处理大文本数据

2020-01-16 237

当文本数据内容超过64K字节时,可以称为大文本数据,大文本数据也称为CLOB数据。在MySQL中,提供了LONGTEXT类型的字段用来存储大文本数据。

课程案例shop数据库的goods(产品表)的brief字段就是大文本数据字段,可以存储4G以内的文本数据。写入大文本数据时,需要通过I/O流的方式从文本文件中读取文本内容。

针对大文本数据,PreparedStatement接口提供了如下几个方法用于写入大文本数据:

void   setAsciiStream(int parameterIndex, InputStream x, int length)

该方法将指定的输入流写入数据库文本字段中。参数parameterIndex表示字段所在记录的列号。参数InputStream为输入流。参数length表示输入流的长度。

void   setBinaryStream(int parameterIndex, InputStream x, int length)

该方法将指定的输入流写入数据库的二进制字段中。参数parameterIndex表示字段所在记录的列号。参数InputStream为输入流。参数length表示输入流的长度。

大文本数据写入数据库后,在查询时需要使用ResultSet接口将数据读出来。ResultSet接口提供了如下几个方法用于读取大文本数据:

InputStream    getAsciiStream(int columnIndex)

该方法根据记录的列编号返回文本输入流。参数columnIndex表示结果集当前光标所在行的列号。

InputStream    getAsciiStream(String columnLabel)

该方法根据记录的列名称返回文本输入流。参数columnLabel表示结果集当前光标所在行的列名称。

Clob   getClob(int columnIndex)

该方法根据记录的列编号返回Clob对象。参数columnIndex表示结果集当前光标所在行的列号。

Clob   getClob(String columnLabel)

该方法根据记录的列名称返回Clob对象。参数columnIndex表示结果集当前光标所在行的列名称。

InputStream    getBinaryStream (int columnIndex)

该方法根据记录的列编号返回二进制数据输入流。参数columnIndex表示结果集当前光标所在行的列号。

InputStream    getBinaryStream(String columnLabel)

该方法根据记录的列名称返回二进制数据输入流。参数columnLabel表示结果集当前光标所在行的列名称。

Blob   getBlob(int columnIndex)

该方法根据记录的列编号返回Blob对象(二进制大数据对象)。参数columnIndex表示结果集当前光标所在行的列号。

Blob   getBlob(String columnLabel)

该方法根据记录的列名称返回Blob对象(二进制大数据对象)。参数columnIndex表示结果集当前光标所在行的列名称。

案例1:在goods表中插入一条记录,goods表的brief是LONGTEXT类型字段,该字段的值需要从文本文件读入。

在demo包下新建SqlDemoTest7类。代码如下:

package demo;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
 
 
 
/**
 * @ClassName: SqlDemoTest7
 * @Description: 数据库编程(处理大文本数据)案例1
 * @author 编程训练营
 * @date
 *
 */
 
public class SqlDemoTest7 {
 
    // 定义JDBC加载路径
    static String jdbc = "com.mysql.cj.jdbc.Driver";
    // 定义MySQL数据库的连接地址
    static String mysqlurl = "jdbc:mysql://localhost:3306/shop?serverTimezone=GMT%2B8";
    // 定义MySQL数据库的用户名
    static String username = "root";
    // 定义MySQL数据库的用户名登录密码
    static String password = "~123456q";
 
    /**
     * @Title: main
     * @Description: Java程序入口main方法
     * @param @param args 参数
     *
     * @return void 返回类型 @throws
     * @throws FileNotFoundException
     */
 
    public static void main(String[] args) throws FileNotFoundException {
      
       Connection conn = null;
       PreparedStatement prepartStatement = null;
       try {
           // 加载JDBC驱动
           Class.forName(jdbc);
           // 连接数据库
           conn = DriverManager.getConnection(mysqlurl, username, password);
           if (null != conn) {
              System.out.println(conn);
               // 向shoper表中插入一条记录
              String sql = "insert into goods(id,name,categoryId,photo,shoperId,price,status,createDate,brief)"
                         + "values(?,?,?,?,?,?,?,?,?)";
              // 实例化PreparedStatement对象
              prepartStatement = conn.prepareStatement(sql);
              // 设置id字段的值
              prepartStatement.setString(1,"0001");
              // 设置name字段的值
              prepartStatement.setString(2,"电脑");
              // 设置categoryId字段的值
              prepartStatement.setString(3,"010");
              // 设置photo字段的值
              prepartStatement.setString(4,"");
              // 设置photo字段的值
              prepartStatement.setString(5,"01");
              // 设置price字段的值
              prepartStatement.setDouble(6, 0.0);
              // 设置status字段的值
              prepartStatement.setInt(7, 0);
              // 设置createDate字段的值
              java.util.Date date = new java.util.Date();
              java.sql.Date sqldate = new java.sql.Date(date.getTime());
              prepartStatement.setDate(8,sqldate);
              // 定义一个File对象,准备从文件中读取数据
              File  file = new File("d:" + File.separator + "temp.txt");
              InputStream input = new FileInputStream(file);
              prepartStatement.setAsciiStream(9, input, file.length());
              // 执行SQL语句
              int row  = prepartStatement.executeUpdate();
              if( row == 1 )
              {
                  System.out.println("goods表添加记录成功");
              }
              else
              {
                  System.out.println("goods表添加记录失败");
              }
              prepartStatement.close();
              conn.close();
           } else {
              System.out.println("数据库连接失败");
           }
       } catch (ClassNotFoundException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       } catch (SQLException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       }
 
    }
 
}

执行大文本数据的写入必须使用PreparedStatement接口,PreparedStatement接口的setDate()方法和Statement接口的setDate()方法有所不同,它需要传入java.sql.Date类型的对象。

程序使用FileInputStream将文本文件读取进来,然后通过PreparedStatement接口的setAsciiStream()方法将文件内容写入到对应的大文本字段中。

程序执行结果如下图所示:

 image.png      

                                   

大文本文件写入完成后,在读取数据库记录时,可以使用ResultSet接口的读取大文本数据的方法将文本内容读取出来。

案例2:查询案例1写入的记录,并将记录内容输出到控制台。

在demo包下新建SqlDemoTest8类。代码如下:

package demo;
 
import java.io.InputStream;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.Scanner;
 
/**
 * @ClassName: SqlDemoTest8
 * @Description: 数据库编程(处理大文本数据)案例2
 * @author 编程训练营
 * @date
 *
 */
 
public class SqlDemoTest8 {
 
    // 定义JDBC加载路径
    static String jdbc = "com.mysql.cj.jdbc.Driver";
    // 定义MySQL数据库的连接地址
    static String mysqlurl = "jdbc:mysql://localhost:3306/shop?serverTimezone=GMT%2B8";
    // 定义MySQL数据库的用户名
    static String username = "root";
    // 定义MySQL数据库的用户名登录密码
    static String password = "~123456q";
   
 
    /**
     * @Title: main
     * @Description: Java程序入口main方法
     * @param @param args 参数
     *
     * @return void 返回类型 @throws
     */
 
    public static void main(String[] args) {
      
       Connection conn = null;
       Statement statement = null;
       try {
           // 加载JDBC驱动
           Class.forName(jdbc);
           // 连接数据库
           conn = DriverManager.getConnection(mysqlurl, username, password);
           if (null != conn) {
              System.out.println(conn);
              // 获取表记录数的SQL语句
              String sql = "select * from goods where id='0001'";
              // 实例化Statement对象
              statement = conn.createStatement();
              // 执行SQL查询语句
              ResultSet resultset = statement.executeQuery(sql);
              if (null != resultset) {
                  while( resultset.next() )
                  {
                     // 获取id字段内容
                     String id = resultset.getString("id");
                     // 获取name字段内容
                     String name = resultset.getString("name");
                      // 获取categoryId字段内容
                     String categoryId = resultset.getString("categoryId");
                     // 获取photo字段内容
                     String photo = resultset.getString("photo");
                     // 获取shoperId字段内容
                     String shoperId = resultset.getString("shoperId");
                     // 获取price字段内容
                     BigDecimal price = resultset.getBigDecimal("price");
                     // 获取status字段内容
                     int status = resultset.getInt("status");
                     // 获取createDate字段内容
                     Date createDate = resultset.getDate("createDate");
                     // 读取大文本数据
                     InputStream input = resultset.getAsciiStream("brief");
                     StringBuilder sbuilder = new StringBuilder();
                     Scanner  scanner = new Scanner(input);
                     while( scanner.hasNext() )
                     {
                         sbuilder.append(scanner.next());
                         sbuilder.append("\n");
                     }
                     System.out.printf("-----输出第%d条记录-----\n",resultset.getRow());
                     System.out.println("id:" + id + ";");
                     System.out.println("name:" + name + ";");
                     System.out.println("categoryId:" + categoryId + ";");
                     System.out.println("photo:" + photo + ";");
                     System.out.println("price:" + price.toString() + ";");
                     System.out.println("status:" + status + ";");
                     System.out.println("createDate:" + createDate.toString() + ";");
                     System.out.println("brief:" + sbuilder.toString() + ";");
                     System.out.println("-------------------------------");
                  }
                 
                  resultset.close();
              } else {
                  System.out.println("SQL语句执行失败");
              }
              statement.close();
              conn.close();
           } else {
              System.out.println("数据库连接失败");
           }
       } catch (ClassNotFoundException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       } catch (SQLException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       }
 
    }
 
}

ResultSet的getAsciiStream()会返回与大文本字段对应的输入流InputStream,程序可以通过InputStream来读取大文本字段内容。

程序也可以调用ResultSet接口的getClob()方法来读取大文本字段内容,getClob()方法会返回Clob对象,该对象也包含一个getAsciiStream()方法,用于获取InputStream输入流。Clob是对大文本数据的一个封装操作接口,该接口在java.sql包内,Clob接口具体内容和使用方法可以参考Java API文档。

程序执行结果如下图所示:

image.png

代码在线纠错(通义千问 qwen-max)

支持粘贴多个代码文件,提交后由阿里云通义千问自动分析代码漏洞、语法错误、逻辑问题并给出修改建议。
您已解锁 AI 代码纠错功能,可正常使用!

评论区

登录 后发表评论
暂无评论