MyException - 我的异常网
当前位置:我的异常网» 数据库 » 数据库口试技巧,通过JDBC展示自己专业性,摘自java

数据库口试技巧,通过JDBC展示自己专业性,摘自java web轻量级开发面试教程

www.MyException.Cn  网友分享于:2013-09-19  浏览:0次
数据库面试技巧,通过JDBC展示自己专业性,摘自java web轻量级开发面试教程

       这篇文章是我之前写的博文 数据库方面的面试技巧,如何从建表方面展示自己能力 和 

面试技巧,如何通过索引说数据库优化能力,内容来自Java web轻量级开发面试教程是一个系列的,通过面试官的视角和大家分享在数据库方面的面试经验,这些内容都来摘自  java web轻量级开发面试教程

       之前的两篇文章点击量都还行,也感谢管理员放入首页,这鼓舞到了我,也让我更有信心和大家分享我的经验。

        我们知道,最终我们是要通过jdbc来连接并访问数据库的,也就是说,最近面试官一定会通过JDBC方面的技能来考核候选人的能力,这篇文章就是和大家展示这方面的说辞。

 

 

1  用try…catch…finally从句

       根据这个从句的特性,不论是否发生异常,不论发生何种异常,finally从句一定会执行(除非用System.exit退出)。

        根据这个特性,需要把关闭JDBC对象部分的代码写到finally从句里。

        同时,在try…catch里应该注意如下三点:

        第一,不能直接用Exception来接收所有异常,应当先用专业的异常处理类,比如SQLException来接收,最后再用Exception来做最后的防守。

      第二,在catch从句里,别什么都不做,也别直接抛出异常了事,应该返回一些有可操作性的语句,提示用户在遇到异常时该怎么办,比如给出联系人的电话。

     第三,因为监听和检测异常是需要代价的,所以应当尽量缩小try…catch的范围,只包括必要的代码即可,而不是把整个函数都包含在try…catch从句里。

      大家别小看上述非常通俗易懂的原则。作者在某个大公司工作时,曾加过一个项目的评审团队,该公司所有的项目在上线前都要经过这个团队评审打分,如果分数达不到标准,就需要整改代码。

      刚提到的这些原则都是具体的打分项,这个大公司是著名外企,其中的员工都很优秀,但在异常处理点上失分是普遍现象。换句话说,如果大家在面试中说出上述的说辞,一定会让面试官对大家刮目相看。

      下面通过一个简单的查询例子ResultDemo.java来观察下标准写法。有个Student表,其中有两个字段,均为字符类型的学号ID和姓名Name。

 1 import java.sql.Connection;
 2 import java.sql.DriverManager;
 3 import java.sql.ResultSet;
 4 import java.sql.SQLException;
 5 import java.sql.Statement;
 6 public class ResultDemo {
 7     public static void main(String[] args) {
 8         try {
 9                //需要确保支持MySQL的jar能被读到
10               Class.forName("com.mysql.jdbc.Driver");
11             } catch (ClassNotFoundException e) {
12                 System.out.println("Where is your MySQL JDBC Driver?");
13                 e.printStackTrace();
14                 return;
15             }
16             Connection connection = null;
17             Statement stmt = null;
18             try {
19             //这里是连接字符串
20                 connection = DriverManager.getConnection(
21                     "jdbc:mysql://localhost:3306/class3", "root", "123456");
22                 if (connection != null) {
23                     stmt = connection.createStatement();
24                     String query = "select ID,Name from student";
25                     ResultSet rs=stmt.executeQuery(query);
26                     while(rs.next())
27                     {
28                         System.out.println(rs.getString(“ID”));
29                         System.out.println(rs.getString("Name"));
30                     }
31                 } else {
32                     System.out.println("Failed to make connection!");
33                 }
34             } catch (SQLException e) {
35     System.out.println("Check the JDBC Driver or Connection!");
36                 e.printStackTrace();
37             } finally {
38             //close the connection 
39                 try {
40                         stmt.close();
41                 connection.close();
42                 } catch (SQLException e) {
43                     e.printStackTrace();
44                 }
45             }
46         }
47     }

    

      上述代码的业务非常简单,连接数据库后依次打印Student表里的ID和Name信息。但请大家关注一下这段代码带给我们的启示。

        第一,在短短的业务逻辑里,我们分别在第8到第15行,第18到第44行,用了两块try…catch,而没有图省事用一块try…catch代码包含所有的业务方法,这遵循了“尽量缩小检测范围”的原则。

        第二,在第35和36行的catch从句里,没有简单地抛出异常了事,而是输出了一些信息,根据这些信息,调试程序的开发人员能很快从中得到提示,从而很快地找到原因。

        此外,在catch从句里,也可以输出一些面向使用者的提示信息,比如让使用者重启程序,总之一句话,需要把面向Java的异常翻译成让程序员或使用者能理解的提示信息。

       第三,在第37到第44行的finally从句里,关闭了连接,因为不论发生了什么异常,或者是否发生异常,finally从句一定会被执行到,所以可以把关闭连接的代码放入其中。如果不关闭连接,这个数据库连接对象是无法被回收的(Java的垃圾回收机制也无法回收)。

 

