java sql 要点大总结

5.7.2 JDBC 要点 
下文为方便理解本章内容所整理的 JDBC 要点,需要指出的是,这一节内容不能代替
专业的 JDBC教材或者参考资料。 
JDBC 要点 

1. 用接口的方式将数据库分成两部分. 一部分是对开发人员提供的编程接口, java.sql.*;第
二部分是给各大厂商, 给他们是驱动接口(java.sql.Driver). 
DriverManager.getConnection(String url, String username, String password). 
java.sql.Connection ==> 实现类, 不是接口. 
class OracleConnection implements java.sql.Connection 
createStatement() -> OracleStatement implements java.sql.Statement 

提供者/调用者 => 工厂模式 => 透明的开发和调用 

2. 一般的 JDBC 项目(增删查改) 
增删改: 能改数据 
INSERT INTO TABLE_NAME [(列 1, 列 2, ...)] VALUES(值 1, 值 2, ...) 
DELETE TABLE_NAME [WHERE 条件子句] 
列名 = 值 AND 列名 LIKE 'beijing%' OR 列 1 = 列 2 
UPDATE TABLE_NAME SET 列 1 = 值 1 , 列 2 = 值 2, ... [WHERE 条件子句] 

查就算是查询 
SELECT *, 或者用列名 FROM [表 1 别名 1, 表 2 别名 1] [WHERE 条件子句] 
两个表的查询: 表 1.id = 表 2.id 或者 别名 1.id = 别名 2.id 
select c.roomName from student s, classroom c where s.id = c.student_id 

