JDBC操作大数据文件

    xiaoxiao2021-12-14  20

    在实际的开发过程中,我们可能需要把大文本或者二进制数据存储到数据库中,下面我们一起来学习一个如何使用JDBC向mysql中插入大文本数据。 在数据库中,大数据称为LOB(Large Objects),而LOB可以分为,clob和blob:

    clob用于存储大文本Text

    blob用于存储二进制数据,例如图像、声音、二进制文等

    在mysql中,提供了以下的数据类型来存储clob和blob:

    TINYTEXT(255)、TEXT(64k)、MEDIUMTEXT(16M)、LONGTEXT(4G)TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB

    下面我们开始jdbc操作大数据文本text的例子。

    1 . 新建一个数据库表:

    test/bigtext

    create table bigtext( id int primary key auto_increment, name varchar(20), content MEDIUMTEXT );

    2. 新建一个项目 导入mysql连接驱动包,这里我们要导入最新mysql-connector-java-5.1.40-bin.jar版本,然后准备好数据库配置文件和数据库连接工具类 详见我写的另一篇文章: 自己写一个数据库连接工具类

    3. 实现插入大文本代码

    public static boolean insertBigtext(String name,String path){ Connection conn = null; PreparedStatement pre = null; try{ //获取连接 conn = mysqlConnUtil.getConn(); //获取传输器 pre = conn.prepareStatement("insert into bigtext values(null,?,?)"); pre.setString(1, name); File file = new File(path); pre.setCharacterStream(2, new FileReader(file), file.length()); return pre.executeUpdate() > 1 ? true : false; }catch(Exception e){ e.printStackTrace(); }finally{ mysqlConnUtil.release(conn, pre, null); return false; } }

    这里要注意一个版本的问题,file.length()返回的数据是一个long类型的数据。 而我们查看JDK关于 PreparedStatement接口的方法描述时,可以发现

    //将给定参数设置为给定 Reader 对象,该对象具有给定字符数长度。 //JDK1.2以上支持 void setCharacterStream(int parameterIndex, Reader reader, int length) // 将指定参数设置为给定 Reader 对象,该对象具有给定字符数长度。 //JDK1.6以上支持 void setCharacterStream(int parameterIndex, Reader reader, long length)

    当我们使用较低版本的mysql-connector时,如果不支持jdk1.6,那么就需要对file.length()进行类型转换为int类型,否则会报错。

    4. 准备一个10M大文件,1.txt

    5. 在main函数中调用方法

    public static void main(String[] args) throws Exception { insertBigtext("java jdbc","1.txt"); }

    当我们运行的时候,发现报错了

    com.mysql.jdbc.PacketTooBigException: Packet for query is too large (10886452 > 1048576). You can change this value on the server by setting the max_allowed_packet' variable. at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3675) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2506) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2677) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2549) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861) at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073) at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009) at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5098) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994) at com.chen.Main.Main.insertBigtext(Main.java:34) at com.chen.Main.Main.main(Main.java:78) Packet for query is too large (10886452 > 1048576). You can change this value on the server by setting the max_allowed_packet' variable.

    上面这段错误信息表明,我们程序的Packet 太大了,超出了数据库设置的max_allowed_packet,需要修改一个这个参数。 为什么会出现这个错误呢,当我们的程序向数据库提交sql的时候,是通过一个数据包发送过去的,数据库为了保证安全和稳点,需要设置一个max_allowed_packet来保证用户不能一次性插入过大的数据。 我们在数据库的安装目录找到my.ini,修改max_allowed_packet这个属性的值为64m,重新启动数据库。运行项目: 这个时候又出现了一个新的问题:

    The size of BLOB/TEXT data inserted in one transaction is greater than 10% of redo log size. Increase the redo log size using innodb_log_file_size.

    这是由于mysql默认的数据库innodb数据库引擎。 我们可以使用命令查看数据库使用的引擎

    默认情况下,MySQL 采用 autocommit 模式运行。这意味着,当执行一个用于更新(修改)表的语句之后,MySQL立刻把更新存储到磁盘中,同时记录锁也会被释放。那么事务提交后,在底层做了什么呢? 1. 把事务写入日志缓冲(log buffer),日志缓冲把事务刷新到事务日志. 2. 把事务写入缓冲池(Buffer pool). 数据库默认的innodb_log_file_size过小,导致我们在插入大文本的时候,数据库把事务写入日记缓冲的时候发生了错误。我们修改my.ini 中的innodb_log_file_size = 64M (innodb_log_buffer_size 日志缓冲区大小 ,默认8M,一般不需要设置太大,除非有BLOB字段) 再重启一下数据库,并运行项目,插入数据库成功。

    另外,还有一个问题需要注意一下 以前在进行大文本的插入时,还会发生java内存溢出的问题。这个时候需要配置两个参数,来设置java虚拟机的运行分配内存:

    -Xms64M -Xmx64M -Xmsn Specify the initial size, in bytes, of the memory allocation pool. This value must be a multiple of 1024 greater than 1MB. Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. The default value is chosen at runtime based on system configuration. For more information, see HotSpot Ergonomics Examples: -Xms6291456 -Xms6144k -Xms6m -Xmxn Specify the maximum size, in bytes, of the memory allocation pool. This value must a multiple of 1024 greater than 2MB. Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. The default value is chosen at runtime based on system configuration. For more information, see HotSpot Ergonomics Examples: -Xmx83886080 -Xmx81920k -Xmx80m

    -Xmsn用来设置虚拟机的初始分配内存,也就是最小内存,-Xmxn用来分配虚拟机分配的最大内存

    那么在eclipse中要如何配置这两个参数呢: 我们需要打开Run Configurations中进行arguments设置:

    转载请注明原文地址: https://ju.6miu.com/read-971781.html

    最新回复(0)