时间:2021-07-01 10:21:17 帮助过:2人阅读
根据SQL语句可以看出,是要从一张员工表里面找到在指定id的员工,rs是结果集的实例化,rs.next()方法就是去遍历每一个字段,当字段遍历到最后为空的时候返回null
而rs.get方法后面跟的类型是要以你的数据库字段类型为标准,比如我要得到员工号,员工号肯定是整数,所以用getInt,以此类推这段测试代码执行后的结果为:
7369
SMITH
得到了员工号为7369,名字为SMITH
从上面的示例可以看到,我们进行SQL查询是传入了一条写好的固定好了的SQL语句,比如我们现在需要进行下一条查询,必须在重新写一个SQL语句,并且重新编译一次。这样看来效率很差,Statement只适合在静态SQL中使用,为此Java引进了PreparedStatement来做出动态SQL查询的效果。
关于PreparedStatement的原理解释有很多很多,下面我直接引入一段代码直观简介的阐明
1 @Test 2 public void test2(){ 3 //假设查询的工资 4 double salary=4500.0; 5 Connection conn=null; 6 try { 7 conn=DBUtil.getConnection(); 8 String sql="select *from emp_jiawenzhe " 9 + "where sal>=?"; 10 //创建PrepareStatement对象 11 //发送SQL并建立执行计划 12 PreparedStatement ps=conn.prepareStatement(sql); 13 //设置参数 14 //ps.set类型(?的索引,?的值) 15 ps.setDouble(1, salary); 16 ResultSet rs=ps.executeQuery(); 17 while (rs.next()) { 18 System.out.println(rs.getInt("empno")); 19 System.out.println(rs.getString("ename")); 20 21 } 22 } catch (SQLException e) { 23 24 e.printStackTrace(); 25 throw new RuntimeException("查询员工失败",e); 26 }finally{ 27 DBUtil.close(conn); 28 } 29 }
在上面的SQL语句中,可以看懂他的意思就是要查询工资大于某个范围的员工信息,但是这个范围我们并没有写死,而是用"?"作为占位符,也就是说,这个问号的具体值将由后面传入,和Statement的方法一样,我们同样要拿到PreparedStatement的接口的连接对象,调用他的一个set()方法将参数传入,第一个参数是索引值,也就是问号的位置,第二个参数就是实际的值,将实际的值存放到变量之中,这样在修改的时候只要改动就可以了,而不用再去改动SQL语句。
接下来的这个例子,你会看到SQL使用了更多的占位符,更加体现了这种方法的有点
1 @Test 2 public void test03(){ 3 //假设用户传入了如下要添加的数据 4 String ename="唐僧"; 5 String job="领导"; 6 int mgr=0; 7 Date date=new Date(System.currentTimeMillis()); 8 double sal=9000; 9 double comm=3000; 10 int deptno=2; 11 Connection conn=null; 12 try { 13 conn=DBUtil.getConnection(); 14 String sql="insert into emp_jiawenzhe(empno,ename,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) " 15 + "values(emp_jiawenzhe_j.nextval,?,?,?,?,?,?,?)"; 16 PreparedStatement ps=conn.prepareStatement(sql); 17 ps.setString(1, ename); 18 ps.setString(2, job); 19 ps.setInt(3, mgr); 20 ps.setDate(4, date); 21 ps.setDouble(5, sal); 22 ps.setDouble(6, comm); 23 ps.setInt(7,deptno); 24 ps.executeQuery(); 25 } catch (SQLException e) { 26 27 e.printStackTrace(); 28 throw new RuntimeException("增加员工失败",e); 29 }finally{ 30 DBUtil.close(conn); 31 } 32 }
下面是一条修改的示例:
1 @Test 2 public void test4(){ 3 //假设用户传入了如下要修改的数据 4 int empno=104; 5 String ename="悟空"; 6 String job="保镖"; 7 int mgr=8; 8 Date date =new Date(System.currentTimeMillis()); 9 double sal=5000.0; 10 double comm=0; 11 int deptno=2; 12 Connection conn=null; 13 try { 14 conn=DBUtil.getConnection(); 15 String sql="update emp_jiawenzhe set " 16 + "ename=?," 17 + "job=?," 18 + "mgr=?," 19 + "hiredate=?," 20 + "sal=?," 21 + "comm=?," 22 + "deptno=? " 23 + "where empno=?"; 24 PreparedStatement ps=conn.prepareStatement(sql); 25 ps.setString(1, ename); 26 ps.setString(2, job); 27 ps.setInt(3, mgr); 28 ps.setDate(4, date); 29 ps.setDouble(5, sal); 30 ps.setDouble(6, comm); 31 ps.setInt(7, deptno); 32 ps.setInt(8, empno); 33 ps.executeQuery(); 34 } catch (SQLException e) { 35 36 e.printStackTrace(); 37 throw new RuntimeException("修改错误",e); 38 }finally{ 39 DBUtil.close(conn); 40 } 41 }
set方法后面跟的类型和我上面说的get方法是完全一样的
下面是一个删除的示例:
1 @Test 2 public void test5(){ 3 Connection conn=null; 4 int empno=104; 5 try { 6 conn=DBUtil.getConnection(); 7 String sql="delete from emp_jiawenzhe " 8 + "where empno=? "; 9 PreparedStatement ps=conn.prepareStatement(sql); 10 ps.setInt(1, empno); 11 ps.executeQuery(); 12 } catch (SQLException e) { 13 14 e.printStackTrace(); 15 throw new RuntimeException("删除错误",e); 16 }finally{ 17 DBUtil.close(conn); 18 } 19 }
注意一下这里面的DBUtil就是我之前写的工具类3
所谓的SQL注入其实就是程序的一个bug,更准确的说是在使用Statement时产生的这样一个bug,我举个例子加以说明一下,比如你在输入密码的时候,其实你是不知道密码的,你输入的密码是:123 or ‘a’=‘a’;这样输入就是利用了SQL里面的关键字or,因为or后面的表达式是恒成立的,所以这个密码整体就是恒正确的,这样你就会在完全不知道密码的情况下登陆系统
为了解决这个办法,必须使用参数化的SQL,即使用?作为占位符,这样就可以有效避免SQL注入
示例代码:
1 @Test 2 public void test6(){ 3 //假设用户输入的数据如下 4 String username ="admin"; 5 String password="‘a‘ or ‘b‘=‘b‘"; 6 Connection conn=null; 7 try { 8 conn=DBUtil.getConnection(); 9 String sql="select*from user_jiawenzhe " 10 + "where username=? " 11 + "and password=? "; 12 PreparedStatement ps=conn.prepareStatement(sql); 13 ps.setString(1, username); 14 ps.setString(2, password); 15 ResultSet rs= ps.executeQuery(); 16 while (rs.next()) { 17 System.out.println("登陆成功"); 18 19 } 20 } catch (SQLException e) { 21 22 e.printStackTrace(); 23 throw new RuntimeException("查询用户失败",e); 24 }finally{ 25 DBUtil.close(conn); 26 } 27 }
这样系统将不会把or理解为SQL的关键字而仅仅当成普通的字符串。
未完待续!
Java——JDBC小结(4)
标签: