JDBC-基础篇

1.执行JDBC 执行SQL的整体流程:
① 加载驱动:Class.forName(“……”)//注意tty…catch
② 获取连接:DriverManager.getConnection(url,psw,psw);
③ 创建Statement/PreparedStatement:con.createStatement();或者con.prepareStatement(sql,…,…);
④ 执行SQL语句: (PreparedStatement )pret.setString(index,value);pret.executeQuery();pret.executeUpdate(); (Statement)stmt.executeUpdate(sql)/stmt.executeQuery(sql);
⑤ 如果是Query,返回结果集Result,对结果集进行处理,如果是Update,返回SQL语句影响数据条数。
⑥ 关闭连接释放资源。
2.对Connection的处理:
主要有三个:
①  设置自动提交:con.setAutoCommit(false);
②  提交:con.commit();
③  回滚:con.rollback();
④  关闭:con.close();
3.对Statement的处理:
主要有三种处理:查询、修改(增删改)、批处理:
 查询:
stmt.executeQuery(sql);//sql为SQL语句
 修改:
stmt.executeUpdate(sql);//sql为SQL语句
 批处理:
stmt.addBatch(sql);//sql为单条SQL语句
stmt.executeBatch();
注意:Statement使用完后需要关闭:stmt.close();
4.对PreparedStatement的处理
PreparedStatement运行的速度比Statement快,使用方式也比Statement繁琐。网上有评论说稍微有点经验的程序员都应该不使用Statement而使用PreparedStatement。
首先从PreparedStatement的创建讲起:
PreparedStatement的创建主要有两种方式:
prepareStatement(String sql) sql通常是由占位符‘?’的sql语句

prepareStatement(String sql, int resultSetType, int resultSetConcurrency)

resultSetType是结果集类型,
static int TYPE_FORWARD_ONLY
The constant indicating the type for a ResultSet object whose cursor may move only forward.
static int TYPE_SCROLL_INSENSITIVE
The constant indicating the type for a ResultSet object that is scrollable but generally not sensitive to changes to the data that underlies the ResultSet.
static int TYPE_SCROLL_SENSITIVE
The constant indicating the type for a ResultSet object that is scrollable and generally sensitive to changes to the data that underlies the ResultSet.
1.TYPE_FORWORD_ONLY,只可向前滚动;
2.TYPE_SCROLL_INSENSITIVE,双向滚动,但不及时更新,就是如果数据库里的数据修改过,并不在ResultSet中反应出来。
3.TYPE_SCROLL_SENSITIVE,双向滚动,并及时跟踪数据库的更新,以便更改ResultSet中的数据。

resultSetConcurrency:结果集并发性。
static int CONCUR_READ_ONLY
The constant indicating the concurrency mode for a ResultSet object that may NOT be updated.
static int CONCUR_UPDATABLE
The constant indicating the concurrency mode for a ResultSet object that may be updated.

设置对象:
 设置普通对象:
在SQL语句中,一些对象都可以转化成字符串的形式,如 int(一类)、char(一类),处理这些数据的时候就可以笼统得写作:pret.setString(index,(String)value);
 设置空值:
pret.setNull(index,type);//type为类型的Type,记录在java.sql.Types里面
 设置大对象:
