3、JDBC小疑惑

推荐1:Java JDBC的基本知识
推荐2:JDBC详解 - ErBing - 博客园
推荐3:JDBC - 壹叶知秋 - 博客园

  1. 为什么使用Class.forName而不是DriverManager.registerDriver加载数据库驱动?

前者不会对具体的驱动类产生依赖,而后者不仅会对具体的驱动类产生依赖,还会造成DriverManager中产生两个一样的驱动。

1 Class.forname("com.mysql.jdbc.Driver");
2 DriverManager.registerDriver(new com.mysql.jdbc.Driver());

如上,用DriverManager.registerDriver加载mysql驱动,需要new一个mysql驱动类,这样会使程序对mysql的jar包产生依赖(耦合度提高,不利于实际开发)。如果项目没有导入mysql的jar包,这里会出现编译出错的问题(目录中这个类会出现红色波浪线)。但如果用Class.forName加载mysql驱动,括号里面的仅仅代表字符串,不会出现编译出错。即使项目里没有导入mysql的jar包,也只会出现运行时出错(出现异常的形式)的问题。

  1. 为什么调用Class.forName()加载数据库驱动就行,而不调用newInstance()创建其实例?

Class.forName()的作用是让JVM动态加载括号中的类,返回的是一个类。如果想实例化一个这个类的对象,就使用Class.forName().newInstance()。若类中有静态代码块,JVM加载此类时必然会先执行该代码片段,而JDBC规范中明确规定Driver类要有静态代码块。所以,使用Class.forName()时,JVM加载此类并执行里面的静态代码,完成了数据库注册功能,已经没有必要去创建实例了。
具体见:Java中newInstance()和new()

  1. url内容表示什么?
  • 协议:JDBC URL中的协议总是jdbc。
  • 子协议:驱动程序名或数据库连接机制(这种机制可由一个或多个驱动程序支持)的名称,如mysql、oracle等。
  1. 为什么使用PreparedStatement而不是Statement?

PreparedStatement对象比Statement对象的效率更高,并且可以防止SQL注入

SQL注入问题:
用Statement执行数据库操作会存在严重的sql注入危险:

String id = "5";
String sql = "delete from table where id=" +  id;
Statement st = conn.createStatement();
st.executeQuery(sql);

sql语句为:delete from table where id = 5

乍看没有任何问题,但是如果用户传入的id为“xx or 1=1”,则真正的sql语句变成:

delete from table where id = xx or 1 = 1

即使id不正确,但1=1条件恒成立,那么这个sql语句就可以执行,表中的记录将会被误删,主要原因是statement使用拼串传值的。显然这种结果是不应该的,这便是SQL注入问题。
用PreparedStatement可以有效地防止sql注入:

String sql = "delete from table where id= ? ";  
PreparedStatement ps = conn.preparedStatement(sql);  
ps.setString(1,5);
ps.executeQuery();

用PreparedStatement时,SQL语句在程序运行前已经进行了预编译,运行时会动态地将参数传给PreprareStatement,即使参数里有敏感字符如 or 1=1,数据库也会一个参数对应一个?来处理,而不会成为一个SQL语句。

  1. 结果集索引从1还是从0开始?

与索引从0开始不同,结果集从1开始获取指定数据。

  1. 释放资源的问题

数据库连接非常消耗资源,尽量晚创建、早释放,同时加上try……catch……finally语句,在finally代码块里释放资源,以防前面代码出现错误,导致资源无法及时关闭。使用后的东西都需要释放,关闭的顺序是先得到的后关闭,后得到的先关闭

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值