13.2 SQL语法

SQL语句是对所有关系数据库都通用的命令语句,而JDBC API只是执行SQL语句的工具JDBC允许对不同的平台、不同的数据库采用相同的编程接口来执行SQL语句。在开始JDBC编程之前必须掌握基本的SQL知识,本节将以MySQL数据库为例详细介绍SQL语法知识。

提示

除了标准的SQL语句之外,所有的数据库都会在标准SQL语句基础上进行扩展,增加一些额外的功能,这些额外的功能属于特定的数据库系统,不能在所有的数据库系统上都通用。因此,如果想让数据库应用程序可以跨数据库运行,则应该尽量少用这些属于特定数据库的扩展

13.2.2 关系数据库基本概念和MySQL基本命令

严格来说,数据库(Database)仅仅是存放用户数据的地方。当用户访问、操作数据库中的数据时,就需要数据库管理系统的帮助。数据库管理系统的全称是Database Management System,简称DBMS习惯上常常把数据库和数据库管理系统笼统地称为数据库,通常所说的数据库既包括存储用户数据的部分,也包括管理数据库的管理系统。
DBMS是所有数据的知识库,它负责管理数据的存储、安全、一致性、并发、恢复和访问等操作。**DBMS有一个数据字典(有时也被称为系统表),用于存储它拥有的每个事务的相关信息**,例如名字、结构、位置和类型,**这种关于数据的数据也被称为元数据(metadata)**。

对于关系数据库而言,最基本的数据存储单元就是数据表,因此可以简单地把数据库想象成大量数据表的集合

数据表是存储数据的逻辑单元,可以把数据表想象成由行和列组成的表格其中每一行也被称为一条记录每一列也被称为一个字段
为数据库建表时,通常需要指定该表包含多少列,每列的数据类型信息,无须指定该数据表包含多少行——因为数据库表的行是动态改变的,每行用于保存一条用户数据。除此之外,还应该为每个数据表指定一个特殊列,该特殊列的值可以唯一地标识此行的记录,则该特殊列被称为主键列。

查看数据库

show databases;

删除数据库

drop database 数据库名称;

创建数据库

create database if not exists 数据库名称;

进入数据库

use 数据库名称;

查看数据库中的所有表格

show tables;

查看表结构

desc 表名

MySQL存储机制

MySQL数据库通常支持如下两种存储机制。

  1. MyISAM:这是MySQL早期默认的存储机制,对事务支持不够好
  2. InnoDB:**InnoDB提供事务安全的存储机制InnoDB通过建立行级锁来保证事务完整性**,并以Oracle风格的共享锁来处理Select语句。系统默认启动InnoDB存储机制,如果不想使用InnoDB表,则可以使用skip-innodb选项。

如果使用5.0以上版本的MySQL数据库系统,通常无须指定数据表的存储机制,因为系统默认使用InnoDB存储机制。如果需要在建表时显式指定存储机制,则可在标准建表语法的后面添加下面任意一句。
ENGINE=MyISAM–强制使用MyISAM存储机制。
ENGINE=InnoDB–强制使用InnoDB存储机制。

13.1 JDBC基础

JDBC的全称是Java Database Connectivity,即Java数据库连接,它是一种可以执行SQL语句的Java API程序可通过JDBC API连接到关系数据库,并使用结构化查询语言(SQL,数据库标准的查询语言)来完成对数据库的查询、更新。与其他数据库编程环境相比,JDBC为数据库开发提供了标准的API,所以使用JDBC开发的数据库应用可以跨平台运行,而且可以跨数据库(如果全部使用标准的SQL。也就是说,如果使用JDBC开发一个数据库应用,则该应用既可以在Windows平台上运行,也可以在UNIX等其他平台上运行;既可以使用MySQL数据库,也可以使用Oracle等数据库,而程序无须进行任何修改。

13.1.1 JDBC简介

通过使用JDBC,就可以使用同一种API访问不同的数据库系统
JDBC API,它们只是接口,没有提供实现类,这些实现类由各数据库厂商提供实现,这些实现类就是驱动程序。而程序员使用JDBC时只要面向标准的JDBC API编程即可,当需要在数据库之间切换时,只要更换不同的实现类(即更换数据库驱动程序)就行,这是面向接口编程的典型应用。
小结:驱动程序就是JDBC API(接口)的实现类

JDBC功能

JDBC可以完成以下三个基本工作:

  1. 建立与数据库的连接。
  2. 执行SQL语句。
  3. 获得SQL语句的执行结果。

通过JDBC的这三个功能,应用程序即可访问、操作数据库系统。

13.1.2JDBC驱动程序

数据库驱动程序是JDBC程序和数据库之间的转换层,数据库驱动程序负责将JDBC调用映射成特定的数据库调用。
大部分数据库系统,例如OracleMySQL等,都有相应的JDBC驱动程序,当需要连接某个特定的数据库时,必须有相应的数据库驱动程序

第17章 SpringMVC介绍

第16章中,我们学习了现代Web应用程序广泛使用的MVC设计模式,也学习了模型2架构的优势以及如何构建一个模型2应用。Spring MVC框架可以帮助开发人员快速地开发MVC应用。
本章首先介绍采用Spring MVC的好处,以及SpringMVC如何加速模型2应用的开发。然后介绍Spring MVC的基本组件,包括Dispatcher Servlet,并学习如何开发一个“传统风格”的控制器,这是在Spring 2.5版本前开发controller的唯一方式。另一种方式将在第18章“基于注解的控制器”中介绍。之所以介绍传统方式,是因为我们可能不得不在基于旧版Spring的遗留代码上工作。对于新应用,我们可以采用基于注解的控制器。
此外,本章还会介绍Spring MVC配置,大部分的Spring MVC应用会用一个XML文档来定义应用中所用的bean

19.2.10 select标签

select标签渲染一个HTMLselect元素。被渲染元素的选项可能来自赋予其items属性的一个CollectionMapArray,或者来自一个嵌套的option或者options标签。select标签的属性如表19.11所示。表19.11中的所有属性都是可选的,其中不包含HTML属性。

表19.11select标签的属性
属性 描述
cssClass 定义要应用到被渲染input元素的CSS
cssStyle 定义要应用到被渲染input元素的CSS样式
cssErrorClass 定义要应用到被渲染input元素的CSS类,如果bound属性中包含错误,则覆盖cssClass属性值
htmlEscape 接受true或者false,表示是否应该对被渲染的(多个)值进行HTML转义
items 用于生成input元素的对象的CollectionMap或者Array
itemLabelitem 属性中定义的CollectionMap或者Array中的对象属性,为每个input元素提供label
itemValueitem 属性中定义的CollectionMap或者Array中的对象属性,为每个input元素提供值
path 要绑定的属性路径
items属性特别有用,因为它可以绑定到对象的CollectionMapArray,为select元素生成选项。
例如,下面的select标签绑定到form backing objectcategory属性的id属性。它的选项来自model属性categories。每个选项的值均来自categoriescollection/map/arrayid属性,它的Label来自name属性:
1
2
3
<form:select id="category" path="category.id"
items="${categories}" itemLabel="name"
itemValue="id"/>

19.2.11 option标签

option标签渲染select元素中用的一个HTMLoption元素,其属性如表19.12所示。表19.12中的所有属性都是可选的,其中不包含HTML属性。
表19.12option标签的属性

属性 描述
cssClass 定义要应用到被渲染input元素的CSS
cssStyle 定义要应用到被渲染input元素的CSS样式
cssErrorClass 定义要应用到被渲染input元素的CSS类,如果bound属性中包含错误,则覆盖cssClass属性值
htmlEscape 接受true或者false,表示是否应该对被渲染的(多个)值进行HTML转义
例如,下面是一个option标签的范例:
1
2
3
4
5
<form:select id="category" path="category.id"
items="${categories}" itemLabel="name"
itemValue="id">
<option value="0">-- Please select --</option>
</form:select>

这个代码片断是渲染一个select元素,其选项来自model属性categories,以及option标签。

19.2.12 options标签

options标签生成一个HTMLoption元素列表,其属性如表19.13所示,其中不包含HTML属性。

表19.13options标签的属性
属性 描述
cssClass 定义要应用到被渲染input元素的CSS
cssStyle 定义要应用到被渲染input元素的CSS样式
cssErrorClass 定义要应用到被渲染input元素的CSS类,如果bound属性中包含错误,则覆盖cssClass属性值
htmlEscape 接受true或者false,表示是否应该对被渲染的(多个)值进行HTML转义
items 用于生成input元素的对象的CollectionMap或者Array
itemLabelitem 属性中定义的CollectionMap或者Array中的对象属性,为每个input元素提供label
itemValueitem 属性中定义的CollectionMap或者Array中的对象属性,为每个input元素提供值
app19a应用程序展示了一个options标签的范例。

19.2.13 errors标签

errors标签渲染一个或者多个HTMLspan元素,每个span元素中都包含一个字段错误。这个标签可以用于显示一个特定的字段错误,或者所有字段错误。
errors标签的属性如表19.14所示。表19.14中的所有属性都是可选的,其中不包含可能在HTMLspan元素中出现的HTML属性。

表19.14errors标签的属性
属性 描述
cssClass 定义要应用到被渲染input元素的CSS
cssStyle 定义要应用到被渲染input元素的CSS样式
delimiter 分隔多个错误消息的分隔符
element 定义一个包含错误消息的HTML元素
htmlEscape 接受true或者false,表示是否应该对被渲染的(多个)值进行HTML转义
path 要绑定的错误对象路径
例如,下面这个errors标签显示了所有字段错误:
1
<form:errors path="*"/>

下面的errors标签显示了一个与form backing objectauthor属性相关的字段错误:

1
<form:errors path="author"/>

19.2.6 checkbox标签

checkbox标签渲染<input type="checkbox"/>元素。checkbox标签的属性如表19.7所示。表19.7中的所有属性都是可选的,其中不包含HTML属性。

表19.7checkbox标签的属性
属性 描述
cssClass 定义要应用到被渲染input元素的CSS
cssStyle 定义要应用到被渲染input元素的CSS样式
cssErrorClass 定义要应用到被渲染input元素的CSS类,如果bound属性中包含错误,则覆盖cssClass属性值
htmlEscape 接受true或者false,表示是否应该对被渲染的(多个)值进行HTML转义
label 要作为label用于被渲染复选框的值
path 要绑定的属性路径
例如,下面的checkbox标签绑定到outOfStock属性:
1
<form:checkbox path="outOfStock" value="Out of Stock"/>

19.2.7 radiobutton标签

radiobutton标签渲染<input type="radio"/>元素。radiobutton标签的属性如表19.8所示。表19.8中的所有属性都是可选的,其中不包含HTML属性。

表19.8radiobutton标签的属性
属性 描述
cssClass 定义要应用到被渲染input元素的CSS
cssStyle 定义要应用到被渲染input元素的CSS样式
cssErrorClass 定义要应用到被渲染input元素的CSS类,如果bound属性中包含错误,则覆盖cssClass属性值
htmlEscape 接受true或者false,表示是否应该对被渲染的(多个)值进行HTML转义
label 要作为label用于被渲染复选框的值
path 要绑定的属性路径
例如,下列radiobutton标签绑定到newsletter属性:
1
2
3
4
Computing Now <form:radiobutton path="newsletter"
value="Computing Now"/> <br/>
Modern Health <form:radiobutton path="newsletter"
value="Modern Health"/>

19.2.8 checkboxes标签

checkboxes标签渲染多个<input type="checkbox"/>元素。checkboxes标签的属性如表19.9所示。表19.9中的属性都是可选的,其中不包含HTML属性。
例如,下面的checkboxes标签将model属性categoryList的内容渲染为复选框。checkboxes标签允许进行多个选择:

1
<form:checkboxes path="category" items="${categoryList}"/>
表19.9checkboxes标签的属性
属性 描述
cssClass 定义要应用到被渲染input元素的CSS
cssStyle 定义要应用到被渲染input元素的CSS样式
cssErrorClass 定义要应用到被渲染input元素的CSS类,如果bound属性中包含错误,则覆盖cssClass属性值
delimiter 定义两个input元素之间的分隔符,默认没有分隔符
element 给每个被渲染的input元素都定义一个HTML元素,默认为“span
htmlEscape 接受true或者false,表示是否应该对被渲染的(多个)值进行HTML转义
items 用于生成input元素的对象的CollectionMap或者Array
itemLabelitem 属性中定义的CollectionMap或者Array中的对象属性,为每个input元素提供label
itemValueitem 属性中定义的CollectionMap或者Array中的对象属性,为每个input元素提供值
path 要绑定的属性路径

19.2.9 radiobuttons标签

radiobuttons标签渲染多个<input type="radio"/>元素。radiobuttons标签的属性如表19.10所示。

表19.10radiobuttons标签的属性
属性 描述
cssClass 定义要应用到被渲染input元素的CSS
cssStyle 定义要应用到被渲染input元素的CSS样式
cssErrorClass 定义要应用到被渲染input元素的CSS类,如果bound属性中包含错误,则覆盖cssClass属性值
delimiter 定义两个input元素之间的分隔符,默认没有分隔符
element 给每一个被渲染的input元素都定义一个HTML元素,默认为“span
htmlEscape 接受true或者false,表示是否应该对被渲染的(多个)值进行HTML转义
items 用于生成input元素的对象的CollectionMap或者Array
itemLabelitem 属性中定义的CollectionMap或者Array中的对象属性,为每个input元素提供label
itemValueitem 属性中定义的CollectionMap或者Array中的对象属性,为每个input元素提供值
path 要绑定的属性路径

例如,下面的radiobuttons标签将model属性categoryList的内容渲染为单选按钮。每次只能选择一个单选按钮:

1
<form:radiobuttons path="category" items="${categoryList}"/>

19.2.3 password标签

password标签渲染<input type="password"/>元素,其属性见表19.4。password标签与input标签相似,只不过它有一个showPassword属性。

表19.4password标签的属性
属性 描述
cssClass 定义要应用到被渲染input元素的CSS
cssStyle 定义要应用到被渲染input元素的CSS样式
cssErrorClass 定义要应用到被渲染input元素的CSS类,如果bound属性中包含错误,则覆盖cssClass属性值
htmlEscape 接受true或者false,表示是否应该对被渲染的值进行HTML转义
path 要绑定的属性路径
showPassword 表示应该显示或遮盖密码,默认值为false
表19.4中的所有属性都是可选的,这个表中不包含HTML属性。下面举一个password标签的例子:
1
<form:password id="pwd" path="password" cssClass="normal"/>

19.2.4 hidden标签

hidden标签渲染<input type="hidden"/>元素,其属性如表19.5所示。hidden标签与input标签相似,只不过它没有可视的外观,因此不支持cssClasscssStyle属性。

表19.5hidden标签的属性
属性 描述
htmlEscape 接受true或者false,表示是否应该对被渲染的值进行HTML转义
path 要绑定的属性路径

表19.5中的所有属性都是可选的,这个表中不包含HTML属性。
下面举一个hidden标签的例子:

1
<form:hidden path="productId"/>

19.2.5 textarea标签

textarea标签渲染一个HTMLtextarea元素。textarea基本上就是一个支持多行输入的input元素。textarea标签的属性如表19.6所示。表19.6中的所有属性都是可选的,这个表中不包含HTML属性。

属性 描述
cssClass 定义要应用到被渲染input元素的CSS
cssStyle 定义要应用到被渲染input元素的CSS样式
cssErrorClass 定义要应用到被渲染input元素的CSS类,如果bound属性中包含错误,则覆盖cssClass属性值
htmlEscape 接受true或者false,表示是否应该对被渲染的值进行HTML转义
path 要绑定的属性路径
例如,下面的textarea标签就是被绑定到formbacking objectnote属性:
1
<form:textarea path="note" tabindex="4" rows="5" cols="80"/>

19.2.2 input标签

input标签渲染<input type="text"/>元素。**这个标签最重要的属性是path**,它将这个输入字段绑定到formbacking object的一个属性。例如,若随附<form/>标签的commandName属性值为book,并且input标签的path属性值为isbn,那么,input标签将被绑定到Book对象的isbn属性。
表19.3展示了input标签的属性。表19.3中的属性都是可选的,其中不包含HTML属性。

表19.3input标签的属性
属性 描述
cssClass 定义要应用到被渲染input元素的CSS
cssStyle 定义要应用到被渲染input元素的CSS样式
cssErrorClass 定义要应用到被渲染input元素的CSS类,如果bound属性中包含错误,则覆盖cssClass属性值
htmlEscape 接受true或者false,表示是否应该对被渲染的值进行HTML转义
path 要绑定的属性路径

举个例子,下面这个input标签被绑定到formbacking objectisbn属性:

1
<form:input id="isbn" path="isbn" cssErrorClass="errorBox"/>

它将会被渲染成下面的<input/>元素:

1
<input type="text" id="isbn" name="isbn"/>

cssErrorClass属性不起作用,除非isbn属性中有输入验证错误,并且采用同一个表单重新显示用户输入,在这种情况下,input标签就会被渲染成下面这个input元素:

1
<input type="text" id="isbn" name="isbn" class="errorBox"/>

input标签也可以绑定到嵌套对象的属性。例如,下列的input标签绑定到form backing objectcategory属性的id属性:

1
<form:input path="category.id"/>

19.2.1 form标签

form标签用于渲染HTML表单。form标签必须利用渲染表单输入字段的其他任意标签。form标签的属性如表19.2所示。
表19.2中的所有标签都是可选的。这个表中没有包含HTML属性,如methodaction

表19.2form标签的属性
属性 描述
acceptCharset 定义服务器接受的字符编码列表
commandName 显示表单对象之模型属性的名称。默认为command
cssClass 定义要应用到被渲染form元素的CSS
cssStyle 定义要应用到被渲染form元素的CSS样式
htmlEscape 接受true或者false,表示被渲染的值是否应该进行HTML转义
modelAttribute 显示form backing object的模型属性名称。默认为command

commandName属性或许是其中最重要的属性,因为它定义了模型属性的名称,其中包含了一个backingobject,其属性将用于填充所生成的表单。如果该属性存在,则必须在返回包含该表单的视图的请求处理方法中添加相应的模型属性。例如,在本章配套的app19a应用程序中,下列form标签是在BookAddForm.jsp中定义的:

1
2
3
4
<!-- commandName用于指定需要的Model对象中的属性名称 -->
<form:form commandName="book" action="book_save" method="post">
...
</form:form>

BookController类中的inputBook方法,是返回BookAddForm.jsp的请求处理方法。下面就是inputBook方法。

1
2
3
4
5
6
7
8
@RequestMapping(value = "/book_input")
public String inputBook(Model model) {
...
//设置一个book属性到Modle之中
model.addAttribute("book", new Book());
//返回视图名称,也就是BookAddForm.jsp
return "BookAddForm";
}

此处用book属性创建了一个Book对象,并添加到Model。如果没有Model属性,BookAddForm.jsp页面就会抛出异常,因为form标签无法找到在其commandName属性中指定的from backing object
此外,一般来说仍然需要使用actionmethod属性。这两个属性都是HTML属性,因此不在表19.2之列。

1.1 Java EE应用概述

今天所说的Java EE应用,超出了Sun所提出的经典Java EE应用规范,而是一种更泛的开发规范。
经典Java EE应用往往以EJB(企业级JavaBean)为核心,以应用服务器为运行环境,所以开发、运行成本较高。
本书所介绍的Spring MVC+MyBatis作为轻量级Java EE应用不仅具备Java EE规范的种种特征,例如面向对象建模的思维方式、优秀的应用分层及良好的可扩展性、可维护性,而且保留了经典Java EE应用的架构,但其开发、运行成本更低。

1.1.1 Java EE应用的分层模型

不管是经典的Java EE架构,还是本书介绍的轻量级Java EE架构,大致上都可分为如下几层:

领域对象层

领域对象层由一系列的POJO组成,POJOPlain Old Java Object的缩写,也就是普通的、传统的Java对象,这些传统的Java对象是该系统的领域对象,领域对象往往包含了各自所需实现的业务逻辑方法

DAO层

DAOData Access Object的缩写,所以DAO层也叫数据访问对象层DAO层由一系列的DAO组件组成,这些**DAO实现了对数据库的创建、查询、更新和删除(CRUD)等原子操作
注意
在经典Java EE应用中,DAO层也被称为EAO层,EAO层组件的作用与DAO层组件的作用基本相似。只是
EAO层主要完成对实体(Entity)的CRUD操作,因此简称为EAO层**。
DAO层在MyBatis中也被称为Mapper,其通过SQL语句的映射完成CRUD操作。

业务逻辑层

业务逻辑层由一系列的业务逻辑对象组成,这些业务逻辑对象实现了系统所需要的业务逻辑方法。这些业务逻辑方法可能仅仅用于暴露领域对象所实现的业务逻辑方法,也可能是依赖DAO组件实现的业务逻辑方法。

控制器层

控制器层由一系列控制器组成,这些控制器用于拦截用户请求,并调用业务逻辑组件的业务逻辑方法,处理用户请求,并根据处理结果向不同的表现层组件转发

表现层

表现层由一系列的JSP页面、Velocity页面、PDF文档视图组件组成,负责收集用户请求,并显示处理结果
大致上,Java EE应用的架构如图1.1所示。
这里有一张图片
各层的Java EE组件之间以松耦合的方式组织在一起,各组件并不以硬编码方式耦合,这种方式是为了应用以后的扩展性从上向下,上面组件的实现依赖于下面组件的功能;从下向上,下面组件支持上面组件的实现。

1.1.2JavaEE应用的组件

Java EE应用大致包括如下几类组件:

表现层组件

表现层组件主要负责收集用户输入数据,或者向客户显示系统状态。**最常用的表现层技术是JSP**,但JSP并不是唯一的表现层技术。表现层还可由VelocityFreeMarkerTapestry等技术完成,或者使用普通的应用程序充当表现层组件,甚至可以是小型智能设备。

控制器组件

Java EEMVC框架提供了一个前端核心控制器,核心控制器负责拦截用户请求,并将请求转发给用户实现的控制器组件。这些用户实现的控制器组件则负责调用业务逻辑方法,处理用户请求

业务逻辑组件

业务逻辑组件可以实现系统的业务逻辑,是系统的核心组件。通常,一个业务业务逻辑方法对应一次用户操作。一个业务逻辑方法应该是一个整体,因此要求对业务逻辑方法增加事务性。

业务逻辑组件中不应出现持久层API

业务逻辑方法仅仅负责实现业务逻辑,不应该进行数据库访问。因此,业务逻辑组件中不应该出现原始的MyBatisHibernateJDBCAPI
提示
保证业务逻辑组件之中不出现MyBatisHibernateJDBCAPI,有一个更重要的原因:保证业务逻辑方法的实现与具体的持久层访问技术分离。当系统需要在不同持久层技术之间切换时,系统的业务逻辑组件无须任何改变
有时会见到一些所谓的Java EE应用,居然在JSP页面里面调用SqlSessionFactorySqlSessionAPI,这无疑是非常荒唐的,这种应用仅仅是使用MyBatis,完全没有脱离Model1JSP开发模式,这是相当失败的结构。实际上,不仅JSPServlet中也不应出现JDBCMyBatisHibernate等持久层API,**最理想的情况是,业务逻辑组件中都不应出现持久层API

DAO组件

DAO组件的对象比较缺乏变化,每个DAO组件都提供了对领域对象(Domain Object)的创建、查询、更新和删除等基本操作,这些操作对应于数据库的CRUD(创建、查询、更新和删除)等原子操作。当然,如果采用不同的持久层访问技术,DAO组件的实现会完全不同。为了业务逻辑组件的实现与DAO组件的实现实现分离,程序应该为每个DAO组件都提供接口,业务逻辑组件面向DAO接口编程,这样才能提供更好的解耦

领域对象组件

领域对象(Domain Object)抽象了系统的对象模型。

领域对象 对应 数据库表

通常而言,这些领域对象的状态都必须保存在数据库里。因此,每个领域对象通常对应一个或多个数据表,领域对象通常需要提供对数据记录的访问方式

1.1.3 Java EE应用的结构和优势

作为Java EE的初学者,常常有一个问题:明明可以使用JSP完成这个系统,为什么还要使用MyBatisHibernate等技术?难道仅仅是为了听起来高深一些?明明可以使用纯粹的JSP完成整个系统,为什么还要将系统分层?
要回答这些问题,就不能仅仅考虑系统开发过程,还需要考虑系统后期的维护扩展;而且不能仅仅考虑小型系统,还要考虑大型系统的协同开发。如果是用于个人学习、娱乐的个人站点,的确没有必要使用复杂的Java EE应用架构,采用纯粹的JSP就可以实现整个系统。
对于大型的信息化系统,采用Java EE应用架构则有很大的优势

维护升级要求

对于信息化系统,前期开发工作对整个系统工作量而言,仅仅是小部分,而后期的维护、升级往往占更大的比重。

扩展性要求

更极端的情况是,可能在前期开发期间,企业需求已经发生变化,而这种改变是客观的,软件系统必须适应这种改变,这要求软件系统具有很好的扩展性

松耦合

这种框架结构其目的是让应用的各组件以松耦合的方式组织在一起,让应用之间的耦合停留在接口层次,而不是代码层次

1.0 本章概述

本章要点

  • Java EE应用的基础知识
  • Java EE应用的模型和相关组件
  • Java EE应用的结构和优势
  • 轻量级Java EE应用的相关技术

引言

时至今日,轻量级Java EE平台在企业开发中占有绝对的优势,Java EE应用以其稳定的性能、良好的开放性以及严格的安全性,深受企业应用开发者的青睐。实际上,对于信息化要求较高的行业,如银行、电信、证券以及电子商务等,都不约而同地选择了Java EE作为开发平台
对于一个企业而言,选择Java EE构建信息化平台,更体现了一种长远的规划:企业的信息化是不断整合的过程,在未来的日子里,经常会有不同平台、不同的异构系统需要整合。Java EE应用提供的跨平台、开放性以及各种远程访问技术,为异构系统的良好整合提供了保证。
一些有高并发、高稳定要求的电商网站(如淘宝、京东等),公司创立之初并没有采用Java EE技术架构(淘宝早期用PHP,京东早期用.NET),但当公司的业务一旦真正开始,他们马上就发现PHP.NET无法支撑公司业务运营,立即全部改为使用Java EE技术架构。就目前的局面来看,Java EE已绎成为真正企业级应用的不二之选。