2  预处理和批处理

         这里对应的问题有:你有没有用过PreparedStatement对象?PreparedStatement和Statement有什么差别?

         请大家说清楚两点,1 提升效率,2 避免SQL注入,从而保证系统的安全。

         什么叫SQL注入?例如有下图所示的登录界面。

         

       我们一般用如下SQL来验证身份:

Select userName from users where username = ‘输入的用户名’ and pwd = ‘输入的密码’

       一般来说,如果用户名和密码不匹配,是无法通过验证的,但有人可以在User Name里输入1,在User Password部分输入:1’ and pwd = ‘1’ or ‘1’=’1

        那么整个SQL语句就会变成:

         Select userName from users where username = ‘1’ and pwd = ‘1’ or ‘1’=’1’

         这样就能绕过验证。

          而处理对象PrepareStatement能有效防止这个现象的发生,因为一个“?”就是一个占位符,无法扩展。下面来看一个预处理和批处理结合的例子,同样用到刚才提到的Student表,这次来批量插入数据。         

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCBatch {
	public static void main(String[] args) {
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			System.out.println("Where is your MySQL JDBC Driver?");
			e.printStackTrace();
			return;
		}
		Connection connection = null;
	        PrepareStatement pstmt;
			try {
	        //这里是连接字符串
				connection = DriverManager.getConnection(
						"jdbc:mysql://localhost:3306/class3", "root", "123456");
				if (connection != null) {
					String query = "insert into student values (?,?)";
					pstmt = connection.preparedStatement(query);//开始设置参数
					pstmt.setString(1,"1");
					pstmt.setString(2,"Peter");
					pstmt.addBatch();
					//设置第二个参数
					pstmt.setString(1,"2");
					pstmt.setString(2,"Mike");
					pstmt.addBatch();
					//执行批处理
					pstmt.executeBatch();				
				} else {
					System.out.println("Failed to make connection!");
				}
			} catch (SQLException e) {
				System.out.println("Some of Students were not inserted correctly, please check the student table and insert manually.");
				e.printStackTrace();
			} finally {
				try {
					connection.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}

  这部分的逻辑也比较简单,用insert语句批量插入数据。但请大家注意如下两点:

① 在PrepareStatement里,占位符的编号是从1开始,而不是从0开始。

② 批量操作能提升效率,但一次性操作多少,才能让效率提升到最高?这在不同的数据库里是不同的,一般是每批操作500到1000条语句。但切记,别一次性把所有的insert语句都用addBatch放入,因为如果SQL语句过多,会撑爆缓存,从而出错。

       PrepareStatement是个比较重要的JDBC对象。再重复一下,我们在面试的时候,有时会问这个问题:Statement和PrepareStatement有什么差别?答案要点是PrepareStatement能预处理,如果能展开一下,说明能防止SQL注入就更好了。

       总结一下,这里大家可以通过叙述代码里的要点来阐释自己在JDBC方面的能力。

       1 阐述try...catch...finally的用法。

       2 详细阐述PreparedStatement的用法,包括预处理批处理和SQL注入两点。

 

文章评论

为什么程序员都是夜猫子
为什么程序员都是夜猫子
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
程序员和编码员之间的区别
程序员和编码员之间的区别
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
10个调试和排错的小建议
10个调试和排错的小建议
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
Java程序员必看电影
Java程序员必看电影
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
 程序员的样子
程序员的样子
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
那些争议最大的编程观点
那些争议最大的编程观点
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
每天工作4小时的程序员
每天工作4小时的程序员
编程语言是女人
编程语言是女人
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
漫画:程序员的工作
漫画:程序员的工作
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
老程序员的下场
老程序员的下场
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
程序员应该关注的一些事儿
程序员应该关注的一些事儿
程序员必看的十大电影
程序员必看的十大电影
一个程序员的时间管理
一个程序员的时间管理
程序员的鄙视链
程序员的鄙视链
旅行,写作,编程
旅行,写作,编程
如何成为一名黑客
如何成为一名黑客
程序员都该阅读的书
程序员都该阅读的书
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
我的丈夫是个程序员
我的丈夫是个程序员
总结2014中国互联网十大段子
总结2014中国互联网十大段子
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
中美印日四国程序员比较
中美印日四国程序员比较
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有