数据库面试技巧,经过JDBC展现本身专业性,摘自java web轻量级开发面试教程

       这篇文章是我以前写的博文 数据库方面的面试技巧,如何从建表方面展现本身能力 和 html

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

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

        咱们知道,最终咱们是要经过jdbc来链接并访问数据库的,也就是说,最近面试官必定会经过JDBC方面的技能来考核候选人的能力,这篇文章就是和你们展现这方面的说辞。程序员

 

 

1  用try…catch…finally从句

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

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

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

        第一,不能直接用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注入两点。

 

相关文章
相关标签/搜索