JDBC—03—SQL注入问题;PreparedStatement介绍;
一、 JDBC的使用? 9.SQL 注入问题9.1什么是 SQL 注入 所谓 SQL 注入,就是通过把 `含有 SQL 语句片段的参数` 插入到需要执行的 SQL 语句中,然后statement把SQL语句发送到数据库中,数据库进行编译,?最终达到欺骗数据库服务器执行恶意操作的 SQL 命令。 9.2如何解决? 因为statement没有SQL语句预编译的能力,所以会是数据库执行到恶意SQL命令; 我们换一个有预编译能力的statement对象就行了---PreparedStatement; ? ? ? 10.PreparedStatement 对象的使用(重点)(1)PreparedStatement 特点:
(2)?通过 PreparedStatement 对象向表中插入数据: //向 Departments 表中插入一条数据 try{ conn = JdbcUtil.getConnection(); //再也不用拼接字符串或者参数了,参数用占位符`?`表示,然后在单独对占位符赋值就好了; ps = conn.prepareStatement("insert into departmentsvalues(default,?,?)"); ps.setString(1,departmentName); ps.setInt(2,locationId); ps.execute(); }catch(Exception e){ e.printStackTrace(); }finally{ JdbcUtil.closeResource(ps,conn,null); } ? ? ? ? 11. PreparedStatement 的预编译能力11.1什么是预编译(1)SQL 语句的执行步骤
但是很多情况,我们的一条 sql 语句可能会反复执行,或者每次执行的时候只有个别的值不同(比如 select 的 where 子句值不同,update 的 set 子句值不同,insert 的 values 值不同)。如果每次都需要经过硬解析----上面的词法语义解析、语句优化、制定执行计划等,那效率就明显不行了。 所谓预编译语句就是将这类语句中的值用占位符替代,可以视为将 sql 语句模板化或者说参数化; 预编译语句的优势在于:一次编译、多次运行,省去了解析优化等过程(将完全硬解析变成了硬软都有);此外预编译语句能防止 sql 注入; (2)解析过程
11.2预编译方式
(1)依赖数据库驱动完成预编译 如果我们没有开启数据库服务端编译,那么默认的是使用数据库驱动完成 SQL 的预编 译处理。 (2)依赖数据库服务器完成预编译 我们可以通过修改连接数据库的 URL 信息,添加 useServerPrepStmts=true 信息开启服 务端预编译。 ? ? ? 12.?通过 PreparedStatement 对象完成数据的更新代码 //更新数据 public void updateDepartment(int departmentId,String departmentName,int localhostId){ Connection conn= null; PreparedStatement ps = null; try{ conn = JdbcUtil.getConnection(); ps = conn.prepareStatement("update departments set department_name = ?,location_id = ? where department_id = ?"); ps.setString(1,localhostId); ps.setInt(3,departmentId); ps.execute(); }catch(Exception e){ e.printStackTrace(); }finally{ JdbcUtil.closeResource(ps,null); } } ? ? ? 13.?通过 PreparedStatement 对象完成数据的查询 (1)查询返回单条结果集 public Departments selectDepartmentsById(intdepartmentId){ Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; Departments dept = null; try{ conn = JdbcUtil.getConnection(); ps = conn.prepareStatement("select * from departments where department_id = ?"); ps.setInt(1,departmentId); rs = ps.executeQuery(); while(rs.next()){ dept=new Departments(); dept.setDepartmentId(rs.getInt("department_id")); dept.setDepartmentName(rs.getString("department_name")); dept.setLocationId(rs.getInt("location_id")); } }catch(Exception e){ e.printStackTrace(); }finally{ JdbcUtil.closeResource(ps,rs); } return dept; } ? (2)查询返回多条结果集 建立了一个集合而已,然后不断地输出这个集合的信息就可以了;? //查询部门表中的部门名称,找到那些包含“人力”的部门信息 public List selectDepartmentByLikeName(String departmentName){ Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; List list = new ArrayList<>(); try{ conn = JdbcUtil.getConnection(); ps = conn.prepareStatement("select * from departments where department_name like ?"); ps.setString(1,"%"+departmentName+"%");//注意like子句,的like关键字要和占位符拼在一起; rs = ps.executeQuery(); while(rs.next()){Departments dept = new Departments(); dept.setDepartmentId(rs.getInt("department_id")); dept.setDepartmentName(rs.getString("department_name")); dept.setLocationId(rs.getInt("location_id")); list.add(dept); } }catch(Exception e){ e.printStackTrace(); }finally{ JdbcUtil.closeResource(ps,rs); } return list; } ? ?14. PreparedStatement 批处理操作批处理:在与数据库的一次连接中,批量的执行条 SQL 语句。 14.1代码 //批量添加 public void addBatch(List list){ Connection conn = null; PreparedStatement ps = null; try{ conn = JdbcUtil.getConnection(); ps = conn.prepareStatement("insert into departments values(default,?)"); for(int i=0;i<list.size();i++){ ps.setString(1, list.get(i).getDepartmentName()); ps.setInt(2,list.get(i).getLocationId()); //添加批处理 ps.addBatch(); } int[] arr =ps.executeBatch(); for(int i=0;i<arr.length;i++){ System.out.println(i); } }catch(Exception e){ e.printStackTrace(); }finally{JdbcUtil.closeResource(ps,null); } } ? ? 15. JDBC 中的事务处理在 JDBC 操作中数据库事务默认为自动提交。如果事务需要修改为手动提交,那么我们 需要使用 Connection 对象中的 setAutoCommit 方法来关闭事务自动提交。然后通过 Connection 对象中的 commit 方法与 rollback 方法进行事务的提交与回滚。 15.1代码 //事务处理 public void deleteDempartments(String depratmentName){ Connection conn = null; PreparedStatement ps = null; try{ conn = JdbcUtil.getConnection(); //关闭事务的自动提交 conn.setAutoCommit(false); ps = conn.prepareStatement("delete from departments where department_name like ?"); ps.setString(1,"%"+depratmentName+"%"); ps.executeUpdate(); ps = conn.prepareStatement("insert into departments values(default,‘开发部‘,2)"); ps.executeUpdate(); String str = null; str.length(); conn.commit(); }catch(Exception e){ e.printStackTrace(); JdbcUtil.rollback(conn); }finally{ JdbcUtil.closeResource(ps,null); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |