java操作sql server数据中,关于PreparedStatement数据注入问题
2015-12-03 18:22
399 查看
问题描述:
在Java操作SQL Server数据库时,会使用PreparedStatement数据注入方式避免“万能密码”的产生以及提高代码执行效率。例如经常使用如下方式:
requery("select * from stu where name = ? and address = ?", new String[]{ "liu", "wo"});
或 requery("select * from stu where name = ? ", new String[]{ "liu"});
//这样实现requery函数的复用,减少代码量。
public void requery(String s,String[] data){
try{
Class.forName(className);
ct=DriverManager.getConnection(url,name,passWord);
ps=ct.prepareStatement(s);
for(int i=0; i <data.length; i++){
ps.setString(i+1,data[i]);
}
rs=ps.executeQuery();
while(rs.next()){
temp=new Vector();
temp.add(rs.getString(1));
temp.add(rs.getString(2));
rowData.add(temp);
}
}catch(Exception e){
e.printStackTrace();
}finally{
//关闭资源
try {
if(rs!=null)
rs.close();
if(ps!=null)
ps.close();
if(ct!=null)
ct.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//但接下来问题来了,若sql语句里的问号所需要填充的数据包括String 、int等各种类型,上述的方法就不能使用了,那怎样才能继续代码复用的这种思想呢?
经过笔者研究,提出如下的解决思路:
1、首先建立一个类模型,成员变量为你要访问的数据库表所对应的各种类型字段,此外加上一个int类型的数组成员变量,长度与前面成员变量个数一直,这个数组用来存放
前面对应的每一个成员变量的位置顺序。如下图
2、A类中添加一个根据位置取A的成员变量的方法
public class User {
public final static int SIZE = 2;
private String username;
private int password;
private int[] flag = new int[SIZE];//对应上面的两个成员
public Object getMenber(int num){
Object o = null;
for(int i = 0; i < SIZE; i++){
if(num == flag[i]){
switch (i) {
case 0: //用户名
o = username;
break;
case 1: //密码
o = password;
break;
}
}
}
return o;
}
public void setFlag(int[] flag) {
this.flag = flag;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(int password) {
this.password = password;
}
}
3、改写requery方法
public void requery(String s,User data, int count){
//查询
columnNames=new Vector();
rowData=new Vector();
//设置列名
columnNames.add("用户名");
columnNames.add("密码");
try{
Class.forName(className);
ct=DriverManager.getConnection(url,name,passWord);
ps=ct.prepareStatement(s);
for(int i=1; i <= count; i++){
ps.setObject(i, data.getMenber(i));
}
rs=ps.executeQuery();
while(rs.next()){
temp=new Vector();
temp.add(rs.getString(1));
temp.add(rs.getString(2));
rowData.add(temp);
}
}catch(Exception e){
e.printStackTrace();
}finally{
//关闭资源
try {
if(rs!=null)
rs.close();
if(ps!=null)
ps.close();
if(ct!=null)
ct.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
4、最后实际应用
User data = new User();
data.setUsername("liu");
data.setPassword(123);
data.setFlag(new int[]{2, 1});
int count = 2; //两个问号
st=new stuMode();
st.requery("select * from stu where password = ? and username = ?",data, count);
在Java操作SQL Server数据库时,会使用PreparedStatement数据注入方式避免“万能密码”的产生以及提高代码执行效率。例如经常使用如下方式:
requery("select * from stu where name = ? and address = ?", new String[]{ "liu", "wo"});
或 requery("select * from stu where name = ? ", new String[]{ "liu"});
//这样实现requery函数的复用,减少代码量。
public void requery(String s,String[] data){
try{
Class.forName(className);
ct=DriverManager.getConnection(url,name,passWord);
ps=ct.prepareStatement(s);
for(int i=0; i <data.length; i++){
ps.setString(i+1,data[i]);
}
rs=ps.executeQuery();
while(rs.next()){
temp=new Vector();
temp.add(rs.getString(1));
temp.add(rs.getString(2));
rowData.add(temp);
}
}catch(Exception e){
e.printStackTrace();
}finally{
//关闭资源
try {
if(rs!=null)
rs.close();
if(ps!=null)
ps.close();
if(ct!=null)
ct.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//但接下来问题来了,若sql语句里的问号所需要填充的数据包括String 、int等各种类型,上述的方法就不能使用了,那怎样才能继续代码复用的这种思想呢?
经过笔者研究,提出如下的解决思路:
1、首先建立一个类模型,成员变量为你要访问的数据库表所对应的各种类型字段,此外加上一个int类型的数组成员变量,长度与前面成员变量个数一直,这个数组用来存放
前面对应的每一个成员变量的位置顺序。如下图
2、A类中添加一个根据位置取A的成员变量的方法
public class User {
public final static int SIZE = 2;
private String username;
private int password;
private int[] flag = new int[SIZE];//对应上面的两个成员
public Object getMenber(int num){
Object o = null;
for(int i = 0; i < SIZE; i++){
if(num == flag[i]){
switch (i) {
case 0: //用户名
o = username;
break;
case 1: //密码
o = password;
break;
}
}
}
return o;
}
public void setFlag(int[] flag) {
this.flag = flag;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(int password) {
this.password = password;
}
}
3、改写requery方法
public void requery(String s,User data, int count){
//查询
columnNames=new Vector();
rowData=new Vector();
//设置列名
columnNames.add("用户名");
columnNames.add("密码");
try{
Class.forName(className);
ct=DriverManager.getConnection(url,name,passWord);
ps=ct.prepareStatement(s);
for(int i=1; i <= count; i++){
ps.setObject(i, data.getMenber(i));
}
rs=ps.executeQuery();
while(rs.next()){
temp=new Vector();
temp.add(rs.getString(1));
temp.add(rs.getString(2));
rowData.add(temp);
}
}catch(Exception e){
e.printStackTrace();
}finally{
//关闭资源
try {
if(rs!=null)
rs.close();
if(ps!=null)
ps.close();
if(ct!=null)
ct.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
4、最后实际应用
User data = new User();
data.setUsername("liu");
data.setPassword(123);
data.setFlag(new int[]{2, 1});
int count = 2; //两个问号
st=new stuMode();
st.requery("select * from stu where password = ? and username = ?",data, count);
相关文章推荐
- 软件体系结构上机实验 面向对象体系结构风格的 KWIC 关键词索引系统设计与实现 java
- Eclipse DDMS中无法查看/data目录
- Ubuntu14.04安装配置jdk1.8
- Spring Web MVC
- java 4种方式读取配置文件 + 修改配置文件
- java 判断文件是否图片
- 解决Java线程池任务执行完毕后线程回收问题
- Java为什么不能创建泛型数组?
- Spring + Mvc + Mybatis 框架例子
- 毕业设计 贪吃蛇 注释+源代码 我的java学习之路
- 【OpenSource】【RxJava】RxJava
- 【OpenSource】【RxJava】RxJava
- 【OpenSource】【RxJava】RxJava
- 【OpenSource】【RxJava】RxJava
- 【OpenSource】【RxJava】RxJava
- 【OpenSource】【RxJava】RxJava
- 【OpenSource】【RxJava】RxJava
- 【OpenSource】【RxJava】RxJava
- Java中的Default方法
- java跳出多重嵌套循环