菜鸟学JDBC(三)

上一篇( http://blog.csdn.net/rowandjj/article/details/8918291)我们写了一个工具类,封装了一些比较频繁的操作,如注册驱动,建立连接,释放资源等。另外我们还简单介绍了一下Statement和preparedStatement的区别。
这次呢,我们学习简单的增删改查以及对不同类型数据的处理。
请看增删改查的例子:
package biogDemo;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import demo.JDBCUtils;
public class BasicOperation
{
    private static Connection conn = null;
    private static PreparedStatement ps = null;
    private static ResultSet rs = null;
    
    public static void main(String[] args) throws SQLException
    {
        // TODO 自动生成的方法存根
        conn = JDBCUtils.getConnection();
        create();
        delete();
        update();
        read();
        JDBCUtils.free(rs, ps, conn);
    }
//    创建
    public static void create() throws SQLException
    {
        String sql_1 = "insert into tb_11 values (?,?,?)";
        ps = conn.prepareStatement(sql_1);
        ps.setInt(1,2);
        ps.setString(2,"sjjhong");
        ps.setFloat(3,100f);
        ps.execute();
        
        /* 如果第一个结果是 ResultSet 对象,则返回 true;如果第一个结果是更新计数或者没有结果,则返回 false */
    }
//    删除
    public static void delete() throws SQLException
    {
        String sql_2 = "delete from tb_11 where id = ?";
        ps = conn.prepareStatement(sql_2);
        ps.setInt(1,2);
        
        ps.execute();
    }
//更新    
    public static int update() throws SQLException
    {
        String sql_3 = "update tb_11 set money = money + ?";
        ps = conn.prepareStatement(sql_3);
        ps.setFloat(1,100f);
        int result = ps.executeUpdate();
        return result;
    }
//    查找
    public static void read() throws SQLException
    {
        String sql_4 = "select id,name,money from  tb_11 where id >= ?";
        ps = conn.prepareStatement(sql_4);
        ps.setInt(1,1);
        rs = ps.executeQuery();
        int count = rs.getMetaData().getColumnCount();
        while(rs.next())
        {
            for(int i = 1;i <= count ;i++)
            {
                System.out.print(rs.getObject(i) + " ");
            }
            System.out.println("\n");
        }
    }
} 

可以看到,增删改查的操作有很多共性,比如都需要创建一个preparedStatement,并传入一个sql语句,如果sql语句中有通配符,还得用set方法替换。如果是查询语句,执行executeQuery方法会返回一个ResultSet结果集,我们可以对结果集进行遍历。
下面我们看一下 几种特殊且比较常用的类型:
1.BLOB类型:
咱们看看mysql中的blob类型吧,书上是这样描述的:BLOB是一个二进制大对象,用来存储可变数量的数据。BLOB类型分为四种,TINYBLOB,BLOB,MEDIUMBLOB和LONGBLOB。他们的区别就是可容纳值的
最大长度不同。(具体请查阅资料0.0)
再来看看文档:
可见,Blob是一个接口,用来存储大的二进制对象,比如图片,视频等。
Blob类提供一系列操作blob对象的方法,我们重点看以下几个方法:
 
 
 
 
 
以上方法可以以流的形式获取或者重写blob中的内容。那么我们如何用jdbc在数据库表中添加一个blob类型的变量呢?
文档提示我们看ResultSet、CallableStatement、PreparedStatement这几个类,以下就是这几个类提供的方法:
PreparedStatement类:
CallableStatement类:
 
ResultSet类:
 
下面我们用个例子使用一下上面的方法吧:
在数据库表中添加一个存放图片的blob对象,并读取出来
需先建立一张表,sql语句如下:
create table tb_13(
id INT,
jpg BLOB
);
代码如下:
package demo;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class BlobDemo
{
    public static void main(String[] args) 
    {
        try
        {
//            insert();
            read();
        }
        catch (Exception e)
        {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
    }
    public static void insert() throws FileNotFoundException
    {
        Connection conn = null;
        ResultSet rs = null;
        PreparedStatement ps = null;
        
        String sql = "insert into tb_13(id,jpg) values (?,?)";
        File file = new File("src\\demo\\binary_data.jpg");
        try
        {
            conn = JDBCUtils.getConnection();//建立连接
            ps = conn.prepareStatement(sql);//创建语句
            ps.setInt(1,1);
            ps.setBinaryStream(2,new FileInputStream(file),file.length());//替换占位符为流对象中的内容
            
            ps.executeUpdate();//执行语句
            
            System.out.println("insert success...");
        }
        catch (SQLException e)
        {
            // TODO: handle exception
            System.out.println("insert failed...");
            e.printStackTrace();
        }
        finally
        {
            JDBCUtils.free(rs, ps, conn);
        }
    }
    public static void read()
    {
        Connection conn = null;
        ResultSet rs = null;
        PreparedStatement ps = null;
        
        String sql = "select id,jpg from tb_13 where id = ?";
        
        try
        {
            conn = JDBCUtils.getConnection();
            ps = conn.prepareStatement(sql);
            ps.setInt(1,1);
            BufferedOutputStream bufo = 
                    new BufferedOutputStream(new FileOutputStream("src\\demo\\blobData.jpg"));
            rs = ps.executeQuery();
            
            if(rs.next())//处理结果集---->这里已经明确结果集的大小为0或者1,故用if
            {
                Blob blob = rs.getBlob("jpg");//通过getBlob方法获取Blob对象
                BufferedInputStream bufi = 
                        new BufferedInputStream(blob.getBinaryStream());//封装inputStream对象
                byte[] buffer = new byte[1024];
                int len = 0;
                while((len = bufi.read(buffer)) != -1)
                {
                    bufo.write(buffer,0, len);//写入文件
                    bufo.flush();
                }
                bufo.close();
                bufi.close();
                
                System.out.println("read success....");
            }
        }
        catch (SQLException | IOException e)
        {
            // TODO: handle exception
            System.out.println("read failed...");
            e.printStackTrace();
        }
        finally
        {
            JDBCUtils.free(rs, ps, conn);
        }
    }
} 
2.clob类型:
mysql中并没有clob类型(各数据库不一样),与之对应的类型叫TEXT,Text同样也分为四种类型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT
,可以用来存储大的非二进制字符串。
同样的,我们来看文档中对Clob类的描述:
从上可知,Blob和Clob类非常相像,进一步查阅文档会发现连方法都差不多,这里请读者自己通过查找ResultSet、CallableStatement、PreparedStatement类来熟悉方法,限于篇幅,我这里就不贴了。下面对应地,我们用一个例子来使用一下这个类:
仿照上面的例子,咱们在数据库中建立一个表,存储Text类型的数据,然后用jdbc的api实现插入和读取操作。
建表:
create table tb_14(
id INT,
content TEXT
);
代码如下:
package demo;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Reader;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
public class ClobDemo
{
    /**
     * @param args
     */
    public static void main(String[] args)
    {
        // TODO 自动生成的方法存根
//        insert();
        read();
    }
    public static void insert()
    {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        
        String sql = "insert into tb_14(id,content) values (?,?)";
        File file = new File("src\\demo\\clobDemo.java");
        try
        {
            conn = JDBCUtils.getConnection();
            ps = conn.prepareStatement(sql);
            
            ps.setInt(1,1);
            ps.setCharacterStream(2,new FileReader(file), file.length());
            
            ps.execute();
            System.out.println("insert success...");
            
        }
        catch (SQLException | FileNotFoundException e)
        {
            System.out.println("insert failed...");
            // TODO: handle exception
            e.printStackTrace();
        }
        finally
        {
            JDBCUtils.free(rs,ps, conn);
        }
    }
    public static void read()
    {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        
        String sql = "select id,content from tb_14 where id = ?";
        String columnLabel = "content";
        
        try
        {
            conn = JDBCUtils.getConnection();
            ps = conn.prepareStatement(sql);
            
            ps.setInt(1, 1);
            rs = ps.executeQuery();//执行查询语句
            
            ResultSetMetaData rsmd = rs.getMetaData();//获取结果集元数据对象
            
//            BufferedWriter bufw = 
//                    new BufferedWriter(new FileWriter("src\\demo\\ClobDemo_cpy.java"));
            
            PrintWriter pw = new PrintWriter(new File("src\\demo\\ClobDemo_cpy.txt"));//用打印流换行较方便
            
            String line = null;
            if(rs.next())
            {
                for(int i = 0; i< rsmd.getColumnCount(); i++)//遍历表中的各列
                {        
                    if(rsmd.getColumnName(i+1).equals(columnLabel))//如果该列的名字等于columnLabel的值,则进入if语句
                    {
                        Clob clob = rs.getClob(columnLabel);//通过getClob方法获取clob对象
                        Reader re = clob.getCharacterStream();//通过Clob对象的getCharacterStream方法获取流
                        BufferedReader bufr = new BufferedReader(re);//封装流
                        while((line = bufr.readLine()) != null)
                        {
//                            bufw.write(line);//写入文件
//                            bufw.flush();
                            pw.println(line);
                            pw.flush();//这里需要刷新
                        }
//                        bufw.close();
                        bufr.close();
                        System.out.println("read success...");
                    }
                }
            }
        }
        catch (SQLException | IOException e)
        {
            // TODO: handle exception
            System.out.println("read failed...");
            e.printStackTrace();
        }
        finally
        {
            JDBCUtils.free(rs,ps, conn);
        }
        
    }
} 

3.日期类型
在JDBC连接数据的过程中,我们还时常会遇到日期的问题。
例如,假设birthday是封装在Person对象中的一个Date类型的属性,在执行向数据库中插入数据的命令:“insert into users (id,name,sex,age,birthday) values(?,?,?,?,?);”我们接下来要做的就是为这其中每一个占位符赋值,我们用预处理语句

PreparedStatementps = null;

ps.setInt(1, m.getId());

ps.setString(2,m.getName());

ps.setString(3,m.getSex());

ps.setInt(4,m.getAge());

这样我们就完成了对于前四位占位符的赋值操作,那么,我们如何为具有特殊类型的占位符birthday赋值呢?

由于在MySQL数据库中,birthday字段的类型是Date类型的,所以,我们在保证数据类型的一致性问题上就得进行考虑,否则就会导致程序出错,数据不能添加到数据库中。

这里,介绍两种保险的赋值方式:

情况1、

将Person类中birthday的类型定义为String类型,这样我们只需在设置birthday字段的占位符的值时,只需将其设置为ps.setString(5,m.getBirthday());即可。

情况2、

在为Person中birthday属性设置类型时将其强制设置为java.sql.Datebirtthday即可。

这样我们在为birthday字段的占位符的值时,只需将其设置为ps.setString(5, java.sql.Date.valueOf("1991-10-13"));即可因为在java.sql.Date中的valueOf()方法可以将 JDBC 日期转义形式的表示 "yyyy-mm-dd" 形式的日期的字符串转换成Date 值。

这样,我们就不会出现由于数据类型不一致导致的数据无法插入到数据库中的问题了。

以上就是本篇的内容了,下一篇我们介绍JDBC中的元数据,事务处理,批量插入,隔离级别等内容。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值