JDBC以及相关技术学习(四)----运载SQL进行查询交通工具Statement

Statement:主要负责将SQL发送给数据库,并将返回的结果放在ResultSet中。另外,充当同样角色的还包括了PreparedStatement、CallableStatement,这三个类的关系是 PreparedStatement继承Statement,而CallableStatement继承PreparedStatement,其中,PreparedStatement相对于Statement主要会对传递的参数进行处理,而CallableStatement主要用于执行存储过程。

Statment主要有以下这些常用的方法:

setMaxRows:设置ResultSet返回数据的最大限制
setMaxFieldSize:设置最大的数据块
setEscapeProcessing可打开或关闭转义处理;缺省状态为打开。
setQueryTimeout:设置查询超时的时间,查询超过该时间,程序就不再等待,直接报错
cancel:取消操作
getWarnings:获取数据库警告
clearWarnings:清除数据库警告
execute:执行SQL,可能反悔多个结果集
getResultSet:返回当前结果集
getUpdateCount:获取计数器数量
getMoreResults:指针跳转到下一个结果集或计数器
setFetchDirection:设置获取数据的方向
setFetchSize:设置每次获取数据数量
getResultSetConcurrency:获取此Statement对象生成的ResultSet对象的结果集并发性
getResultSetType:获取结果集合类型
addBatch:添加到批量处理
clearBatch:删除批量处理
executeBatch:执行批量处理
getConnection:获取连接
getGeneratedKeys:获取自增主键
executeUpdate:执行更新语句、插入语句等没有返回查询结果的语句
getResultSetHoldability:获取此Statement对象生成的ResultSet对象的结果集合可保存性
isClosed:是否关闭
setPoolable:请求将 Statement 池化或非池化。


其中,executeUpdate与executeQuery是比较常用的,分别为执行删除、增加更新的语句,并返回受影响的行数,而executeQuery语句主要为执行SQL并返回结果集。

execute同样是执行SQL语句,不过返回的可能是多个结果集,通常与getResultSet (获取当前结果集)  getMoreResults(把指针跳转到下一个结果集)

addBatch与executeBatch也是比较常用的语句,通常将要执行的语句先批量添加进去,然后再批量执行,这样可以减少与数据库的交互次数,提高程序的性能。


但是,Statement主要是通过拼凑SQL并执行,可能存在SQL注入的问题,如下面代码:

public static void read(String name) throws SQLException{
JDBCToolSingleTon jDBCToolSingleTon = JDBCToolSingleTon.getInstance();
Connection conn = jDBCToolSingleTon.getConnection();
Statement statement = conn.createStatement();
String sql = "select id,name,birthday,account from UserInfo where name='"+name+"'";
ResultSet resultSet = statement.executeQuery(sql);
while(resultSet.next()){
System.out.println(resultSet.getString("name"));
}
jDBCToolSingleTon.freeResource(conn, resultSet, statement);

}


加入别人传递进来的参数是:‘ or '1'='1,这样,拼凑成的SQL就变成了:select id,name,birthday,account from UserInfo where name='' or '1'='1',这样就会导致查询结果错误,当然,我们可以采用对字符串进行替换处理的情况来解决,但程序就变得不优雅了,为了解决这个问题,就需要PreparedStatement上场了。

PreparedStatement 主要是在Statement的基础上再进一步的封装,可以有效解决SQL注入的问题。

PreparedStatement 继承自Statement方法,除了Statement的方法,PreparedStatement 主要多出了一些Set的方法用于设置参数,如下:

setString

setBytes

setDate

.....等,用于设置参数,代码如下:


public static void readNoSQLInject(String name) throws SQLException{
JDBCToolSingleTon jDBCToolSingleTon = JDBCToolSingleTon.getInstance();
Connection conn = jDBCToolSingleTon.getConnection();
String sql = "select id,name,birthday,account from UserInfo where name=?";
PreparedStatement pStatement = conn.prepareStatement(sql);
pStatement.setString(1, name);
ResultSet resultSet = pStatement.executeQuery();//注意,这里不能加上参数,否则就是调用了Statement了

while(resultSet.next()){
System.out.println(resultSet.getString("name"));
}
jDBCToolSingleTon.freeResource(conn, resultSet, pStatement);

}

从代码中我们可以看到,name的参数成了一个?,然后通过setString的方法对Name进行赋值,然后通过执行executeQuery进行查询,注意,特别要注意,调用PreparedStatement的时候,一定要调用没有参数的exeucteQuery()方法,而不能调用带参数的executeQuery(SQL)方法,否则就是调用了其父类的方法了,达不到我们想要的目的,达得一提的是,PreparedStatement不但可以处理这些特殊字符串,还有对SQL进行预编译的处理,可以一定程度上提高程序的性能。

CallableStatement  主要继承自PreparedStatement,主要用于执行SQL语句,很简单,看下代码就懂了。


public int Create(){
Connection conn = null;
CallableStatement cs = null;
ResultSet rs = null;
try{
conn =JDBCTool.getConnection();
String sql = "  { call addUser(?,?,?,?)}";//注意是先写大括号,然后在里面写call
cs = conn.prepareCall(sql);//
cs.registerOutParameter(4, Types.INTEGER);//注册参数关键语句
cs.setString(1,"psname");
cs.setDate(2, new java.sql.Date(System.currentTimeMillis()));
cs.setFloat(3, 100f);
cs.executeUpdate();
int id = cs.getInt(4);
System.out.println("id="+id);

}catch(Throwable e){
e.printStackTrace();
}
finally{

}
return 0;
 

}

相对于PreparedStatement,CallableStatement 主要多了一个  registerOutParameter方法,用于注册返回的参数。








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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值