jdbc setclob mysql_JDBC(二)之JDBC处理CLOB和BLOB及事务与数据库元数据获取

前面大概介绍了JDBC连接数据库的过程,以及怎么操作数据库,今天给大家分享JDBC怎么处理CLOB和BLOB存储图片的事情,以及JDBC怎么去处理事务。怎么在插入数据的时候生成主键返回值

一、JDBC处理CLOB和BLOB数据

1.1、JDBC处理CLOB(在MySQL中是TEXT)

环境:

create table tb_clob_test_1(id int,clob_data text);

前面使用的DButils工具类,用来获取Connection连接和关闭资源。

1)text类型也可以存储字符串

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public voidclobTest_1() {

Connection conn= null;

PreparedStatement pstmt= null;try{

conn=DBUtils.getConn();

String sql= "insert into tb_clob_test(clob_data)values(?)";

pstmt=conn.prepareStatement(sql);

pstmt.setString(1, "hello world");

pstmt.execute();

}catch(SQLException e) {

e.printStackTrace();

}finally{

DBUtils.close(null, pstmt, conn);

}

}

clobTest_1()

2)数据的存入

如果数据只有ASCII,即不能有中文字符和特殊字符:

pstmt.setAsciiStream(1,x);

如果数据包含中文字符或者其他特殊字符:

File file=new File(“xxx”);

FileReader reader=new FileReader(file);

pstmt.setCharacterStream(1,reader,file.length());

pstmt.setCharacterStream(1,new FileReader("D:/java.txt"));

pstmt.setClob(1,new FileReader("D:/java.txt"));

@Testpublic voidclobTest_2() {

Connection conn= null;

PreparedStatement pstmt= null;try{

conn=DBUtils.getConn();

String sql= "insert into tb_clob_test(clob_data)values(?)";

pstmt=conn.prepareStatement(sql);//pstmt.setCharacterStream(1,new FileReader("D:/java.txt"));

pstmt.setClob(1,new FileReader("D:/java.txt"));

pstmt.execute();

}catch(SQLException e) {

e.printStackTrace();

}catch(FileNotFoundException e) {

e.printStackTrace();

}finally{

DBUtils.close(null, pstmt, conn);

}

}

3)数据的获取

直接拿出字符流

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public voidclobSelectTest_1() {

Connection conn= null;

PreparedStatement pstmt= null;

ResultSet rs= null;

PrintWriter writer= null;

BufferedReader bf= null;try{

conn=DBUtils.getConn();

String sql= "select * from tb_clob_test where id = 4";

pstmt=conn.prepareStatement(sql);

rs=pstmt.executeQuery();

writer= new PrintWriter("java.txt.bak");while(rs.next()){int id = rs.getInt(1);

Reader reader= rs.getCharacterStream(2);

bf= newBufferedReader(reader);

String str= null;while ((str=bf.readLine())!=null){

writer.write(str);

writer.write("\r\n");

writer.flush();

}

}

pstmt.execute();

}catch(SQLException e) {

e.printStackTrace();

}catch(FileNotFoundException e) {

e.printStackTrace();

}catch(IOException e) {

e.printStackTrace();

}finally{try{

bf.close();

}catch(IOException e) {

e.printStackTrace();

}try{

writer.close();

}catch(Exception e) {

e.printStackTrace();

}

DBUtils.close(null, pstmt, conn);

}

}

clobSelectTest_1

先拿出Clob,然后转化成字符流

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

resultSet=pstmt.executeQuery();while(res.next()) {

File file= new File("note_bak.txt");

FileWriter fw= newFileWriter(file);

Clob clob= resultSet.getClob(2);

Reader reader=clob.getCharacterStream();char[] cs = new char[1024];int length = 0;while((length = reader.read(cs))!=-1){

fw.write(cs,0, length);

fw.flush();

}

fw.close();

reader.close();

View Code

1.2、JDBC处理BLOB

环境:

create table tb_blob_test_1(id int,blob_data longblob);

1)存储图片

public classBlobDemo_0010 {

@Testpublic voidblobInsert_1(){

Connection conn= null;

PreparedStatement pstmt= null;try{

conn=DBUtils.getConn();

String sql= "insert into tb_blob_test(blob_data)values(?)";

pstmt=conn.prepareStatement(sql);

pstmt.setBinaryStream(1,new FileInputStream("D:/11.jpg"));

boolean execute=pstmt.execute();

System.out.println(execute);

}catch(SQLException e) {

e.printStackTrace();

}catch(FileNotFoundException e) {

e.printStackTrace();

}

}

方式二:

String sql=”insert into tb_blob_test_1(blob_data) values(?)”;

pstmt=conn.prepareStatement(sql);

File file=newFile(“xxx.jpg”);

BufferedInputStream bis=new BufferedInputStream(newFileInputStream(file));

pstmt.setBlob(2,bis);

pstmt.execute();

2)从数据库中读取图片

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public voidblobSelect_1(){

Connection conn= null;

PreparedStatement pstmt= null;try{

conn=DBUtils.getConn();

String sql= "select * from tb_blob_test where id =1";

pstmt=conn.prepareStatement(sql);

ResultSet rs=pstmt.executeQuery();

rs.next();

InputStreamis = rs.getBinaryStream(2);

OutputStream os= new FileOutputStream("D:/blob.jpg");byte[] bs = new byte[1024];int len = -1;while ((len=is.read(bs))!=-1){

os.write(bs,0,len);

}

os.flush();

os.close();

}catch(SQLException e) {

e.printStackTrace();

}catch(FileNotFoundException e) {

e.printStackTrace();

}catch(IOException e) {

e.printStackTrace();

}

}

}

