前面大概介绍了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类型也可以存储字符串

public void clobTest_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(, "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"));   

    @Test
public void clobTest_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(,new FileReader("D:/java.txt"));
pstmt.execute();
} catch (SQLException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
DBUtils.close(null, pstmt, conn);
}
}

  3)数据的获取

    直接拿出字符流   

public void clobSelectTest_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();
Reader reader = rs.getCharacterStream();
bf = new BufferedReader(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,然后转化成字符流

resultSet=pstmt.executeQuery();
while (res.next()) {
File file = new File("note_bak.txt");
FileWriter fw = new FileWriter(file);
Clob clob = resultSet.getClob();
Reader reader = clob.getCharacterStream();
char[] cs = new char[];
int length = ;
while((length = reader.read(cs))!=-){
fw.write(cs, , length);
fw.flush();
}
fw.close();
reader.close();

1.2、JDBC处理BLOB 

  环境: 

create table tb_blob_test_1(id int,blob_data longblob);

  1)存储图片 

public class BlobDemo_0010 {

    @Test
public void blobInsert_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(,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=new File(“xxx.jpg”);
BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file));
pstmt.setBlob(,bis);
pstmt.execute();

  2)从数据库中读取图片

public void blobSelect_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();
InputStream is = rs.getBinaryStream();
OutputStream os = new FileOutputStream("D:/blob.jpg");
byte[] bs = new byte[];
int len = -;
while ((len=is.read(bs))!=-){
os.write(bs,,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);

  事务处理具体实例:   

public void tx_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=;
if(rs.next()){
balance = rs.getDouble();
}
//转账金额
double much = ;
//判断余额是否大于转账金额
if(balance<much){
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());

  具体步骤: 

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)类型。

public void testParameterMetaData() 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(, );
st.setString(, "Ding");
st.setInt(, ); ParameterMetaData paramMetaData = st.getParameterMetaData();
//获取参数个数
int paramCount = paramMetaData.getParameterCount();
//以字符串形式获取指定参数的SQL类型,这里有问题
String paramTypeName = paramMetaData.getParameterTypeName();
//返回指定参数的SQL类型,以java.sql.Types类的字段表示,这里有问题
int paramType = paramMetaData.getParameterType();
//返回指定参数类型的Java完全限定名称,这里有问题
String paramClassName = paramMetaData.getParameterClassName();
//返回指定参数的模,,这里有问题
int paramMode = paramMetaData.getParameterMode();
//返回指定参数的列大小,这里有问题
int precision = paramMetaData.getPrecision();
//返回指定参数的小数点右边的位数,这里有问题
int scale = paramMetaData.getScale();
}

testParameterMetaData

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

  结果:

      

  因为我们的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中的类型(包名加类名)

  实例:

    数据表     

create table user(
id int primary key,
name varchar(),
age int
);
insert into user(id,name,age) values(,'Ding',);
insert into user(id,name,age) values(,'LRR',);

user

    测试

public void testResultSetMetaData() 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();
//获取指定列的SQL类型对应于java.sql.Types类的字段
int columnType = resultMetaData.getColumnType();
//获取指定列的SQL类型
String columnTypeName = resultMetaData.getColumnTypeName();
//获取指定列SQL类型对应于Java的类型
String className= resultMetaData.getColumnClassName();
//获取指定列所在的表的名称
String tableName = resultMetaData.getTableName();
}

testResultSetMetaData

