OAF_JDBC系列1 - 数据库交互取值方式(案例)
2014-06-15 Created By BaoXinjian
一、摘要
通过VO和数据库交互
通过OracleStatement和数据库交互
通过OraclePreparedStatement和数据库交互
通过OracleCallableStatement和数据库交互
通过OracleCallableStatement调用存储过程
二、具体解析
1. 通过VO和数据库交互
public void initQuery(String reportName)
{
if ((reportName != null) && (!("".equals(reportName.trim()))))
{
String repName = null;
try
{
repName = new String(reportName); //由String得到一个Number类
} catch (Exception e)
{
throw new OAException("AK", "FWK_TBX_INVALID_EMP_NUMBER");
}
setWhereClause("REPORT_HEADER_ID = :1");
setWhereClauseParams(null); // Always reset
setWhereClauseParam(0, repName);
System.out.println("viktor3 repName=" + repName);
executeQuery();
}
}
}
2. 通过OracleStatement和数据库交互
public void create(AttributeList attributeList)
{
super.create(attributeList);
try
{
OracleConnection conn = (OracleConnection)transaction.getJdbcConnection(); //获取当前连接
OracleStatement stmt = (OracleStatement)conn.createStatement(); //生成语句
OracleResultSet rset = (OracleResultSet)stmt.executeQuery("select msi.segment1 from mtl_system_items_b msi"); //执行查询
while (rset.next()) //向前转移指针
{
setItemDesc(rset.getString(1)); //获取结果集中的第一个字段
break; //假定只取一条记录
}
rset.close(); //关闭结果集
} catch(SQLException ex) {}
//process exception
}
3. 通过OracleStatement和数据库交互
private Map<String, String> getDisplayInst(String supplierClass) throws Exception
{
if (supplierClass == null)
return null;
Map<String, String> ret = null;
OraclePreparedStatement ops = null;
OracleResultSet ors = null;
OADBTransaction trx = null;
trx = this.getOADBTransaction();
ops = (OraclePreparedStatement)trx.createPreparedStatement("SELECT * FROM CUX_SUP_INFO_DISP t WHERE t.supplier_class = ?", -1);
ops.setString(1, supplierClass);
ors = (OracleResultSet)ops.executeQuery();
if (ors.next())
{
ret = new HashMap<String, String>();
for (int i = 1; i <= ors.getMetaData().getColumnCount(); i++)
{
String columnName = ors.getMetaData().getColumnName(i);
ret.put(columnName, ors.getString(columnName));
Logger.debug( "getDisplayInst" + i + "==>" + columnName + ":" + ors.getString(columnName));
}
}
if (ors != null)
{
ors.close();
}
if (ops != null)
{
ops.close();
}
return ret;
}
4. 通过OracleCallableStatement和数据库交互
public void setAllAttribute(){
System.out.println("ExpenseHeaderEOImpl.setAllAttribute");
OADBTransaction transaction = getOADBTransaction();
Number n_report_header_id = transaction.getSequenceValue("BXJ_EXPENSE_REPORT_ID_S");
setReportHeaderId(n_report_header_id);
Number n_employee_id = new Number(25);
String v_sql_getsupervisor = "BEGIN\n" +
" SELECT nvl(supervisor_id, 25)\n" +
" INTO :p_supervisor_id \n" +
" FROM per_all_assignments_f\n" +
" WHERE person_id = :2\n" +
" AND effective_start_date <= sysdate\n" +
" AND effective_end_date > sysdate\n" +
" AND rownum <= 1;\n" +
"END;";
OracleCallableStatement callablestatement
= (OracleCallableStatement)transaction.createCallableStatement(v_sql_getsupervisor, 1);
try{
callablestatement.registerOutParameter(1, OracleTypes.NUMBER);
callablestatement.setNUMBER(2, n_employee_id);
callablestatement.execute();
Number n_supervisor_id = new Number(callablestatement.getNUMBER(1));
setApproveId(n_supervisor_id);
}
catch(Exception bxj_exception){
throw OAException.wrapperException(bxj_exception);
}
finally{
try{
callablestatement.close();
}
catch(Exception bxj_excpetion){
throw OAException.wrapperException(bxj_excpetion);
}
}
}
5. 通过OracleCallableStatement调用存储过程
public String updateVendor(String type, String supplierName,
String rejectReason, String date, String pRecommended, String vendorid)
{
String status = null;
String msg = null;
String sql =
"begin\n" + " bxj_po_supplier_common_pkg.update_vendor(p_vendor_id => :1,\n" +
" p_vendor_name => :2,\n" +
" p_inactive_date => :3,\n" +
" p_reject_reason => :4,\n" +
" p_recommended => :5,\n" +
" x_status => :6,\n" +
" x_message => :7,\n" +
" p_flag => :8);\n" + "end;";
OADBTransaction tnx = getOADBTransaction();
CallableStatement ocs = tnx.createCallableStatement(sql, 1);
Date endDate = null;
if (date != null && !"".equals(date))
{
endDate = Date.valueOf(date);
}
try
{
ocs.setObject(1, vendorid);
ocs.setObject(2, supplierName);
ocs.setDate(3, endDate);
ocs.setObject(4, rejectReason);
ocs.setObject(5, pRecommended);
ocs.registerOutParameter(6, Types.VARCHAR);
ocs.registerOutParameter(7, Types.VARCHAR);
ocs.setObject(8, type);
ocs.execute();
status = ocs.getString(6);
msg = ocs.getString(7);
}
catch (Exception e)
{
throw new OAException("鏇存柊渚涘簲鍟�:" + supplierName + "淇℃伅澶辫触!" +
e.getMessage());
}
finally
{
if (ocs != null)
{
try
{
ocs.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
if (!"S".equalsIgnoreCase(status))
{
throw new OAException(msg);
}
return msg;
}
三、知识点
1. OracleStatement 和 OraclePrepareStatement
1. PreparedStatement是预编译的,对于批量处理可以大大提高效率. 也叫JDBC存储过程
2. 使用 Statement 对象。在对数据库只执行一次性存取的时侯,用 Statement 对象进行处理。
PreparedStatement 对象的开销比Statement大,对于一次性操作并不会带来额外的好处。
3. statement每次执行sql语句,相关数据库都要执行sql语句的编译,preparedstatement是预编译得, preparedstatement支持批处理
4. 执行许多SQL语句的JDBC程序产生大量的Statement和PreparedStatement对象。
通常认为PreparedStatement对象比Statement对象更有效,特别是如果带有不同参数的同一SQL语句被多次执行的时候。
PreparedStatement对象允许数据库预编译SQL语句,这样在随后的运行中可以节省时间并增加代码的可读性。
然而,在Oracle环境中,开发人员实际上有更大的灵活性。当使用Statement或PreparedStatement对象时,Oracle数据库会缓存SQL语句以便以后使用。
在一些情况下,由于驱动器自身需要额外的处理和在Java应用程序和Oracle服务器间增加的网络活动,执行PreparedStatement对象实际上会花更长的时间。
然而,除了缓冲的问题之外,至少还有一个更好的原因使我们在企业应用程序中更喜欢使用PreparedStatement对象,那就是安全性。
传递给PreparedStatement对象的参数可以被强制进行类型转换,使开发人员可以确保在插入或查询数据时与底层的数据库格式匹配。
当处理公共Web站点上的用户传来的数据的时候,安全性的问题就变得极为重要。
传递给PreparedStatement的字符串参数会自动被驱动器忽略。
最简单的情况下,这就意味着当你的程序试着将字符串“D'Angelo”插入到VARCHAR2中时,该语句将不会识别第一个“,”,从而导致悲惨的失败。几乎很少有必要创建你自己的字符串忽略代码。
在Web环境中,有恶意的用户会利用那些设计不完善的、不能正确处理字符串的应用程序。
特别是在公共Web站点上,在没有首先通过PreparedStatement对象处理的情况下,所有的用户输入都不应该传递给SQL语句。此外,在用户有机会修改SQL语句的地方,如HTML的隐藏区域或一个查询字符串上,SQL语句都不应该被显示出来。
5. 一般来说,我会习惯使用PreparedStatement对数据库进行操作。
PreparedStatement是预编译方式的,在执行SQL语句的时候效率就要高一些,还有就是PreparedStatement可以更好地避免SQL注入问题;
在拼接sql语句时,采用PreparedStatement可以有效地减少出错的几率;
PreparedStatement是Statement的一个子类,理所当然地PreparedStatement对Statement有一定的扩展,在性能方面有一定的提高。
Thanks and Regards
技术交流,技术讨论,欢迎加入
Technology Blog Created By Oracle ERP - 鲍新建