1) 把驱动程序加入到 classpath; 
2) 
// 加载驱动程序 
// 方式 a 
new com.mysql.jdbc.Driver(); 
// 方式 b 动态类加载 
try { 
Class.forName("com.mysql.jdbc.Driver"); 
} catch(Exception e) { 


// 打开数据库连接 
try { 
String url = "jdbc:mysql://localhost:3306/test"; 
String username = "root"; 
String password = "";// 空密码可以写成 "" 或者 null 
Connection conn = DriverManager.getConnection(url, username, password); MyEclipse 6 Java开发中文教程 
85   刘长炯著 

// 数据改动用 executeUpdate(String sql) 
Statement stmt = conn.createStatement(); 
// Statement stm = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, 
ResultSet.CONCUR_UPDATABLE);//获得可更新和可滚动的结果集 
String sql = "insert into student values(1, 'student1')"; 

int rows = stmt.executeUpdate(sql);// 返回改动的数据的行数 
   
// 读取数据 executeQuery(String sql) 
sql = "select * from student"; 
   
ResultSet rs = stmt.executeQuery(sql); 

// rs = null; 

while(rs != null && rs.next()) { 
   // 取数据可以根据下标或者列名 
   String studentname = rs.getString(2);// 下标从 1 开始 
   int id = rs.getInt("id");// 根据列名获取 

   byte[] bytes = rs.getBytes("face");// 读取二进制 


// 释放资源 
rs.close(); 
stmt.close(); 
conn.close(); 
} catch(Exception e) { 


代码的问题在于如果中间出现异常, 那么连接资源就不能释放, 解决办法是把变量声
明放在 try-catch 语句之外; 第二把资源释放给放进 finally 里面. 

// 打开数据库连接 
// 声明用到的资源 
Connection conn = null; 
Statement stmt = null; 
ResultSet rs = null; 
try { 
String url = "jdbc:oracle:thin:@hostname:1521:tarena"; 
String username = "openlab"; 
String password = "";// 空密码可以写成 "" 或者 null 
conn = DriverManager.getConnection(url, username, password); MyEclipse 6 Java开发中文教程 
86   刘长炯著 

// 数据改动用 executeUpdate(String sql) 
stmt = conn.createStatement(); 
// Statement stm = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, 
ResultSet.CONCUR_UPDATABLE); 
String sql = "insert into student values(1, 'student1')"; 

int rows = stmt.executeUpdate(sql);// 返回改动的数据的行数 
   
// 读取数据 executeQuery(String sql) 
sql = "select * from student"; 
   
rs = stmt.executeQuery(sql); 

// rs = null; 

while(rs != null && rs.next()) { 
   // 取数据可以根据下标或者列名 
   String studentname = rs.getString(2);// 下标从 1 开始 
   int id = rs.getInt("id");// 根据列名获取 

   byte[] bytes = rs.getBytes("face");// 读取二进制 



} catch(SQLException e) { 
throw new 数据处理失败异常(); 
// throw SQLExeption 
} finally { 
   // 释放资源 
try { 
   rs.close(); 
} catch(Exeption ex) { 
    


try { 
   stmt.close(); 
} catch(Exeption ex) { 
    


try { 
   conn.close(); MyEclipse 6 Java开发中文教程 
87   刘长炯著 
} catch(Exeption ex) { 
    

   
// 简化成 
// close(rs, stmt, conn); 
   


close(ResultSet rs, Statement stmt, Connection conn) { 
   // 释放资源 
try { 
   rs.close(); 
} catch(Exeption ex) { 
    


try { 
   stmt.close(); 
} catch(Exeption ex) { 
    


try { 
   conn.close(); 
} catch(Exeption ex) { 
    


3. 获取结果集中有多少字段及其类型,可以用 rs.getMetaData() 来获取 
ResultSetMetaData 对象, 很多框架就是用这种办法再加上反射来进行自动的属性填充操作
的,例如 Hibernate。 
    ResultSetMetaData 可用于获取关于 ResultSet 对象中列的类型和属性信息的对象。
以下代码片段创建 ResultSet 对象 rs,创建 ResultSetMetaData 对象 rsmd,并使用 
rsmd 查找 rs 有多少列,以及 rs 中的第一列是否可以在 WHERE 子句中使用。 


     ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2"); 
     ResultSetMetaData rsmd = rs.getMetaData(); 
     int numberOfColumns = rsmd.getColumnCount(); 
     boolean b = rsmd.isSearchable(1); 

4. PreparedStatement 的用法 
PreparedStatement 继承自 Statement, 所有的 Statement 能进行的操作这里都可以MyEclipse 6 Java开发中文教程 
88   刘长炯著 
用. 
1) 执行速度优化(预编译) 
2) 简化 SQL 编写 
String sql = "select * from user where username = ?"; 
3) 增加安全性 
SQL 注入攻击 
String sql = "select * from user where username = '" + username + "'"; 
username 输入 1' = '1' or username = '张三 
select * from user where username = '1' = '1' or username = '张三' 

避免方法: a) 过滤用户输入的特殊字符 '' = ' 
username.replaceAll("'", "''"); 
b) 用 PreparedStatement.setString(下标, username) 自动转换输入的字符串为合法
的 SQL 的格式 
用法: 
// 1. 打开 
PreparedStatement pstmt = conn.createPreparedStatement("select * from user where 
username = ? and regdate = ?"); 
// 2. 设置要处理的数据 
pstmt.setString(1, "张三"); 
java.util.Date now = new java.util.Date(); 
pstmt.setDatetime(2, new java.sql.Date(now.getTime()) );// 设置日期 
// 3. 执行查询或者更新 
ResultSet rs = pstmt.executeQuery();// 
rs = pstmt.executeQuery("select * ..:");// 
int rows = pstmt.executeUpdate();// 更新 

3. CallableStatement 用来调用存储过程(了解) 
在 JDBC 中调用已储存过程的语法如下所示。注意,方括号表示其间的内容是可选项;方
括号本身并不是语法的组成部份。 
{call 过程名[(?, ?, ...)]} 

返回结果参数的过程的语法为: 

{? = call 过程名[(?, ?, ...)]} 

不带参数的已储存过程的语法类似: 

{call 过程名} 

示例代码: 

String procedure="{call Operator_login(?,?,?)}"; 
    //注册存储过程 MyEclipse 6 Java开发中文教程 
89   刘长炯著 
    CallableStatement callStmt=conn.prepareCall(procedure); 
    //注册存储过程输出参数的类型 
    callStmt.registerOutParameter(3,java.sql.Types.INTEGER); 
    //提供输入参数的值 
    callStmt.setString(1,this.operatorID); 
    callStmt.setString(2,this.password); 
    //执行存储过程 
    callStmt.execute(); 
    //返回输出参数 
    login_state=callStmt.getInt(3); 


CallableStatement cs = conn.prepareCall("{call ec_get_cust_terms(?)}"); 
cs.setInt(1, custNo); 
rs = cs.executeQuery();

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值