JDBC(二)之JDBC处理CLOB和BLOB及事务与数据库元数据获取的更多相关文章

  1. [转载]JDBC读写Oracle的CLOB、BLOB

    JDBC读写Oracle10g的CLOB.BLOB http://lavasoft.blog.51cto.com/62575/321882/ 在Oracle中存取BLOB对象实现文件的上传和下载 ht ...

  2. 十二、JDBC

    day17 JDBC入门 l 导jar包:驱动! l 加载驱动类:Class.forName(“类名”); l 给出url.username.password,其中url背下来! l 使用Driver ...

  3. JDBC二部曲之_入门

    JDBC 1 什么是JDBC? JDBC(Java DataBase Connectivity),即Java数据库连接!也就是说,Java程序员可以使用JDBC API来操作数据库. 最早JDBC是J ...

  4. JAVA基础-JDBC二(常用的开源工具)

    一.连接池 在实际的开发应用中,我们常常会对数据库进行大量的高并发的访问,而最原始的连接和操作方式并不能满足这种大量的访问,程序员为了追求更方便.更快捷.更科学安全的开发.第三方的工具类和Dao层的框 ...

  5. JDBC驱动程序注册 JDBC简介(二)

    使用JDBC进行数据库操作的第一步就是驱动注册(当然你得先导入JAR). 驱动注册有多种方式,第一步必然是获得正确的驱动名称与URL格式 驱动名称与URL格式 RDBMS 驱动程序名称        ...

  6. MySQL 系列(二)Jdbc

    MySQL 系列(二)Jdbc 一.Jdbc 基本操作 import java.sql.Connection; import java.sql.DriverManager; import java.s ...

  7. JavaWeb学习笔记(十二)—— JDBC的基本使用

    一.JDBC概述 1.1 数据库驱动 这里的驱动的概念和平时听到的那种驱动的概念是一样的,比如平时购买的声卡,网卡直接插到计算机上面是不能用的,必须要安装相应的驱动程序之后才能够使用声卡和网卡,同样道 ...

  8. OpenJDK源码研究笔记(十二):JDBC中的元数据,数据库元数据(DatabaseMetaData),参数元数据(ParameterMetaData),结果集元数据(ResultSetMetaDa

    元数据最本质.最抽象的定义为:data about data (关于数据的数据).它是一种广泛存在的现象,在许多领域有其具体的定义和应用. JDBC中的元数据,有数据库元数据(DatabaseMeta ...

  9. Java基础(三十二)JDBC(2)连接数据库

    一.连接数据库的过程 连接数据库的过程:加载数据库驱动程序,不过只需在第一次访问数据库时加载一次,然后在每次访问数据库时创建一个Connection实例,然后执行操作数据库的SQL语句,并返回执行结果 ...

随机推荐

  1. 《深入浅出Netty》【PDF】下载

    <深入浅出Netty>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062563 内容简介 本文档主要讲述的是深入浅出Netty: ...

  2. OC学习16——对象归档

    转载自  OC学习篇之---归档和解挡 OC中的归档就是将对象写入到一个文件中,Java中的ObjectInputStream和ObjectOutputStream来进行操作的.当然在操作的这些对象都 ...

  3. iOS 上线因iPv6被拒,查询服务器是否支持iPv6,mac设置iPv6网络,手机测试iPv6

    一. iOS----如何检查域名是否支持ipv6 iOS----------如何检查域名是否支持ipv6 1.检查你所用到的库,像af 3.0以上什么的(不用改),其他的库自己去搜下是否支持ipv6吧 ...

  4. openstack操作之一 命令行

    在openstack环境中提供了多种操作虚拟机的方法,有最简单直接的dashborad界面,有不直观但高效的命令行,还有进阶版的postman调用openstack restfulapi和命令行中使用 ...

  5. 入门级Nginx反向代理nodejs

    本着想实现前后端分离开发的初衷,我决定学习一下关于nignx反向代理的配置. 1.下载Nginx稳定版本 2.打开nginx配置文件 nginx.conf: 3.在http模块的server部分配置 ...

  6. Oracle数据库中插入日期型数据(to_date的用法)(转载)

    往Oracle数据库中插入日期型数据(to_date的用法) INSERT  INTO  FLOOR  VALUES  ( to_date ( '2007-12-20 18:31:34' , 'YYY ...

  7. Linux(CentOS6.5)下编译Popt报错”GNU gettext is required. The latest version”(gettext已经编译安装,但是没有安装在默认目录)的解决方案

    本文地址http://comexchan.cnblogs.com/,作者Comex Chan,尊重知识产权,转载请注明出处,谢谢!   背景: 编译popt的时候出现下述报错. 直接vi查看confi ...

  8. Python的range函数详细用法

    1. >>> range(1,5)  #代表从1到5(不包含5) [1, 2, 3, 4]>>> 2. >>> range(1,5,2) #代表从 ...

  9. 字符串匹配KMP算法的C语言实现

    字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...

  10. IE下判断IE版本的语句...[if lte IE 8]……[endif]

    <!--[if lte IE 6]> <![endif]--> IE6及其以下版本可见   <!--[if lte IE 7]> <![endif]--> ...