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值 |
可以设置各种值,常用方法仅展示部分。
栗子:查询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();
}
}
程序运行结果:
CLOB=LONGTEXT总是处理字符大对象。(小说)
BLOB=LONGBLOB总是处理二进制大对象。(图片、影视)