blobSelect_1

二、JDBC中设置事务的隔离级别

在JDBC中一些基本的设置事务的操作

//MySQL设置事务隔离级别,一般不会再JDBC代码中设置,会直接在MySQL服务器中去设置

conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);//在JDBC设置手动提交事务

conn.setAutoCommit(false);

//设置回滚点

sp = conn.setSavepoint();

//事务回滚

conn.rollback(sp);

事务处理具体实例:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public voidtx_test_1(){

Connection conn= null;

PreparedStatement pstmt=null;

Savepoint sp= null;try{

conn=DBUtils.getConn();//MySQL设置事务隔离级别,一般不会再JDBC代码中设置,会直接在MySQL服务器中去设置

conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);//在JDBC设置手动提交事务

conn.setAutoCommit(false);//在转账的时候,先判断源账号的余额是否大于转账金额//判断之前先查询源账户的余额

String sql0 = "select balance from tb_account where id =1";

pstmt=conn.prepareStatement(sql0);

ResultSet rs=pstmt.executeQuery();double balance=0;if(rs.next()){

balance= rs.getDouble(1);

}//转账金额

double much = 1000;//判断余额是否大于转账金额

if(balance

DBUtils.close(rs,pstmt,conn);return;

}

sp=conn.setSavepoint();//张三的余额减去1000

String sql1 = "update tb_account set balance=balance-1000 where id=1";

pstmt=conn.prepareStatement(sql1);

pstmt.executeUpdate();//李四的余额加上1000

String sql2 = "update tb_account set balance=balance+1000 where id=2";//pstmt.executeUpdate(sql2);这是调用父类的方法一样可以

pstmt =conn.prepareStatement(sql2);

pstmt.executeUpdate();

}catch(SQLException e) {try{//conn.rollback();

conn.rollback(sp);

}catch(SQLException e1) {

e1.printStackTrace();

}

e.printStackTrace();

}finally{try{

conn.commit();

}catch(SQLException e) {try{

conn.rollback();

}catch(SQLException e1) {

e1.printStackTrace();

}

e.printStackTrace();

}

DBUtils.close(null,pstmt,conn);

}

}

tx_test_1

三、生成主键返回值

环境:

create tb_pserson_1(id int primary key auto_increment,name varchar(20));

具体步骤:

String sql=”insert into tb_pserson_1(name) values(?)”;

pstmt=conn. prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);

pstmt.executeUpdate();

resultSet=pstmt. getGeneratedKeys();

此时的resultSet里面存放的是刚才插入的那条数据的自动生成的ID。

四、数据库元数据的查看

在我们前面使用JDBC来处理数据库的接口主要有三个,即Connection,PreparedStatement和ResultSet这三个,而对于这三个接口,还可以获取不同类型的元数据,通过这些元数据类获得一些数据库的信息。

元数据(MetaData),即定义数据的数据。打个比方,就好像我们要想搜索一首歌(歌本身是数据),而我们可以通过歌名,作者,专辑等信息来搜索,那么这些歌名,作者,专辑等等就是这首歌的元数据。因此数据库的元数据就是一些注明数据库信息的数据。

① 由Connection对象的getMetaData()方法获取的是DatabaseMetaData对象。

② 由PreparedStatement对象的getParameterMetaData ()方法获取的是ParameterMetaData对象。

③由ResultSet对象的getMetaData()方法获取的是ResultSetMetaData对象。

4.1、DatabaseMetaData

DatabaseMetaData是由Connection对象通过getMetaData方法获取而来,主要封装了是对数据库本身的一些整体综合信息。

例如数据库的产品名称,数据库的版本号,数据库的URL,是否支持事务等等,能获取的信息比较多,具体可以参考DatabaseMetaData的API文档。

DatabaseMetaData data = conn.getMetaData(); //查看当前连接中有关MySQL的系统信息,比如版本号,是否支持事务,数据库名字。

以下有一些关于DatabaseMetaData的常用方法:

·getDatabaseProductName:获取数据库的产品名称

·getDatabaseProductName:获取数据库的版本号

·getUserName:获取数据库的用户名

·getURL:获取数据库连接的URL

·getDriverName:获取数据库的驱动名称

·driverVersion:获取数据库的驱动版本号

·isReadOnly:查看数据库是否只允许读操作

·supportsTransactions:查看数据库是否支持事务

4.2、ParameterMetaData

