【ORACLE JDBC】Oracle中使用JDBC对CLOB操作,传说中关于666限制问题

19 篇文章 0 订阅
Oracle CLOB  666
package Jdbc;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;



public class JdbcClobTest {
	
    private Connection con;

    /**
     * mflag = true: 传入Connection
     * mflag = false: 不传入Connection
     */
    private boolean mflag = false;


    public void ExeSQL(Connection tConnection)
    {
        con = tConnection;
        mflag = true;
    }

    public void ExeSQL()
    {
    }
    
    /**
     * 内容过长超过4000字符 需要向数据库中插入大对象来保存内容
     * 此方法 提供底层对数据库大对象的操作支持 目前仅支持oracle
     * oracle数据库可以强制把字符串插入到字符大对象中 此方法仅支持更新大对象 
     * TODO 下面封装的操作oracle大对象的方法还需要完善!!!!!!
     * 
     * 输入:预编译sql和需要的参数   在ExeSQL类初始化的时候建立连接。
     * 输出:如果成功执行,返回True,否则返回False,并且在Error中设置错误的详细信息
     * @param sql String
     * @param params String[] 
     * @return boolean
     */
    /**
     * 此方法用于执行对大对象进行操作的sql语句
     * 传入的参数:sql带?号(需要传入参数并且为大对象类型)的sql语句,params参数数组,用params中的元素替换sql中的?号
     */
    public boolean execUpdateClobSQL(String sql, String[] params){
        PreparedStatement pstmt = null;
        StringReader reader = null;
        System.out.println("预编译ExecSQL执行时间:"+new java.util.Date()+"; ExecSQL : " + sql);
        if (!mflag){
            con = DBConn.getConn();
        }
        try{
            pstmt = con.prepareStatement(sql);
            //循环传入的参数数据  将数组内的参数 赋值给 预编译sql
            for (int i = 0; i < params.length; i++) {
            	System.out.println("传入参数:"+params[i]+" 的对象类型:"+params[i].getClass().getName());
            	reader = new StringReader(params[i]);
            	pstmt.setCharacterStream(i+1, reader,params[i].length());
            	System.out.println("reader = " + reader);
    		}
            pstmt.execute();
            pstmt.close();
            if (!mflag){
                con.commit();
                con.close();
            }
        }
        catch (SQLException e){
            // @@错误处理
            System.out.println("### Error ExeSQL at execUpdateSQL: " + sql);

            try{
                if (pstmt != null){
                    //由于描述的问题,导致执行的sql错误百出,因此pstmt的关闭需要特殊处理
                    try{
                        pstmt.close();
                    }
                    catch (SQLException ex){
                        ex.printStackTrace();
                    }
                    finally{
                        try{
                            System.out.println("Sql's bug is very big: " + sql);
                            pstmt.close();
                        }
                        catch (SQLException ex){}
                    }
                }
                if (!mflag){
                    con.rollback();
                    con.close();
                }
            }
            catch (SQLException ex){
                //在这个地方,有可能会没有关闭连接
                ex.printStackTrace();
                return false;
            }
            return false;
        }finally{
        	reader.close();
        	try {
				pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
        }
        return true;
    }
    
    
   /***
    * 
    * 更新oracle的CLOB字段  上面的方法只能做插入带有CLOB的操作  
    * @param sql String  例如:select workjson from tbl_lwprocess where processid = ? for update 
    * @param params String[]   此处为?需要的值 
    * @param toClobString      需要写入大对象字段的字符串
    * @return boolean
    */
    public boolean updateClob(String sql, String[] params, String toClobString){
        PreparedStatement pstmt = null;
		ResultSet rs = null;    
		Writer write = null;
		oracle.sql.CLOB clob = null;   
        //System.out.println("下面是预编译ExecSQL...");
        System.out.println("预编译ExecSQL执行时间:"+new java.util.Date()+"; ExecSQL : " + sql);
        try{
        	if (!mflag){
        		con = DBConn.getConn();
        		con.setAutoCommit(false);
        	}
            pstmt = con.prepareStatement(sql);
          //循环传入的参数数据  将数组内的参数 赋值给 预编译sql modified by guodanlong at 2012-05-28
            for (int i = 0; i < params.length; i++) {
            	System.out.println("传入参数:"+params[i]+" 的对象类型:"+params[i].getClass().getName());
            	pstmt.setObject(i+1, params[i]);
    		}
            rs = pstmt.executeQuery();
            if(rs.next())     
			{     
			   clob = (oracle.sql.CLOB)rs.getClob(1);     
			}     
			write = clob.getCharacterOutputStream();     
			write.write(toClobString);     
			write.flush();     
			write.close();     
			rs.close(); 
            pstmt.close();
            if (!mflag){
                con.commit();
                con.close();
            }
        }
        catch (Exception e){
            // @@错误处理
            System.out.println("### Error ExeSQL at execUpdateSQL: " + sql);

            try{
                if (pstmt != null){
                    //由于描述的问题,导致执行的sql错误百出,因此pstmt的关闭需要特殊处理
                    try{
                        pstmt.close();
                    }
                    catch (SQLException ex){
                        ex.printStackTrace();
                    }
                    finally{
                        try{
                            System.out.println("Sql's bug is very big: " + sql);
                            pstmt.close();
                        }
                        catch (SQLException ex){}
                    }
                }
                if (!mflag){
                    con.rollback();
                    con.close();
                }
            }
            catch (SQLException ex){
                //在这个地方,有可能会没有关闭连接
                ex.printStackTrace();
                return false;
            }
            return false;
        }finally{
        	try {
        		write.close();
				pstmt.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
        }
        return true;
    }
    
    
    /***
     * 支持系统底层获取数据库大对象内容
     * 每次只能获取一个大对象字段的全部内容
     * 后续如有需要获取部分大对象内容请重载此方法
     * 目前仅支持oracle
     * 
     * 预编译sql执行查询,将预编译的sql查询结果返回!
     * @param sql String     //预编译sql
     * @param params Object[]     //预编译sql需要的参数
     * @return String       //返回预编译sql和参数组合后的sql命令执行后的结果集
     * */
    public String execClobSQL(String sql ,Object[] params)
    {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        String clobStr = "";

        System.out.println("预编译ExecSQL执行时间:"+new java.util.Date()+"; ExecSQL : " + sql);
        if (!mflag)
        {
            con = DBConn.getConn();
        }

        try
        {
            pstmt = con.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY
                    , ResultSet.CONCUR_READ_ONLY);
            //循环传入的参数数据  将数组内的参数 赋值给 预编译sql modified by guodanlong at 2012-05-28
            for (int i = 0; i < params.length; i++) {
            	System.out.println("传入参数:"+params[i]+" 的对象类型:"+params[i].getClass().getName());
            	pstmt.setObject(i+1, params[i]);
    		}
            rs = pstmt.executeQuery();
            
            /**
             * 下面将结果集中的大对象流 读出并拼装成字符串返回
             * 如果有记录去取出大对象的内容并处理  
             * 如果有记录 大对象的内容没有 则直接返回
             */
            if (rs.next())    
        	    {    
        	        java.sql.Clob clob = rs.getClob(1);    
        	        if(clob == null){//如果大对象字段为空 则直接返回""字符串
        	        	return clobStr;
        	        }
        	        Reader inStream = clob.getCharacterStream();    
        	        char[] c = new char[(int) clob.length()];    
        	        try {
						inStream.read(c);
						clobStr = new String(c);    
						inStream.close();    
					} catch (IOException e) {
						e.printStackTrace();
					}    
        	        //clobStr是读出并需要返回的数据,类型是String    
        	    }
            
            rs.close();
            pstmt.close();

            if (!mflag)
            {
                con.close();
            }
        }
        catch (SQLException e)
        {
            System.out.println("### Error ExeSQL at execSQL(String sql): " + sql);
            e.printStackTrace();

            // @@错误处理
            try
            {
                if (rs != null)
                {
                    rs.close();
                }
                if (pstmt != null)
                {
                    //由于描述的问题,导致执行的sql错误百出,因此pstmt的关闭需要特殊处理
                    try
                    {
                        pstmt.close();
                    }
                    catch (SQLException ex)
                    {
                        ex.printStackTrace();
                    }
                    finally
                    {
                        try
                        {
                            System.out.println("Sql's bug is very big: " + sql);
                            pstmt.close();
                        }
                        catch (SQLException ex)
                        {}
                    }
                }
                if (!mflag)
                {
                    con.close();
                }
            }
            catch (SQLException ex)
            {
                ex.printStackTrace();
            }
        }

        return clobStr;
    }
    
    public static void main(String[] args) {
    	
    	JdbcClobTest jdbcClobTest=new JdbcClobTest();
    	//查询CLOB字段
    	String cxsql = "select workjson from tbl_lwprocess";
    	String content = jdbcClobTest.execClobSQL(cxsql,new String[] {});
    	System.out.println(content);
    	
    	//插入
		String crsql = "insert into tbl_lwprocess (processid,workjson) values ('001',?) ";
		String[] crparams={"123测试大字符串"};
		jdbcClobTest.execUpdateClobSQL(crsql, crparams);

		content = jdbcClobTest.execClobSQL(cxsql,new String[] {});
    	System.out.println(content);	
    	
    	//更新
    	String gxsql = "select workjson from tbl_lwprocess where 1 = ? for update ";
		String workjson = "{111naasdfasdfasdfasdfasdfasdfasdfme':null,'count':3,'nodes':[{'id':'node_1','name':'0000000010','type':'node','shape':'rect','number':1,'left':100,'top':80,'width':100,'height':40,'property':[{'id':'n_p_name','text':'select','value':'0000000010'}]},{'id':'node_2','name':'0000000003','type':'node','shape':'rect','number':2,'left':145,'top':193,'width':100,'height':40,'property':[{'id':'n_p_name','text':'select','value':'0000000003'}]}],'lines':[{'id':'line_3','name':'001','type':'line','shape':'line','number':3,'from':'node_1','to':'node_2','fromx':150,'fromy':120,'tox':145,'toy':193,'polydot':[],'property':[{'id':'l_p_id','text':'span','value':'line_3'},{'id':'l_p_name','text':'}]}]} f";
		String[] params={"1"};
		jdbcClobTest.updateClob(gxsql, params, workjson);
		
		content = jdbcClobTest.execClobSQL(cxsql,new String[] {});
    	System.out.println(content);
	}
    

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值