当前位置:Gxlcms > 数据库问题 > Java——JDBC小结(4)

Java——JDBC小结(4)

时间:2021-07-01 10:21:17 帮助过:2人阅读

@Test 2 public void test1(){ 3 //假设传入的员工id是 4 int id=7369; 5 Connection con=null; 6 //创建连接 7 try { 8 String sql="select * from emp_jiawenzhe " 9 + "where empno="+id; 10 con=DBUtil.getConnection(); 11 Statement smt=con.createStatement(); 12 ResultSet rs=smt.executeQuery(sql); 13 //结果集中封装了多行数据,需要遍历 14 while(rs.next()){ 15 //rs.get类型(字段名) 16 //rs.get类型(字段索引) 17 System.out.println(rs.getInt("empno")); 18 System.out.println(rs.getString("ename")); 19 } 20 } catch (SQLException e) { 21 //记录日志 22 e.printStackTrace(); 23 //能处理则自己处理,处理不了向上抛给调用者 24 throw new RuntimeException("查询员工失败",e); 25 }finally{ 26 //归还连接 27 DBUtil.close(con); 28 } 29 }

根据SQL语句可以看出,是要从一张员工表里面找到在指定id的员工,rs是结果集的实例化,rs.next()方法就是去遍历每一个字段,当字段遍历到最后为空的时候返回null

而rs.get方法后面跟的类型是要以你的数据库字段类型为标准,比如我要得到员工号,员工号肯定是整数,所以用getInt,以此类推这段测试代码执行后的结果为:

7369
SMITH

得到了员工号为7369,名字为SMITH

2.PreparedStatement

从上面的示例可以看到,我们进行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

3.SQL注入

所谓的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)

标签:

人气教程排行