Spring-MVC-Hibernate-搭建后台服务


框架介绍

Spring MVC

Spring MVC基于传统Spring的MVC模式的开发框架。 MVC设计模式在Spring MVC中表现为 模型 - 视图 - 控制器,模型封装应用程序的数据和一般他们会组成的POJO(Plain Ordinary Java Object)简单的Java对象,视图(View)是负责呈现模型数据并且一般由它生成HTML输出,客户端浏览器来解析显示,控制器(Controller)负责处理用户的请求,并建立适当的模型,并把它传递给视图渲染。

在Spring MVC中,有一个很重要的类是DispatcherServlet,叫中央前端控制器,所有的请求都由该控制器接受并分发到到合适的处理器,处理器解析请求直接返回Response或者跳转jsp页面,这些过程都要通过中央前端处理器。如图1所示:

接收HTTP请求后,DispatcherServlet 咨询 HandlerMapping 来调用相应的控制器。
该控制器接受请求并调用基于使用GET或POST方法相应的服务方法。服务方法将基于定义的业务逻辑设置模型数据,并返回视图名到DispatcherServlet.
DispatcherServlet将需要帮助的ViewResolver从拾取到该请求所定义的视图。
一旦视图被敲定,DispatcherServlet会传递模型数据是在浏览器上最终呈现的视图。

Spring MVC的基本使用

在java web项目中,都有一个web.xml文件用于配置当前项目,在这里,我们可以通过简单的对比了解Spring MVC的作用在没有使用Spring MVC框架前, 单纯的使用servlet接受网络请求的过程是这样的 :

配置web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<web-app>
<!-- 配置servlet-->
<servlet>

<!-- servlet名称-->
<servlet-name>Sorry</servlet-name>
<!-- 对应servlet要指向的HttpServlet类-->
<servlet-class>moreservlets.SorryServlet</servlet-class>
</servlet>
<!-- 映射servlet到url-->
<servlet-mapping>
<!--这里表示所有以/servlet/开头的请求都会由Sorry这个Servlet来处理-->
<servlet-name> Sorry </servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
</web-app>

不使用SpringMVC时的网络请求

继承HttpServlet类,并复写doGet(),doPost()等方法来处理请求

1
2
3
4
5
6
7
public class SorryServlet extends HttpServlet {  
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String title = "Invoker Servlet Disabled.";
out.println(ServletUtilities.headWithTitle(title) + "<BODY BGCOLOR=/"#FDF5E6/">/n" + "<H2>" + title + "</H2>/n" + "Sorry, access to servlets by means of/n" + "URLs that begin with/n" + "http://host/webAppPrefix/servlet//n" + "has been disabled./n" + "</BODY></HTML>");
}

很明显,如果需求中有很多的请求,那么web.xml文件将会变得臃肿不堪,同时也要写大量的HttpServlet类用于处理请求,不利于代码的维护。

使用Spring mvc

接受网络请求是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
配置web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

<!-- spring 配置文件 默认是/WEB-INF/applicationContext.xml ,在这里可以配置数据库地址,数据库文件,java bean等等-->

<context-param>
<param-name>contextConfigLocation</param-name>
<!-- 默认是/WEB-INF/applicationContext.xml -->
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

<!-- spring mvc的中央前端分发器配置,不同于纯Servlet,所有的网络请求都经过该类然后分发-->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置文件,配置了beans -->
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 默认是/WEB-INF/[servlet名字]-servlet.xml,在这个文件里配置控制器所在的包 -->
<param-value>/WEB-INF/SpringMVC-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<!--同样需要映射url,参数<url-pattern>表示所有的请求都由SpringMVC这个中央前端控制器接受 -->
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<!--转码控制 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

定义控制器:

1
2
3
4
5
6
7
8
9
10
//注解Controller表示这个类是一个控制器
@Controller
public class AppInfoController {
private Logger logger = Logger.getLogger(AppInfoController.class);

//RequestMapping注解表示这个方法处理 /app的请求
@RequestMapping(value = "/app",method = RequestMethod.GET)
public void getAppInfoById(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().append("Hello World");
}

因此使用Spring MVC的话,只需要在web.xml文件中配置DispatcherServlet,然后通过Controller注解一个类为控制器,再通过RequestMapping注解指定某方法可以接受某一类请求即可。这是最简单的使用,Spring MVC还提供很多其他的注解方式,比如ResponseBody注解直接将函数返回值作为Response的body返回,或者直接返回jsp文件名称并跳转页面等,不在赘述。

Hibernate

简介

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,并将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得我们可以使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用, 完成数据持久化的任务。

hibernate使用

在引入Hibernate类库之后,需要完成两个步骤,涉及到两种文件:

1.配置Hibernate

hibernate.cfg.xml 文件:这是hibernate的配置文件,在这里要做的事包括但不限于:
a. 操作的数据库的地址,账户,密码
b. .配置数据库驱动

2.实体类及映射文件

POJO的映射文件。例如有一个AppInfo的模型类,为了使hibernate可以将读出来的数据直接转化为对象,需要创建相对应的AppInfo.hbm.xml文件,下面以AppInfo类为例进行说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//这个是AppInfo model类,要求属性私有,并提供相应的setter和getter
public class AppInfo implements java.io.Serializable {
private static final long serialVersionUID = 1111111111111111111L;

private long id = 0;
private String appId;
public void setId(long id){
this.id=id;
}
public long getId(){
return id;
}
public void setAppId(String appId){
this.appId = appId;
}
public String getAppId(){
return appId;
}
}

对应的AppInfo.hbm.xml文件,其中id标签表示将属性id作为数据库的主键,property标签对应AppInfo类中的appId属性,其他属性以此类推

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="qiyi.vr.app.model">
<class name="AppInfo" table="app_info">

<id name="id" type="java.lang.Long">
<column name="id" />
<generator class="native" />
</id>

<property name="appId" type="java.lang.String">
<column name="app_id" />
</property>
</class>
</hibernate-mapping>

注:关于hbm.xml文件的生成:在MyEclipse中,可以通过根据数据库的字段反向映射来生成hbm.xml文件,但是这样会生成两个hbm.xml文件,具体原因及使用方法未知

3.注册映射文件

在hibernate.cfg.xml文件中注册上面得到的映射文件

1
<mapping resource="qiyi/vr/app/model/AppInfo.hbm.xml" />

4.hibernate与数据库的交互

hibernate与数据库的交互涉及到三个比较重要的类:

SessionFactory:SessionFactory实例对应一个数据存储源,其特点是1.线程安全,同一个SessionFactory可被多个线程共享2.重量级,SessionFactory需要大缓存,缓存中会存储预设的SQL语句,因此,如果只需要访问一个数据库,那么创建一个SessionFactory对象即可

Session:Session是持久化管理器,由SessionFactory生成,其特点是:1线程不安全,session代表和当前数据库之间的一次操作,尽量避免多线程共享session2.轻量级,创建session耗费的资源相对较少3.session又被称为Hibernate的一级缓存,存放当前工作单元加载的对象,使用完毕要关闭session

Transaction:Transaction接口是Hibernate数据库事务接口,Hibernate进行持久化操作时必须进行事务控制,简单说就是具体的数据库操作要在开启事务后进行,然后由事务进行commit,很类似于Android FragmentManager的Transaction。

1
2
3
4
5
6
7
8
9
10
@Override
public long insert(AppInfo entity) throws SQLException {
// TODO Auto-generated method stub
Session session = HibernateSessionFactory.getSession();
Transaction transaction = session.beginTransaction();
session.save(entity);
transaction.commit();
session.close();
return 0;
}