ParameterMetaData是由PreparedStatement对象通过getParameterMetaData方法获取而来,主要是针对PreparedStatement对象和其预编译的SQL命令语句提供一些信息,

比如像”insert into account(id,name,money) values(?,?,?)”这样的预编译SQL语句,ParameterMetaData能提供占位符参数的个数,获取指定位置占位符的SQL类型等等,功能也比较多,这里不列举完,详细请看有关ParameterMetaData的API文档。

常用方法:

·getParameterCount:获取预编译SQL语句中占位符参数的个数

在我看来,ParameterMetaData对象能用的只有获取参数个数的getParameterCount()方法。

注意:ParameterMetaData许多方法MySQL并不友好支持,比如像获取指定参数的SQL类型的getParameterType方法,如果数据库驱动连接URL只是简单的“jdbc:mysql://localhost:3306/jdbcdemo”那么MyEclipse会抛出SQLException异常,

必须要将URL修改为“jdbc:mysql://localhost:3306/jdbcdemo?generateSimpleParameterMetadata=true”才行。但是像getParameterType等等与其他的方法也没多好用,因为如下面的例子,这些方法好像只会将所有的参数认为是字符串(VARCHAR)类型。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public voidtestParameterMetaData() throws SQLException {

Connection conn= null;

PreparedStatement st= null;

ResultSet rs= null;try{

conn=JdbcUtils.getConnection();

String sql= "insert into user(id,name,age) values(?,?,?)";

st=conn.prepareStatement(sql);

st.setInt(1, 1);

st.setString(2, "Ding");

st.setInt(3, 25);

ParameterMetaData paramMetaData=st.getParameterMetaData();//获取参数个数

int paramCount =paramMetaData.getParameterCount();//以字符串形式获取指定参数的SQL类型,这里有问题

String paramTypeName = paramMetaData.getParameterTypeName(1);//返回指定参数的SQL类型,以java.sql.Types类的字段表示,这里有问题

int paramType = paramMetaData.getParameterType(1);//返回指定参数类型的Java完全限定名称,这里有问题

String paramClassName = paramMetaData.getParameterClassName(1);//返回指定参数的模,,这里有问题

int paramMode = paramMetaData.getParameterMode(1);//返回指定参数的列大小,这里有问题

int precision = paramMetaData.getPrecision(1);//返回指定参数的小数点右边的位数,这里有问题

int scale = paramMetaData.getScale(1);

}

testParameterMetaData

注:完全限定名称,指的是该类型的Java完整名称,包括包名和类型。

结果:

0ea9e0a7395d30c5cdbaec515651a0ef.png

因为我们的SQL语句为"insert into user(id,name,age) values(?,?,?)",而我们所有利用ParameterMetaData查询的信息除了参数个数以外,都是查询第一个参数的信息,也就是“id”列,而这个“id”列我们创建时是int整型的,

但是利用ParameterMetaData的查询结果都是显示为字符串类型,因此我对ParameterMetaData的功能产生了怀疑。

因此在以后使用参数元数据ParameterMetaData尽量只要使用其getParamterCount()方法获取参数个数,对于该对象其他方法请慎用。

4.3、ResultSetMetaData

ResultSetMetaData是由ResultSet对象通过getMetaData方法获取而来,主要是针对由数据库执行的SQL脚本命令获取的结果集对象ResultSet中提供的一些信息,

比如结果集中的列数、指定列的名称、指定列的SQL类型等等,可以说这个是对于框架来说非常重要的一个对象。关于该结果集元数据对象的其他具体功能和方法请查阅有关ResultSetMetaData的API文档。

以下有一些关于ResultSetMetaData的常用方法:

·getColumnCount:获取结果集中列项目的个数

·getColumnType:获取指定列的SQL类型对应于Java中Types类的字段

·getColumnTypeName:获取指定列的SQL类型

·getClassName:获取指定列SQL类型对应于Java中的类型(包名加类名)

实例:

数据表

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

create table user(

idintprimary key,

name varchar(40),

ageint);

insert into user(id,name,age) values(1,'Ding',25);

insert into user(id,name,age) values(2,'LRR',24);

user

测试

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public voidtestResultSetMetaData() throws SQLException {

Connection conn= null;

PreparedStatement st= null;

ResultSet rs= null;try{

conn=JdbcUtils.getConnection();

String sql= "select * from user";

st=conn.prepareStatement(sql);

rs=st.executeQuery();

ResultSetMetaData resultMetaData=rs.getMetaData();//获取结果集的列数

int columnCount =resultMetaData.getColumnCount();//获取指定列的名称

String columnName = resultMetaData.getColumnName(1);//获取指定列的SQL类型对应于java.sql.Types类的字段

int columnType = resultMetaData.getColumnType(1);//获取指定列的SQL类型

String columnTypeName = resultMetaData.getColumnTypeName(1);//获取指定列SQL类型对应于Java的类型

String className= resultMetaData.getColumnClassName(1);//获取指定列所在的表的名称

String tableName = resultMetaData.getTableName(1);

}

testResultSetMetaData

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值