java sql

href="file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_filelist.xml" rel="File-List" />

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();

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值