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中的类型类名

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值