一、Servlet生命周期与工作原理
1. Servlet生命周期分为三个阶段: 初始化阶段 调用init()方法
响应客户请求阶段调用service()方法 终止阶段调用destroy()方法
2. Servlet初始化阶段:
在下列时刻Servlet容器装载Servlet:
1) Servlet容器启动时自动装载某些Servlet,实现它只需要在web.XML文件中的
Servlet何时被创建:
a. 默认情况下,当WEB客户第一次请求访问某个Servlet的时候,WEB容器将创建
这个Servlet的实例。
b. 当web.xml文件中如果
容器在启动web服务器时,将按照顺序创建并初始化Servlet对象。
注意:在web.xml文件中,某些Servlet只有
2) 在Servlet容器启动后,客户首次向Servlet发送请求 3) Servlet类文件被更新后,重新装载Servlet
Servlet被装载后,Servlet容器创建一个Servlet实例并且调用Servlet的init()方法进行初始化。在Servlet的整个生命周期内,init()方法只被调用一次。
3. Servlet响应请求阶段:
对于用户到达Servlet的请求,Servlet容器会创建特定于这个请求的ServletRequest对象和ServletResponse对象,然后调用Servlet的service方法。service方法从ServletRequest对象获得客户请求信息,处理该请求,并通过ServletResponse对象向客户返回响应信息。
4. Servlet终止阶段:
当WEB应用被终止,或Servlet容器终止运行,或Servlet容器重新装载Servlet新实例时,Servlet容器会先调用Servlet的destroy()方法,在destroy()方法中可以释放掉Servlet所占用的资源。
5. Servlet工作原理:
首先简单解释一下Servlet接收和响应客户请求的过程,首先客户发送一个请求,Servlet是调用service()方法对请求进行响应的,通过源代码可见,service()方法中对请求的方式进
行了匹配,选择调用doGet,doPost等这些方法,然后再进入对应的方法中调用逻辑层的方法,实现对客户的响应。在Servlet接口和GenericServlet中是没有doGet,doPost等等这些方法的,HttpServlet中定义了这些方法,但是都是返回error信息,所以,我们每次定义一个Servlet的时候,都必须实现doGet或doPost等这些方法。
每一个自定义的Servlet都必须实现Servlet的接口,Servlet接口中定义了五个方法,其中比较重要的三个方法涉及到Servlet的生命周期,分别是上文提到的init(),service(),destroy()方法。GenericServlet是一个通用的,不特定于任何协议的Servlet,它实现了Servlet接口。而HttpServlet继承于GenericServlet,因此HttpServlet也实现了Servlet接口。所以我们定义Servlet的时候只需要继承HttpServlet即可。 Servlet接口和GenericServlet是不特定于任何协议的,而HttpServlet是特定于HTTP协议的类,所以HttpServlet中实现了service()方法,并将请求ServletRequest,ServletResponse强转为HttpRequest和HttpResponse。 public void service(ServletRequest req,ServletResponse res) throws ServletException,IOException {
HttpRequest request; HttpResponse response;
try {
req = (HttpRequest)request; res = (HttpResponse)response; }catch(ClassCastException e) {
throw new ServletException(\ }
service(request,response); }
代码的最后调用了HTTPServlet自己的service(request,response)方法,然后根据请求去调用对应的doXXX方法,因为HttpServlet中的doXXX方法都是返回错误信息, protected void doGet(HttpServletRequest res,HttpServletResponse resp) throws ServletException,IOException {
String protocol = req.getProtocol();
String msg = IStrings.getString(\ if(protocol.equals(\ {
resp.sendError(HttpServletResponse.SC.METHOD.NOT.ALLOWED,msg); } esle {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST,msg); } }
所以需要我们在自定义的Servlet中override这些方法! 源码面前,了无秘密!
---------------------------------------------------------------------------------------------------------------------------------
对于Tomcat来说,它会将传递过来的参数放在一个Hashtable中,该Hashtable的定义是: private Hashtable
HashMap线程不安全的,Hashtable线程安全。
Web应用何时被启动:
1,当Servlet容器启动的时候,所有的Web应用都会被启动 2,控制器启动web应用
Servlet与JSP的比较:
有许多相似之处,都可以生成动态网页。
JSP的优点是擅长于网页制作,生成动态页面比较直观,缺点是不容易跟踪与排错。 Servlet是纯Java语言,擅长于处理流程和业务逻辑,缺点是生成动态网页不直观。
二、Hibernate
1、 Hibernate工作流程
原理:
1. 读取并解析配置文件
2. 读取并解析映射信息,创建SessionFactory
3. 打开Sesssion
4. 创建事务Transation
5. 持久化操作
6. 提交事务
7. 关闭Session
8. 关闭SesstionFactory
Hibernate优缺点:
Hibernate 是一个开放源的对象关系映射框架,Hibernate是JDBC的轻量级的对象封装,它是一个独立的对象持久层框架,使得Java程序员可以随 心所欲的使用对象编程思维来操纵数据库。
Hibernate 可以应用在任何使用JDBC的场合:Java应用程序的数据库访问代码,也可以在Servlet/JSP的 Web应用中使用(DAO接口的实现类),甚至可以是BMP里面的访问数据库的代码。大多数开发机构经常采取创建各自独立的数据持久层。一旦底层的数据结构发生改变,那么修改应用的其余部分使之适应这种改变的代价将是十分巨大的。Hibernate适 时的填补了这一空白,它为Java应用提供了一个易用的、高效率的对象关系映射框架。 优点:
a. Hibernate 使用 Java 反射机制 而不是字节码增强程序来实现透明性。 b. Hibernate 的性能非常好,因为它是个轻量级框架。 映射的灵活性很出色。 c. 它支持各种关系数据库,从一对一到多对多的各种复杂关系。 缺点:
它限制您所使用的对象模型。(例如,一个持久性类不能映射到多个表) 2、 Hibernate是如何延迟加载?
a. Hibernate2延迟加载实现:a)实体对象 b)集合(Collection)
b.Hibernate3 提供了属性的延迟加载功能 ,当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,从而提高了服务器的性能。
Hibernate中的update()和saveOrUpdate()的区别,session的load()和get()的区别。
(1) saveOrUpdate()方法可以实现update()的功能,但会多些步骤,具体如 下: 如果对象在该session中已经被持久化,不进行操作;
对象的标识符属性(identifier property)在数据库中不存在或者是个暂时的
值,调用save()方法保存它;
如果session中的另一个对象有相同的标识符抛出一个异常; 以上皆不符合则调用update()更新之。
Session.load/get方法均可以根据指定的实体类和id从数据库读取记录,并返回与之对应的实体对象。其区别在于:
如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个ObjectNotFoundException;
load方法可返回实体的代理类实例,而get方法永远直接返回实体类; load方法可以充分利用内部缓存和二级缓存中的现有数据,而get方法则仅仅在内部缓存中进行数据查找,如没有发现对应数据,将越过二级缓存,直接调用SQL完成数据读取。
在hibernate中进行多表查询,每个表中各取几个字段,也就是说查询出来的结果集并没有一个实体类与之对应,如何解决这个问题?
解决方案一,按照Object[]数据取出数据,然后自己组bean
解决方案二,对每个表的bean写构造函数,比如表一要查出field1,field2两个字段,那么有一个构造函数就是Bean(type1 filed1,type2 field2) ,然后在hql里面就可以直接生成这个bean了。具体怎么用请看相关文档,我说的不是很清楚。
(2)load()和get()的区别 load加载方法: Java代码 User user=(Users)session.load(Users.class,userId) get加载方法: Java代码 User user=(Users)session.get(Users.class,userId); 两加载方法区别:
区别1:如果数据库中,没有userId的对象。如果通过get方法加载,则返回的是一个null;如果通过load加载,则返回一个代理对象,如果后面代码如果调用user对象的某个属性(比如user.getPassword())会抛出异常:org.hibernate.ObjectNotFoundException;
区别2:load支持延迟加载,get不支持延迟加载。也就是说User user=(Users)session.load(Users.class,userId);这句代码不会执行数据库查询,只有用到user时才会去执行数据库查询。但User user=(Users)session.get(Users.class,userId);则会立即去执行数据库查询。所以User user=(Users)session.load(Users.class,userId);不会执行sql
3. Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系)
类与类之间的关系主要体现在表与表之间的关系进行操作,它们都市对对象进行