记一次面试题目,并进行了一些扩展:
因为我简历上有写熟悉JDBC、Servlet、Jsp,所以首先问了关于JDBC和Servlet的知识:
1.说一下JDBC操作数据库的步骤。
- 1.加载数据库连接驱动
Class.forName(...); - 2.获取数据连接对象
Connection conn = DriverManger.getConnection(...); - 3.获取语句对象
会话对象有两种Statement和PreparedStatement
Statement stat = conn.createStatement();
PreparedStatement ps = conn.prepareStatement(...) - 4.执行sql语句
如果是Statement对象
int i = stat.executeUpdate(...); 或者 ResultSet rs = stat.executeQuery(...);
如果是PreparedStatement对象,需要先设置参数
int i = ps.executeUpdate(); 或者 ResultSet resultSet = ps.executeQuery(); - 5.如果是处理查询语句,要处理结果集ResultSet
根据执行语句后返回的结果来处理结果集,一般DML(数据操纵语言)操作不需要处理结果集,DQL(数据查询语句)才需要,通过ResultSet对象的API操作
while (rs.next()){ ... } - 6.关闭资源
rs.close()、stat.close()、conn.close() 注意关闭顺序以及处理异常
public static void main(String[] args) throws Exception { String className = "oracle.jdbc.driver.OracleDriver";// 驱动类名称 String url = "jdbc:oracle:thin:@localhost:1521:XE";// 连接字符串 //-------------------------加载数据库驱动----------------------------- Class.forName(className); //-------------------------创建数据库连接----------------------------- Connection conn = DriverManager.getConnection(url, "no8", "123456"); //-------------------------获取操作对象Statement---------------------- Statement stat = conn.createStatement(); //--------------------------执行sql语句------------------------------ //执行insert into语句: String sql = "insert into student(id,name) values(myseq.nextval,'" + name + "')"; int i = stat.executeUpdate(sql);//增删改调用方法 System.out.println("操作影响了"+i+"行!"); /*执行selset语句: String sql = "select * from student"; // 接收查询结果 ResultSet rs = stat.executeQuery(sql); // 操作结果集对象 while(rs.next()){ String name = rs.getString("name"); System.out.println(name); }*/ //------------------------关闭数据库连接------------------------------ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } finally { conn = null; } }
有什么要注意的地方吗?
我说了执行select与增删改语句的问题:如果执行selset调用executeQuery("sql语句"),并用ResultSet接收查询结果;而增删改调用executeUpdate("sql语句")
后来想了一下,其实应该要说下数据库连接中资源关闭的顺序,而且需要处理异常:
在JDBC连接数据库时首先要获得connection,再通过它获得相应的statement,最后获得结果集resultset。
所以应该先关闭ResultSet,然后是Statement,最后是Connetion。
public static void closeAllResource(Connection conn,Statement stat,ResultSet rs) { if (rs!=null) { try { rs.close(); } catch (Exception e) { e.printStackTrace(); } } if (stat!=null) { try { stat.close(); } catch (Exception e) { e.printStackTrace(); } } if (conn!=null) { try { conn.close(); } catch (Exception e) { e.printStackTrace(); } } }
然后面试官问那ResultSet需要关闭吗? 需要。
2.说一下Severlet的生命周期
Servlet生命周期分为4个阶段:
- 实例化。new ,Servlet是由服务器(Tomcat)端实例化的。
- 初始化阶段,调用init()方法初始化Servlet。
- 响应客户请求阶段,调用service()方法 。每当一个客户请求一个HttpServlet对象,该对象的Service()方法就要调用。service根据客户端的请求类型,调用doGet、doPost等方法。
- 终止阶段,调用destory()方法进行销毁。(当需要释放内存或者容器关闭时,容器就会调用Servlet实例的destroy()方法。在destroy()方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收。如果再次需要这个Servlet处理请求,Servlet容器会创建一个新的Servlet实例。)
详细可看https://www.cnblogs.com/lgk8023/p/6427977.html
初始化init是什么时候调用的?
init 方法的执行时刻其实与 servlet 的配置有关,根据配置文件中<load-on-startup>的值,分为两种情况:
- 如果load-on-startup的值大于等于 0,则在 Servlet 实例化的时候执行。(需要配置web.xml文件,并且正数的值越小,启动该servlet的优先级越高)
- 如果load-on-startup小于0或者没有配置,则在第一次请求(第一次调用servelt)的时候才执行。
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- 配置第一个servlet --> <servlet> <!-- 给servlet取一个名字,名字按照变量命名规范可以自定义名字。 --> <servlet-name>OneServlet</servlet-name> <!-- 说明这个类在项目中的路径 ,包含这个类所在的包名和这个类的类名如下面的配置: test05是类所在的包名,OneServlet是类名--> <servlet-class>test05.OneServlet</servlet-class> <!-- 配置初始化方式为tomcat容器启动后自动初始化该servlet类 --> <load-on-startup>1</load-on-startup> </servlet> <!-- 配置如何访问这个servlet --> <servlet-mapping> <!-- 引用上面servlet类定义的名字 --> <servlet-name>OneServlet</servlet-name> <!-- 配置url访问这个servlet类的名字,名字按照变量命名规范可以自定义名字。 如下配置:/one,这个名字会在访问OneServlet类时候使用。例如:127.0.0.1:8080/项目名称/one--> <url-pattern>/one</url-pattern> </servlet-mapping> </web-app>
3.Servlet的调用
Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:
①Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。
②装载并创建该Servlet的一个实例对象。
③调用Servlet实例对象的init()方法。
④创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
⑤WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。
具体参考:https://www.cnblogs.com/xdp-gacl/p/3760336.html
参考:https://blog.csdn.net/m0_38039437/article/details/75193791