pret.setBlob(int parameterIndex, Blob x) ;//并不常用
pret.setBlob(int parameterIndex, InputStream inputStream, long length);//联系中使用的是这种方式具体情况: pret.setBlob(index,new FileInputStream(new file(filename)),new File(filename).length);
读取Blob:
Blob b = (Blob)rs.getBlob(index);
InputStream fin = b.getBinaryStream();
FileOutputStream fout = new FileOutputStream(f);
int by ;
while((by=fin.read())!=-1){
fout.write(by);
}
fout.close();
fin.close();
从上面的代码中可以看出,Blob是字节流对象,查看Blob时需要将Blob写到本地磁盘上,之后才能进行下一步处理
setClob(int parameterIndex, Clob x) ;
setClob(int parameterIndex, Reader reader, long length) ;
从形式上看,设置Clob对象的方式与设置Blob对象的方式基本相同,唯一不同的就是,Blob是字节流(Binary Large OBjects),Clob是字符流(Character Large OBjects),因为Clob是字符流,所以在查询的过程中也会将Clob当做字符串来处理。参考如下代码:(注: POSSTR(arg1,arg2)的含义是找出arg2在arg1中出现的位置)
public static void main(String[] args) throws Exception{
final String url = “jdbc:db2:sample”;
final String user = “db2admin”;
final String psw = “db2admin”;
Connection con = DriverManager.getConnection(url,user,psw);
String resume = null;
String empnum = “000130”;
int startper=0, startper1, startdpt = 0;
PreparedStatement stmt1, stmt2, stmt3 = null;
String sql1, sql2, sql3 = null;
String empno, resumefmt = null;
Clob resumelob = null;
ResultSet rs1, rs2, rs3 = null;

                     sql1 = "SELECT POSSTR(RESUME,'Personal') " 
                              + "FROM EMP_RESUME " 
                              + "WHERE EMPNO = ? AND RESUME_FORMAT = 'ascii'  "; 
                     stmt1 = con.prepareStatement (sql1); 
                     stmt1.setString ( 1, empnum); 
                     rs1 = stmt1.executeQuery(); 
                     while (rs1.next()) { 
                        startper = rs1.getInt(1); 
                      }  // end while 





        sql2 = "SELECT POSSTR(RESUME,'Department') " 

                                   + "FROM EMP_RESUME " 

                                   + "WHERE EMPNO = ? AND RESUME_FORMAT = 'ascii'  "; 

                          stmt2 = con.prepareStatement (sql2); 

                          stmt2.setString ( 1, empnum); 
                         rs2 = stmt2.executeQuery(); 

                         while (rs2.next()) { 

                            startdpt = rs2.getInt(1); 

                          }  // end while 




        startper1 = startper - 1; 
                    sql3 = "SELECT EMPNO, RESUME_FORMAT,               " 
                             + "SUBSTR(RESUME,1,?)|| SUBSTR(RESUME,?) AS RESUME                  " 
                             + "FROM EMP_RESUME " 
                             + "WHERE EMPNO = ? AND RESUME_FORMAT = 'ascii'  "; //对字符进行截取,并组成新的Clob
                    stmt3 = con.prepareStatement (sql3); 
                    stmt3.setInt (1, startper1); 
                    stmt3.setInt (2, startdpt); 
                    stmt3.setString ( 3, empnum); 
                    rs3 = stmt3.executeQuery(); 
                   while (rs3.next()) { 
                      empno = rs3.getString(1); 
                      resumefmt = rs3.getString(2); 
                      resumelob = rs3.getClob(3); 
                      long len = resumelob.length(); 
                      int len1 = (int)len; 
                      String resumeout = resumelob.getSubString(1, len1); 
          System.out.println(empno +"\t"+resumefmt   +"\t"+resumeout );
                    }  // end while 

    con.commit();
    stmt1.close();
    stmt2.close();
    stmt3.close();
    con.close();
}

         显然,在处理Clob对象的过程中,我们把它当做字符串处理了。

最后,记得关闭pret.close();

5.对ResultSet的处理
① 获取:
ResultSet rs = pret.executeQuery();//PreparedStatement获取ResultSet对象PreparedStatement一般会预先设置好sql语句
ResultSet rs = stmt.executeQuery(sql);//Statement获取ResultSet对象Statement需要设置sql语句
② 访问(遍历):值得注意的是,从前往后遍历的时候,rs的游标指向数据开始的一条空行上;从前往后遍历的时候,rs的游标指向数据结束的一条空行上;
访问实例:
rs.first();//指向第一行数据
rs.previous();
while (rs.next()) {
startper = rs.getInt(1);
}
rs.last();//指向最后一行数据
rs.next();
while (rs.previous())) {
startper = rs.getInt(1);
}

其它:rs.get*()获得数据,比较懒的办法就是rs.getObject();将结果集中的对象都转成Object,处理交给之后的程序。
注意:访问空值方式如下:
        Rs.get*(i);//先移动到要访问的列
        Rs.wasNull();//返回Boolean,表示当前列是不是空值

③ 关闭:rs.close();
④ 对数据的操作:使用sql语句对数据经行操作的方式较为繁琐(繁琐在编写sql语句,效率也较低),rs对数据的操作还算简单,给人的感觉就是在修改一张表。
a. 移动:rs.absolute(index);//移动到index(从1开始)所指的那条数据。
b. 修改:
Rs.update*(index,value);//index为列的编号(从1开始)
或者rs.update*(label,value);//label为字符串,是列名,
最后落实更新:rs.updateRow();
取消更新:rs.cancelRowUpdates();
c. 添加:
移动到新加行:rs.moveToInsertRow() ;
然后对新加的行进行更新操作。
落实添加:rs.insertRow();
d. 删除:
移动到要删除的行(a);
执行删除rs.deleteRow();

6.对ResultSetMetaData的处理
ResultSetMetaData是一个很强大的类,可以通过它来获取列名、列的类型(Types),列对应的java中的类等等。
① 获取方式:
ResultSet rs = stmt.executeQuery(“SELECT a, b, c FROM TABLE2”);
ResultSetMetaData rsmd = rs.getMetaData();
② 使用:
a. getColumnCount() Returns the number of columns in this ResultSet object.
b. getColumnName(int column) Get the designated column’s name.
c. getColumnType(int column) Retrieves the designated column’s SQL type
d. getColumnClassName(int column) 获得这一列可能对应的java中的类型类名

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值