Java Web开发笔记(2016-5-6 11:13、2016-5-10 11:13、2016-5-12 14:58)

20160518添加:
Java Web项目打包:
E:\apache-tomcat-7.0.65\webapps\EquipmentSys1>jar -cvf EquipmentSys1.war *

Xftp 4
product key:
101210-450789-147200
20160507添加:
/*
JAVA发送HTTP请求,返回HTTP响应内容
请求类HttpRequester类封装了JAVA实现简单请求的代码。
响应对象HttpRespons其实只是一个数据BEAN,由此来封装请求响应的结果数据。
I:\Java14>javac HttpTest.java

I:\Java14>java HttpTest
http://www.biliongjoy.com:8080/EquipmentSys/equipment/findByEquipmentNumber.html
?DEVEICEID=04:e6:76:df:de:72
http
www.biliongjoy.com
8080
GBK
GET
Dragon, http://www.biliongjoy.com:8080/resource/resources/201603272200554792016.apk,1.1,http://www.biliongjoy.com:8080/resource/ConfigListTxt/92.txt
*/

import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.InputStream;  
import java.io.InputStreamReader;  
import java.net.HttpURLConnection;  
import java.net.URL;  
import java.nio.charset.Charset;  
import java.util.Map;  
import java.util.Vector;  

/** 
 * HTTP请求对象 
 *  
 * @author YYmmiinngg 
 */  
class HttpRequester {  
    private String defaultContentEncoding;  

    public HttpRequester() {  
        this.defaultContentEncoding = Charset.defaultCharset().name();  
    }  

    /** 
     * 发送GET请求 
     *  
     * @param urlString 
     *            URL地址 
     * @return 响应对象 
     * @throws IOException 
     */  
    public HttpRespons sendGet(String urlString) throws IOException {  
        return this.send(urlString, "GET", null, null);  
    }  

    /** 
     * 发送GET请求 
     *  
     * @param urlString 
     *            URL地址 
     * @param params 
     *            参数集合 
     * @return 响应对象 
     * @throws IOException 
     */  
    public HttpRespons sendGet(String urlString, Map<String, String> params)  
            throws IOException {  
        return this.send(urlString, "GET", params, null);  
    }  

    /** 
     * 发送GET请求 
     *  
     * @param urlString 
     *            URL地址 
     * @param params 
     *            参数集合 
     * @param propertys 
     *            请求属性 
     * @return 响应对象 
     * @throws IOException 
     */  
    public HttpRespons sendGet(String urlString, Map<String, String> params,  
            Map<String, String> propertys) throws IOException {  
        return this.send(urlString, "GET", params, propertys);  
    }  

    /** 
     * 发送POST请求 
     *  
     * @param urlString 
     *            URL地址 
     * @return 响应对象 
     * @throws IOException 
     */  
    public HttpRespons sendPost(String urlString) throws IOException {  
        return this.send(urlString, "POST", null, null);  
    }  

    /** 
     * 发送POST请求 
     *  
     * @param urlString 
     *            URL地址 
     * @param params 
     *            参数集合 
     * @return 响应对象 
     * @throws IOException 
     */  
    public HttpRespons sendPost(String urlString, Map<String, String> params)  
            throws IOException {  
        return this.send(urlString, "POST", params, null);  
    }  

    /** 
     * 发送POST请求 
     *  
     * @param urlString 
     *            URL地址 
     * @param params 
     *            参数集合 
     * @param propertys 
     *            请求属性 
     * @return 响应对象 
     * @throws IOException 
     */  
    public HttpRespons sendPost(String urlString, Map<String, String> params,  
            Map<String, String> propertys) throws IOException {  
        return this.send(urlString, "POST", params, propertys);  
    }  

    /** 
     * 发送HTTP请求 
     *  
     * @param urlString 
     * @return 响映对象 
     * @throws IOException 
     */  
    private HttpRespons send(String urlString, String method,  
            Map<String, String> parameters, Map<String, String> propertys)  
            throws IOException {  
        HttpURLConnection urlConnection = null;  

        if (method.equalsIgnoreCase("GET") && parameters != null) {  
            StringBuffer param = new StringBuffer();  
            int i = 0;  
            for (String key : parameters.keySet()) {  
                if (i == 0)  
                    param.append("?");  
                else  
                    param.append("&");  
                param.append(key).append("=").append(parameters.get(key));  
                i++;  
            }  
            urlString += param;  
        }  
        URL url = new URL(urlString);  
        urlConnection = (HttpURLConnection) url.openConnection();  

        urlConnection.setRequestMethod(method);  
        urlConnection.setDoOutput(true);  
        urlConnection.setDoInput(true);  
        urlConnection.setUseCaches(false);  

        if (propertys != null)  
            for (String key : propertys.keySet()) {  
                urlConnection.addRequestProperty(key, propertys.get(key));  
            }  

        if (method.equalsIgnoreCase("POST") && parameters != null) {  
            StringBuffer param = new StringBuffer();  
            for (String key : parameters.keySet()) {  
                param.append("&");  
                param.append(key).append("=").append(parameters.get(key));  
            }  
            urlConnection.getOutputStream().write(param.toString().getBytes());  
            urlConnection.getOutputStream().flush();  
            urlConnection.getOutputStream().close();  
        }  

        return this.makeContent(urlString, urlConnection);  
    }  

    /** 
     * 得到响应对象 
     *  
     * @param urlConnection 
     * @return 响应对象 
     * @throws IOException 
     */  
    private HttpRespons makeContent(String urlString,  
            HttpURLConnection urlConnection) throws IOException {  
        HttpRespons httpResponser = new HttpRespons();  
        try {  
            InputStream in = urlConnection.getInputStream();  
            BufferedReader bufferedReader = new BufferedReader(  
                    new InputStreamReader(in));  
            httpResponser.contentCollection = new Vector<String>();  
            StringBuffer temp = new StringBuffer();  
            String line = bufferedReader.readLine();  
            while (line != null) {  
                httpResponser.contentCollection.add(line);  
                temp.append(line).append("\r\n");  
                line = bufferedReader.readLine();  
            }  
            bufferedReader.close();  

            String ecod = urlConnection.getContentEncoding();  
            if (ecod == null)  
                ecod = this.defaultContentEncoding;  

            httpResponser.urlString = urlString;  

            httpResponser.defaultPort = urlConnection.getURL().getDefaultPort();  
            httpResponser.file = urlConnection.getURL().getFile();  
            httpResponser.host = urlConnection.getURL().getHost();  
            httpResponser.path = urlConnection.getURL().getPath();  
            httpResponser.port = urlConnection.getURL().getPort();  
            httpResponser.protocol = urlConnection.getURL().getProtocol();  
            httpResponser.query = urlConnection.getURL().getQuery();  
            httpResponser.ref = urlConnection.getURL().getRef();  
            httpResponser.userInfo = urlConnection.getURL().getUserInfo();  

            httpResponser.content = new String(temp.toString().getBytes(), ecod);  
            httpResponser.contentEncoding = ecod;  
            httpResponser.code = urlConnection.getResponseCode();  
            httpResponser.message = urlConnection.getResponseMessage();  
            httpResponser.contentType = urlConnection.getContentType();  
            httpResponser.method = urlConnection.getRequestMethod();  
            httpResponser.connectTimeout = urlConnection.getConnectTimeout();  
            httpResponser.readTimeout = urlConnection.getReadTimeout();  

            return httpResponser;  
        } catch (IOException e) {  
            throw e;  
        } finally {  
            if (urlConnection != null)  
                urlConnection.disconnect();  
        }  
    }  

    /** 
     * 默认的响应字符集 
     */  
    public String getDefaultContentEncoding() {  
        return this.defaultContentEncoding;  
    }  

    /** 
     * 设置默认的响应字符集 
     */  
    public void setDefaultContentEncoding(String defaultContentEncoding) {  
        this.defaultContentEncoding = defaultContentEncoding;  
    }  

//import java.util.Vector;  

/** 
 * 响应对象 
 */  
class HttpRespons {  

    String urlString;  

    int defaultPort;  

    String file;  

    String host;  

    String path;  

    int port;  

    String protocol;  

    String query;  

    String ref;  

    String userInfo;  

    String contentEncoding;  

    String content;  

    String contentType;  

    int code;  

    String message;  

    String method;  

    int connectTimeout;  

    int readTimeout;  

    Vector<String> contentCollection;  

    public String getContent() {  
        return content;  
    }  

    public String getContentType() {  
        return contentType;  
    }  

    public int getCode() {  
        return code;  
    }  

    public String getMessage() {  
        return message;  
    }  

    public Vector<String> getContentCollection() {  
        return contentCollection;  
    }  

    public String getContentEncoding() {  
        return contentEncoding;  
    }  

    public String getMethod() {  
        return method;  
    }  

    public int getConnectTimeout() {  
        return connectTimeout;  
    }  

    public int getReadTimeout() {  
        return readTimeout;  
    }  

    public String getUrlString() {  
        return urlString;  
    }  

    public int getDefaultPort() {  
        return defaultPort;  
    }  

    public String getFile() {  
        return file;  
    }  

    public String getHost() {  
        return host;  
    }  

    public String getPath() {  
        return path;  
    }  

    public int getPort() {  
        return port;  
    }  

    public String getProtocol() {  
        return protocol;  
    }  

    public String getQuery() {  
        return query;  
    }  

    public String getRef() {  
        return ref;  
    }  

    public String getUserInfo() {  
        return userInfo;  
    }  


public class HttpTest {  
    public static void main(String[] args) {  
        try {  
            HttpRequester request = new HttpRequester();  
            //HttpRespons hr = request.sendGet(" http://www.jb51.net");
            HttpRespons hr = request.sendGet(" http://www.biliongjoy.com:8080/EquipmentSys/equipment/findByEquipmentNumber.html?DEVEICEID=04:e6:76:df:de:72");

            System.out.println(hr.getUrlString());  
            System.out.println(hr.getProtocol());  
            System.out.println(hr.getHost());  
            System.out.println(hr.getPort());  
            System.out.println(hr.getContentEncoding());  
            System.out.println(hr.getMethod());  

            System.out.println(hr.getContent());  

        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}  


http://localhost:8080/EquipmentSys/equipment/findEquipStateByEquipmentNumber.html?DEVEICEID=04:e6:76:df:f0:94
返回
1,1
设备状态(1运营,2维护,3锁定),是否更新的开关IsUpdate={1,0}(游戏APK更新条件:IsUpdate=1而且版本号不一样)
 /**
  * 接口
  * @param request
  * @return
  * @throws UnsupportedEncodingException
  */
 @RequestMapping(value="/findEquipStateByEquipmentNumber",produces="text/html;charset=UTF-8")
 @ResponseBody
 public String findEquipStateByEquipmentNumber( HttpServletRequest request ) throws UnsupportedEncodingException{
  String number = request.getParameter("DEVEICEID");
  TbEquipment equipment = equipmentService.queryEquipmentByNumber(number);
  TbEqGamesInfo eqGamesInfo = null;
  TbEquipmentConfiglist equipmentConfiglist = null;
  TbConfigList configList = null;
  TbResources resources = null;
  Integer eid = null;
  StringBuffer sbBuffer = new StringBuffer();
  
  if( equipment != null ){
   eid = equipment.getId();
   eqGamesInfo = eqGamesInfoService.queryEqGamesInfoByEquipmentId(eid);  
   if( eqGamesInfo != null ){
    sbBuffer.append(equipment.getStatus()+","+eqGamesInfo.getIsUpdate());
   }
   else{
    sbBuffer.append("unable");
   }
  }else{ 
   sbBuffer.append("unable");
  }
  return sbBuffer.toString();
 }

加字段:
ALTER TABLE tb_eq_games_info ADD COLUMN `isUpdate` TINYINT(4) DEFAULT 1  COMMENT '是否更新'

SQL语句和HQL语句:
0、
SELECT * FROM tb_sys_account WHERE 1=1 AND loginName='admin' AND loginPwd='202cb962ac59075b964b07152d234b70'
1、
SELECT * FROM tb_equipment WHERE number='04:e6:76:df:de:72' AND STATUS=1
2016-05-12 14:42:07,385 [com.poobo.base.impl.BaseDaoImpl]-[INFO] hql= from TbEquipment where number='04:e6:76:df:de:72' and status=1
2016-05-12 14:42:07,839 [com.poobo.base.impl.BaseDaoImpl]-[INFO] 设备Id=701
2A、
SELECT * FROM tb_eq_games_info WHERE eqid=701 AND isDefault=1
2016-05-12 15:17:50,214 [com.poobo.base.impl.BaseDaoImpl]-[INFO] hql=from TbEqGamesInfo where eqid=701 and isDefault=1
2016-05-12 15:17:50,220 [com.poobo.base.impl.BaseDaoImpl]-[INFO] 设备游戏信息没找到
2B、
http://localhost:8080/EquipmentSys/equipment/findByEquipmentNumber.html?DEVEICEID=04:e6:76:df:e5:f8
2016-05-12 15:23:01,341 [com.poobo.base.impl.BaseDaoImpl]-[INFO] hql=from TbEqGamesInfo where eqid=207 and isDefault=1
2016-05-12 15:23:01,347 [com.poobo.base.impl.BaseDaoImpl]-[INFO] 设备游戏信息id=661
SELECT * FROM tb_eq_games_info WHERE eqid=207 AND isDefault=1
3、
2016-05-12 15:40:47,103 [com.poobo.base.impl.BaseDaoImpl]-[INFO] hql= from TbEquipmentConfiglist where eid=207
2016-05-12 15:40:47,109 [com.poobo.base.impl.BaseDaoImpl]-[INFO] 设备配置列表id=356
SELECT * FROM tb_equipment_configlist WHERE eid=207
4、
Reid = 225
资源名称 = Dragon
服务器资源名称 = http://www.biliongjoy.com:8080/resource/resources/201603272200554792016.apk
游戏版本号= 1.1
配置列表id = 92
配置列表名称 = 出厂配置(驯龙广告片)

2016-05-11 16:50:06,959 [org.hibernate.hql.internal.ast.HqlSqlWalker]-[WARN] [DEPRECATION] Encountered positional parameter near line 1, column 60 in HQL: [from com.poobo.entity.TbSysAccount where 1=1 and loginName=? and loginPwd=?].  Positional parameter are considered deprecated; use named parameters or JPA-style positional parameters instead.
2016-05-11 16:50:06,961 [org.hibernate.hql.internal.ast.HqlSqlWalker]-[WARN] [DEPRECATION] Encountered positional parameter near line 1, column 75 in HQL: [from com.poobo.entity.TbSysAccount where 1=1 and loginName=? and loginPwd=?].  Positional parameter are considered deprecated; use named parameters or JPA-style positional parameters instead.
Hibernate: select tbsysaccou0_.ID as ID1_6_, tbsysaccou0_.name as name2_6_, tbsysaccou0_.loginName as loginNam3_6_, tbsysaccou0_.loginPwd as loginPwd4_6_, tbsysaccou0_.createDate as createDa5_6_, tbsysaccou0_.status as status6_6_ from equipmentsysdb.tb_sys_account tbsysaccou0_ where 1=1 and tbsysaccou0_.loginName=? and tbsysaccou0_.loginPwd=?
2016-05-11 16:50:07,180 [com.poobo.controller.SysAccountCtr]-[INFO] admin成功登陆!
Hibernate: select count(*) as col_0_0_ from equipmentsysdb.tb_sys_log tbsyslog0_ where 1=1
Hibernate: select tbsyslog0_.id as id1_7_, tbsyslog0_.exceptionMthod as exceptio2_7_, tbsyslog0_.mthodDesc as mthodDes3_7_, tbsyslog0_.acitionLoginName as acitionL4_7_, tbsyslog0_.loginNameIp as loginNam5_7_, tbsyslog0_.mthodParams as mthodPar6_7_, tbsyslog0_.createDate as createDa7_7_ from equipmentsysdb.tb_sys_log tbsyslog0_ where 1=1 order by tbsyslog0_.id desc limit ?



http://download.csdn.net/detail/db2_oracle/5030458#comment
轻量级J2EE企业应用实战——Structs+Spring+Hibernate整合开发
李刚 著
2007年4月第1次印刷
chap4 使用Hibernate完成持久化
4.1 ORM简介
4.2 Hibernate概述
4.3 Hibernate的安装和使用
Hibernate目前[2007年]的最新版本是3.1.2。
PO(Persistent Object)持久化对象的作用是完成持久化操作。
为了使POJO具备持久化操作的能力,Hibernate应采用XML映射文件。
项目中的Hibernate映射文件TbConfigList.hbm.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
" http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<!--hibernate-mapping是映射文件的根元素-->
<hibernate-mapping>
<!--每个class元素对应一个持久化对象-->
    <class name="com.poobo.entity.TbConfigList" table="tb_config_list" catalog="equipmentsysdb">
<!--id元素定义持久化类的标识属性-->
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="identity" />
        </id>
<!--property元素定义常规属性-->
        <property name="name" type="java.lang.String">
            <column name="name" length="50" />
        </property>
        <property name="isEnable" type="java.lang.Short">
            <column name="isEnable" />
        </property>
        <property name="isGenerationTxt" type="java.lang.Short">
            <column name="isGenerationTxt" />
        </property>
        <property name="listUrl" type="java.lang.String">
            <column name="listUrl" length="255" />
        </property>
    </class>
</hibernate-mapping>
PO=POJO+映射文件
Hibernate管理数据库的配置——连接数据库所需的用户名、密码及数据库名等等基本信息
连接所需的基本配置信息可通过.properties的属性文件来配置。
PO只有在Session的管理下才可完成数据库访问。
对PO的操作必须在Session管理下才能与数据库同步,Session由SessionFactory厂商提供,
SessionFactory是数据库编译后的内存镜像,通常一个应用对应一个SessionFactory对象。
4.4 Hibernate的基本映射
4.5 Hibernate的关系映射
4.6 Hibernate查询体系
Hibernate通过了异常强大的查询体系,有多种查询方式可以供我们使用。如Hibernate的HQL查询或者使用条件查询,甚至可以使用原生的SQL查询语句等。另外还提供了一种数据过滤功能,这些都用于筛选目标数据。
SQL的操作对象是数据表和列等数据对象;而HQL的操作对象是类、实例和属性等。
HQL是完全面向对象的查询语言,因此可以支持继承和多态等特征。
HQL查询依赖于Query类,每个Query实例对应一个查询对象,使用HQL查询按如下步骤进行:
(1)获取Hibernate Session对象;
@Autowired
private SessionFactory sessionFactory;

private Session session;

public void setSession(Session session) {
this.session = session;
}
public Session getSession() {
return sessionFactory.getCurrentSession();
}
(2)编写HQL语句;
(3)以HQL语句作为参数,调用Session的createQuery方法创建查询对象;
(4)如果HQL语句包含参数,调用Query的setXxx方法为参数赋值;
/**
* 根据hql语句更新对象
* @param hql
*/
public void updateByHql(String hql, Object[] objects) {
if (!hql.equals("")) {
Query query = getSession().createQuery(hql);
for (int i = 0; i < objects.length; i++) {
query.setParameter(i, objects[i]);
}
query.executeUpdate();
}
}

(5)调用Query对象的list等方法遍历查询结果。
/**
* 根据hql查询数据
* @param hql
* @return
*/
public List<?> findAll(String hql) {
if (!hql.equals("")) {
Session session = sessionFactory.getCurrentSession();
return session.createQuery(hql).list();
}
return null;
}
Query还包含两个方法:
setFirstResult设置返回的结果集从第几条记录开始
setMaxResults设置本次查询返回的结果数
这两个方法用于实现Hibernate分页。

项目中数据库equipmentsysdb的8个表|8个持久化类:
tb_config_list|TbConfigList
tb_eq_games_info|TbEqGamesInfo
tb_equipment|TbEquipment
tb_equipment_configlist|TbEquipmentConfiglist
tb_resources|TbResources
tb_resources_config|TbResourcesConfig
tb_sys_account|TbSysAccount
tb_sys_log|TbSysLog
系统用户信息,包含用户昵称、用户账号、用户注册时间(初始化时间)、用户状态(是否禁用)
equipmentsysdb.tb_sys_account
ID
name
loginName
loginPwd
createDate
status

设备信息,包含设备编号、店主ID、运营地址、设备状态、设备别名、创建时间
equipmentsysdb.tb_equipment
ID
number
shopId
address
status
createDate
name

资源信息,包含资源名称、资源类型、服务器资源名称、资源后缀名、游戏版本号
equipmentsysdb.tb_resources
ID
NAME
type
path
lastName
isConfigRange
version
配置列表信息,包含列表名称、是否可配置
equipmentsysdb.tb_config_list
ID
name
isEnable
isGenerationTxt
listUrl

资源配置信息,包含资源名称、资源类型、播放顺序、执行星期、开始时间、结束时间、其他播放时间(秒)、特殊播放
equipmentsysdb.tb_resources_config
ID
configId
resourcesId
DisplayOrder
DateCompany
ActionDate
isAlone
endDate
week
seconds
isSpecial
dayOne
dayTwo
dayThree
dayFour
dayFive
isLive
url

设备配置列表信息,包含设备编号、配置列表名称
equipmentsysdb.tb_equipment_configlist
ID
eId
configListId

设备游戏配置信息,包含设备编号、游戏名称、是否默认
equipmentsysdb.tb_eq_games_info
ID
eqid
reid
isDefault

系统日志信息,包含操作描述、操作人、操作人IP、执行时间
equipmentsysdb.tb_sys_log
id
exceptionMthod
mthodDesc
acitionLoginName
loginNameIp
mthodParams
createDate
 
下面简单介绍HQL语句的语法[项目中的8个XxxDaoImpl类大量用到了]。
HQL语句本身不区分大小写,但HQL语句中所使用的包名、类名、实例名及属性名都区分大小写。
1、from子句
from关键字后紧跟持久化类的类名。
命名别名时,as关键字是可选的,但为了增强可读性,建议保留。from后还可以同时出现多个持久化类,此时将产生一个笛卡尔积或跨表的连接。
2、select子句
select选择的属性必须是from后持久化类包含的属性。
3、聚集函数
HQL也支持在选出的属性上使用聚集函数。HQL支持的聚集函数与SQL完全相同,有如下5种:
avg:计算属性平均值
count:统计选择对象的数量
max:统计属性值的最大值
min:统计属性值的最小值
sum:计算属性值得总和
4、多态查询
HQL语句被设计成能理解为多态查询,其from后跟的持久化类名不仅会查询出该持久化类的全部实例,还会查询出该类中子类的全部实例。
5、where子句
where子句用于筛选选中的结果,以缩小选择的范围。
6、表达式
不仅包括SQL的运算符,也包括EJB-QL的运算符等。
7、order by子句
8、group by子句
9、子查询
10、fetch关键字
11、命名查询

Hibernate还支持使用SQL查询。
SQLQuery接口是Query接口的子接口,因此完全可以调用Query接口的方法。
例如:
setFirstResult
setMaxResults
list
但SQLQuery比Query多了两个重载的方法。
addEntity
addScalar
执行SQL查询的步骤如下:
(1)获取Hibernate Session对象;
(2)编写SQL语句;
(3)以SQL语句作为参数,调用Session的createSQLQuery方法创建查询对象;
/**
* 根据sql查询
*/
public <E> List<E> querySQL(String sql) {
return getSession().createSQLQuery(sql).list();
}
(4)如果SQL语句包含参数,调用Query的setXxx方法为参数赋值;
public void execSql(String sql, Object... obj) {
Query query = getSession().createSQLQuery(sql);
if (obj != null && obj.length > 0) {
for (int i = 0; i < obj.length; i++) {
query.setParameter(i, obj[i]);
}
}
query.executeUpdate();
}
(5)调用SQLQuery对象的addEntity或addScalar方法,将选出的结果与实体或标量值关联。
(6)调用Query的list方法返回查询的结果集。
4.7 事件框架
Hibernate的事件框架由以下两个部分组成:
拦截器机制:对于特定动作拦截,回调应用中的特定动作。
事件系统:重写Hibernate的事件监听器。
P484
10.1.5系统的功能模块
通常建议按细粒度的模块来设计Service组件,使每个Service组件Facade多个DAO组件;每个Service组件包含模块内的业务方法。
本系统主要有8个DAO对象。
XxxDaoImpl:提供对xxx表的基本操作。
10.2 Hibernate持久层
可以避免使用JDBC操作数据库。
10.2.1设计持久化对象(PO)
本系统一共设计了如下8个PO。
 
Java Web开发实战经典基础篇(JSP、Servlet、Struts、Ajax)
李兴华 王月清 编著
2010年8月第1版
第1章 Java Web开发简介
1.1Web发展历程
静态Web处理流程:
Web浏览器发送HTTP请求到Web服务器后收到HTTP回应。
1995年,SUN公司推出Applet程序
Applet程序属于胖客户端程序
Web浏览器植入JVM
动态Web流程图:
客户端不需要JVM的支持了
HTTP请求通过Web服务插件进行接收,区分用户发出的请求是动态请求还是静态请求。
动态请求交给Web容器进行处理,在Web容器中将会采用拼凑代码的形式(主要是拼凑HTML)动态生成数据并通过Web服务器发送给客户端浏览器。
想要实现一个动态Web,可以采用如下5种方式:
CGI
PHP
ASP
ASP.NET
JSP
1.2企业开发架构
现在的开发往往都会通过中间件进行过渡,即程序运行在中间件上,并且通过中间件进行数据库的操作,而具体一些相关的处理,如事务、安全等完全由中间件负责,这样程序员只需要负责具体功能的开发即可。
企业开发的核心架构:
开发平台:如Java EE
中间件:如Tomcat、JBoss、WebLogic
数据库:如DB2、Oracle、MySQL
操作系统:如Linux、UNIX、Windows
1.3 Java EE架构
Java EE(2005年之前称为J2EE)是在Java SE基础之上建立起来的一种标准开发架构,主要用于企业级应用程序的开发。
.NET开发架构也是由Java EE而来。

Java EE主要由容器、组件和服务三大核心部分构成。
1、Java EE容器
容器负责一种组件的运行,在Java EE中一共提供了4种容器,即Applet Container、Application Client Container、Web Container和EJB Container。
2、Java EE组件
每一种Java EE组件实际上都表示一种程序的开发。
每一种容器中都运行各自的组件。
Web容器中运行的是JSP和Servlet组件。
3、Java EE服务
主要服务有如下几种。
HTTP
RMI-IIOP
Java IDL
JTA
JDBC
JMS
JavaMail
JAF
JNDI
JAXP
JCA
JAAS
JSF
JSTL
Web服务组件
1.4 Java EE核心设计模式
在整个Java EE中最核心的设计模式就是MVC设计模式。
显示层:Web浏览器-HTML Doc-JSP页面
控制层:Servlet
模型层:EJB、JavaBean
持久层:数据库
1.5 Struts开发框架
Apache专门提供了一套用于进行MVC开发的框架——Struts。
Struts框架的主要作用还是在Web层上,也就是说Struts是对JSP和Servlet的一种变相应用。
第4章 Tomcat服务器的安装及配置
4.1 Web容器简介
要想运行一个Java Web的程序,则必须有相应的Web容器支持,所有的程序代码要在Web容器中执行,并将最后的结果交付给用户使用。
4.2 Tomcat简介
本书使用的是Tomcat 6.x版本的服务器,直接选择下载Windows安装版即可。[项目中用的是7.x]
使用Tomcat时必须有JDK的支持,本书所使用的JDK版本是jdk-6u2-windows-i586-p.exe。[
项目中用的是1.7 ]
Tomcat主要目录的作用
bin|所有的可执行命令,启动和关闭服务器的命令就在此文件夹之中
conf|服务器的配置文件夹,其中保存了各个配置信息
lib|Tomcat服务器所需要的各个库文件
logs|保存服务器的系统日志
webapps|Web应用程序存放的目录,Web项目保存到此目录中即可发布
work|临时文件夹,生成所有的临时文件(*.java、*.class)
服务器安装完成后,即可通过Tomcat中bin目录下的tomcat6.exe[项目中是tomcat7.exe]命令启动Tomcat服务器。
4.3.3服务器配置
1、修改端口号
打开Tomcat目录中的conf/server.xml文件,将port=”8080”定义的内容修改即可。
注意:配置文件修改后服务器必须重新启动。
2、配置虚拟目录
每一个虚拟目录都保存了一个完整的Web项目。
可以从Tomcat安装目录下的webapps\ROOT\WEB-INF文件夹中找到web.xml文件。
打开conf/server.xml文件,
<Content>是一个固定的标记,表示配置虚拟目录,其中两个参数的意义分别介绍如下。
path:表示浏览器上的访问虚拟路径名称,前面必须加上/
docBase:表示此虚拟路径名称所代表的真实路径地址。
一个Tomcat服务器可以配置多个虚拟目录,但是path不能重名。
HTTP状态码说明
404属于客户端发生的错误,一般都是由于路径输入不正确造成的。
500表示服务器的程序出错。
状态码|表示的含义
2xx|请求成功
3xx|重定向
4xx|客户机中出现的错误
403|禁止——即使有授权也不需要访问
404|服务器找不到指定的资源,文档不存在
5xx|服务器中出现的错误
500|服务器内部错误——因为意外情况,服务器不能完成请求。

所谓的JSP程序代码开发是指在HTML中嵌入大量的Java代码而已。
JSP在第一次执行时会首先将*.jsp文件翻译成*.java文件,然后再将*.java编译成*.class文件后才执行的。
最后真正执行的文件还是以*.class文件格式为主的。
第二次执行时,已经生成好了相应的*.class文件,所以直接执行即可,因此执行速度会变快。

chap6 JSP内置对象 
JSP提供了9个内置对象,这些内置对象将由容器为用户进行实例化,用户直接使用即可,而不用像在Java中那样,必须通过关键字new进行实例化对象后才可以使用。
内置对象|类型|描述
pageContext|javax.servlet.jsp.PageContent|JSP的页面容器
request|javax.servlet.http.HttpServletRequest|得到用户的请求信息
response|javax.servlet.http.HttpServletResponse|服务器向客户端的回应信息
session|javax.servlet.http.HttpSession|用来保护每一个用户的信息
application|javax.servlet.ServletContext|表示所有用户的共享信息
config|javax.servlet.ServletConfig|服务器配置,可以取得初始化参数
out|javax.servlet.jsp.JspWriter|页面输出
page|java.lang.Object|表示从该页面中表示出来的一个Servlet实例
exception|java.lang.Throwable|表示JSP页面所发生的异常,在错误页中才起作用
以上的9个内置对象中比较常用的是pageContext、request、response、session、application,掌握了这5个内置对象,即可进行程序开发。
 
在JSP中提供了4种属性的保存范围。
page:只在一个页面中保存属性,跳转之后无效。
request:只在一次请求中保存,服务器跳转后依然有效。
session:在一次会话范围中,无论何种跳转都可以使用,但是新开浏览器无法使用。
application:在整个服务器上保存,所有用户都可以使用。
以上的4个内置对象都支持的属性操作方法:
setAttribute、getAttribute、removeAttribute

request属性范围:
跳转到配置列表页面时
if( configList.getIsEnable() != null ){
if( configList.getIsEnable() == 1 ){
request.setAttribute("isEnable","是");
}else if( configList.getIsEnable() == 0 ){
request.setAttribute("isEnable","否");
}else{
request.setAttribute("isEnable","");
}
session属性范围:
成功登录时
request.getSession().setAttribute(WebConstants.CURRENT_USER, _sysAccount.get(0));
系统用户登出时
TbSysAccount tbSysAccount=(TbSysAccount) request.getSession().getAttribute(WebConstants.CURRENT_USER);
if(tbSysAccount!=null){
request.getSession().removeAttribute(WebConstants.CURRENT_USER);
log.info("用户:"+tbSysAccount.getName()+"退出成功");
}else{
System.out.println("当前没有登录");
}

ServletRequest接口只有HttpServletRequest一个子接口
现在Java Web开发只支持HTTP协议,所以使用HttpServletRequest表示HTTP协议的操作。
request内置对象的常用方法
方法|描述
getParameter|接收客户端发来的请求参数内容
getParameterValues|取得客户端发来的一组请求参数内容
getParameterNames|取得全部请求参数的名称
getRemoteAddr|取得客户端的IP地址
setCharacterEncoding|设置统一的请求编码
isUserInRole|进行用户身份的验证
getSession|取得当前的session对象
getRequestURL|返回正在请求的路径
getHeaderNames|取得全部请求的头信息的名称
getHeader|根据名称取得头信息的内容
getMethod|取得用户的提交方式
getServletPath|取得访问的路径
getContextPath|取得上下文资源路径

7.9 DAO设计模式
DAO(数据访问对象)的主要功能是数据操作,在程序的标准开发架构中属于数据层的操作。
程序的标准开发架构: 
客户层|显示层JSP/Servlet|业务层BO|数据层DAO|资源层DataBase
如果业务操作比较简单,可以不使用BO,而完全通过DAO完成操作。
DAO由以下几个部分组成。
DatabaseConnection:专门负责数据库的打开与关闭操作的类。
VO:主要由属性、setter、getter方法组成,VO类中的属性与表中的字段相对应,每一个VO类的对象都表示表中的每一条记录。
DAO:主要定义操作的接口,定义一系列数据库的原子性操作,如增加、修改、删除、按ID查询等。
Impl:DAO接口的真实实现类,完成具体的数据库操作,但是不负责数据库的打开和关闭。
Proxy:代理实现类,主要完成数据库的打开和关闭,并且调用真实实现类对象的操作。
Factory:工厂类,通过工厂类取得一个DAO的实例化对象。
项目中包的命名
数据库连接:
DAO接口:com.poobo.dao.IXxxDao
DAO接口真实实现类:com.poobo.dao.impl.XxxDaoImpl
DAO接口代理实现类:
VO类:com.poobo.entity.TbXxx,VO的命名要与表的命名一致
工厂类:
7.9.2 DAO开发
com.poobo.entity.TbConfigList是一个简单的VO类,包含了属性、getter、setter方法。
/*表: tb_config_list*/-----------------------

/*列信息*/-----------

Field            Type          Collation        Null    Key     Default  Extra           Privileges                       Comment  
---------------  ------------  ---------------  ------  ------  -------  --------------  -------------------------------  ---------
ID               int(11)       (NULL)           NO      PRI     (NULL)   auto_increment  select,insert,update,references           
name             varchar(50)   utf8_general_ci  YES             (NULL)                   select,insert,update,references           
isEnable         tinyint(4)    (NULL)           YES             (NULL)                   select,insert,update,references           
isGenerationTxt  tinyint(4)    (NULL)           YES             (NULL)                   select,insert,update,references           
listUrl          varchar(255)  utf8_general_ci  YES             (NULL) 

在DAO设计模式中,最重要的就是定义DAO接口。
com.poobo.dao.IConfigListDao
DAO接口定义完成后需要做具体的实现类,DAO的实现类有两种,一种是真实主题实现类,另外一种是代理操作实现类。
com.poobo.dao.impl.ConfigListDaoImpl
DAO操作只完成后台的功能。
 
附录B MyEclipse开发工具
Java的开发可以通过Eclipse开发工具进行程序的快速开发,但是如果要将Eclipse用于Web项目上,则必须使用其他的插件完成,而MyEclipse就是这样一个插件。
B.1 MyEclipse简介
MyEclipse企业级开发平台(MyEclipse Enterprise Workbench),是为Eclipse开发平台准备出来的一个插件,通过此插件可以帮助用户完成Java EE程序的开发、调试、部署等操作,从而大大地提高了工作效率。
在MyEclipse组件中,方便地提供了JSP、Servlet、HTML、XML、Struts、Hibernate、Spring等框架的开发支持。
MyEclipse依然是插件,只是现在已经将Eclips吸收了。
本书使用的是MyEclipse 6.0开发平台。[项目中用的是MyEclipse Professional 2014]
在MyEclipse中支持多种项目的建立,如EJB Project、Web Project、Web Service Project等。
选择建立Web Project
Java EE的支持版本为5.0[项目中用的是6.0]
可以发现,通过MyEclipse建立的项目会自动建立好WEB-INF/lib文件夹、WEB-INF/classes文件夹,而且同时会在WEB-INF/web.xml文件中配置好默认的首页是index.jsp。
B.4配置Tomcat服务器
在MyEclipse中可以通过配置,直接将Tomcat服务器配置到项目中,以后即可通过MyEclipse进行服务器的启动和关闭。
用户选择Window|Preferences|MyEclispe|Servers|Tomcat|Tomcat 7.x命令,并将Tomcat的目录配置到MyEclipse中。
Tomcat 7.x中默认JDK版本是com.sun.java.jdk7.win32.x86_64_1.7.0.u45
MyEclipse自带的JDK安装路径为D:\MyEclipse\binary\com.sun.java.jdk7.win32.x86_64_1.7.0.u45

C:\Users\DELL->java -version
java version "1.7.0_11"
Java(TM) SE Runtime Environment (build 1.7.0_11-b21)
Java HotSpot(TM) 64-Bit Server VM (build 23.6-b04, mixed mode)
】 
配置完成之后,即可直接通过MyEclips进行服务器的启动,但是在启动之前还需要将项目部署到Tomcat,在主界面中有项目部署和Tomcat启动的快捷按钮。
在Tomcat目录中的webapps的文件夹保存的就是所有直接部署的项目
虽然MyEclipse本身提供了自动部署的功能,但是从实际的开发来看,使用手工部署(配置虚拟目录)的方式会比较方便。
Spring实战(第3版)
[美]Craig Walls著
耿渊 张卫滨 译
2013年6月第1版
关于作者
Craig Walls也是《Spring 实战》前两个版本(Manning,2005年及2007年)的作者 。
第1章  Spring之旅
一切都要从Bean开始。
1996年12月,Sun公司发布了JavaBean 1.00-A规范。
1998年3月,Sun发布了EJB 1.0规范。
为了降低Java开发的复杂性,Spring采取了以下4种关键策略:
基于POJO的轻量级和最小侵入性编程;
通过依赖注入(DI)和面向接口实现松耦合;
基于切面和惯例进行声明式编程;
通过切面和模板减少样板式代码。
重量级框架都存在如下问题:强迫开发者编写大量冗余代码、应用与框架绑定,并且通常难以编写测试代码。
依赖注入的方式之一:构造器注入
依赖注入的最大好处:松耦合。
创建应用程序之间协作的行为通常称为装配。
Spring有多种装配Bean的方式,采用XML配置通常是最常见的装配方式。
Spring配置文件:
项目中WEB-INF\config\spring\applicationContext.xml、spring-servlet.xml
这是Spring装配Bean的一种简单方式。
Spring通过应用上下文(Application Context)装载Bean的定义并把它们组装起来。
Spring应用上下文全权负责对象的创建和组装。
依赖注入让相互协作的软件组件保持松散耦合,而AOP编程允许你把遍布应用各处的功能分离出来形成可重用的组件。
诸如日志、事务管理和安全此类的系统服务通常被称为横切关注点,因为它们总是跨越系统的多个组件。
对遍布系统的关注点服务(日志、安全、事物管理)的调用经常散布到各个组件中,而这些关注点并不是组件的核心业务
AOP使这些服务模块化,并以声明的方式将它们应用到它们需要影响的组件中去。
AOP确保POJO保持简单。
利用AOP,你可以使用各种功能层去包裹核心业务层。可以将安全、事物和日志关注点与你的核心业务逻辑相分离。
利用AOP,遍布系统的关注点覆盖在它们所影响的组件之上,促使应用组件只需关注它们的核心业务功能
许多Java API,例如JDBC,会涉及编写大量的样板式代码。
Spring旨在通过模板封装来消除样板式代码。Spring的JdbcTemplate使得在执行数据库操作时,避免传统的JDBC样板式代码成为了可能。
在Spring应用中,对象由Spring容器创建、装配和管理
Spring自带了几种容器实现,可以归为两种不同的类型。
Bean工厂是最简单得多容器,提供基本的DI支持。
应用上下文基于BeanFactory之上构建,并提供面向应用的服务,例如从属性文件解析文本信息的能力,以及发布应用事件给感兴趣的事件监听者的能力。
Spring框架自带的JAR文件
本书中是20个3.0.5,项目中是14个4.1.0
spring-aop-4.1.0.RELEASE.jar
缺***asm***.jar
spring-aspects-4.1.0.RELEASE.jar
spring-beans-4.1.0.RELEASE.jar
spring-context-4.1.0.RELEASE.jar
spring-context-support-4.1.0.RELEASE.jar
spring-core-4.1.0.RELEASE.jar
spring-expression-4.1.0.RELEASE.jar
缺***instrument***.jar
缺***instrument.tomcat***.jar
spring-jdbc-4.1.0.RELEASE.jar
spring-jms-4.1.0.RELEASE.jar
spring-orm-4.1.0.RELEASE.jar
缺***oxm***.jar
缺***test***.jar
缺***transaction***.jar
缺***web.portlet***.jar
缺***web.servlet***.jar
缺***web.struts***.jar
多spring-tx-4.1.0.RELEASE.jar
spring-web-4.1.0.RELEASE.jar
多spring-webmvc-4.1.0.RELEASE.jar
多spring-websocket-4.1.0.RELEASE.jar
Spring框架由6个定义明确的模块组成
1、核心Spring容器
2、Spring的AOP模块
3、数据访问与集成
Spring的JDBC和DAO模块封装了这些样板式代码。
4、Web和远程调用
该模块自带了一个强大的MVC框架,有助于应用提升Web层技术的松散耦合。
该框架提供了两种形式:面向传统Web应用的基于Servlet的框架和面向使用Java Portlet API的基于Portlet的应用。
5、测试
6、监测器(Instrumentation)
2007年11月,Spring团队发布了Spring框架2.5版本。Spring 2.5的重大意义在于拥抱注解驱动开发,Spring 2.5之前的版本都是采用基于XML的配置。
使用@Autowired实现基于注解驱动的依赖注入和使用@Qualifier实现细粒度的自动装配(auto-wiring)控制。
支持JSR-250注解,包括支持命名资源依赖注入的@Resource,以及对生命周期方法支持的@PostConstruct和@PreDestroy。
自动扫描使用@Component注解(或其他构造型注解)所标注的Spring组件。
一个全新的基于注解驱动的Spring MVC编程模型,极大简化了Spring Web开发。
基于JUnit 4和注解的一个新的集成测试框架。
第2章 装配Bean
在Spring中,对象无需自己负责查找或创建与其关联的其他对象。
相反,容器负责把需要相互协作的对象引用赋予各个对象。
创建应用对象之间协作关系的行为通常被称为装配(wiring),这也是依赖注入的本质。
Spring是一个基于容器的框架。但是如果你没有配置Spring,那它就是一个空容器。
从Spring 3.0开始,Spring容器提供了两种配置Bean的方式。
传统上,Spring使用一个或多个XML文件作为配置文件,而Spring 3.0还同时提供了基于Java注解的配置方式。
Spring配置文件的根元素是来源于Spring beans命名空间所定义的<beans>元素。
在<beans>元素内,你可以放置所有的Spring配置信息,包括<bean>元素的声明。
Spring的核心框架自带了10个命名空间配置。
Java自带了多种XML命名空间,通过这些命名空间可以配置Spring容器
命名空间|用途
aop|为声明切面以及将@AspectJ注解的类代理为Spring切面提供了配置元素
beans|支持声明Bean和装配Bean,是Spring最核心也是最原始的命名空间
context|为配置Spring应用上下文提供了配置元素,包括自动检测和自动装配Bean、注入非Spring直接管理的对象
jee|提供了与Java EE API的集成,例如JNDI和EJB
jms|为声明消息驱动的POJO提供了配置元素
lang|支持配置由Groovy、JRuby或BeanShell等脚本实现的Bean
mvc|启用Spring MVC的能力,例如面向注解的控制器、视图控制器和拦截器
oxm|支持Spring的对象到XML映射配置
tx|提供声明式事物配置
util|提供各种各样的工具类元素,包括把集合配置为Bean、支持属性占位符元素
第3章 最小化Spring XML配置
Spring提供了几种技巧,可以帮助我们减少XML的配置数量。
自动装配(autowiring)有助于减少甚至消除配置<property>元素和<constructor-arg>元素,让Spring自动识别如何装配Bean的依赖关系。
自动检测(autodiscovery)比自动装配更进了一步,让Spring能够自动识别哪些类需要被配置成Spring Bean,从而减少对<bean>元素的使用。
从Spring 2.5开始,最有趣的一种装配Spring Bean的方式是使用注解自动装配Bean的属性。
Spring 3支持几种不同的用于自动装配的注解:
Spring自带的@Autowired注解[项目中大量用到了];
JSR-330的@Inject注解;
JSR-250的@Resource注解。
@Autowired注解特别有趣的地方在于,我们不仅能使用它标注setter方法,还可以标注需要自动装配Bean引用的任意方法。
我们还可以直接使用@Autowired注解直接标注属性,并删除setter方法。
<context:component-scan base-package="com.poobo" />  <!-- 扫描包 -->
Spring还有另一种技巧。 <context:component-scan>元素除了完成与<context:annotation-config>一样的工作,还允许Spring自动检测Bean和定义Bean。这意味着不使用<bean>元素,Spring应用中的大多数(或者所有)Bean都能够实现定义和装配。
<context:component-scan>元素会扫描指定的包及其所有子包,并查找出能够自动注册为Spring Bean的类。base-package属性标识了<context:component-scan>元素所扫描的包。
默认情况下,<context:component-scan>查找使用构造型注解所标注的类,这些特殊的注解如下。
@Component——通用的构造型注解,标识该类为Spring组件[例如项目中的SystemLogAspect类]。
@Controller——标识将该类定义为Spring MVC controller[例如项目中的ConfigListCtr类、EqGamesInfoCtr类、EquipmentCtr类、EquipmentlConfigListCtr类、InitSysCtr类、ResourcesConfigCtr类、ResourcesCtr类、SysAccountCtr类]。
@Repository——标识将该类定义为数据仓库[例如项目中的ConfigListDaoImpl类、EqGamesInfoDaoImpl类、EquipmentConfiglistDaoImpl类、EquipmentDaoImpl类、ResourcesConfigDaoImpl类、ResourcesDaoImpl类、SysAccountDaoImpl类、SysLoginDaoImpl类]。
@Service——标识将该类定义为服务[例如项目中ConfigListServiceImpl类、EqGamesInfoServiceImpl类、EquipmentConfigListServiceImpl类、EquipmentServiceImpl类、ResourcesConfigServiceImpl类、ResourcesServiceImpl类、SysAccountServiceImpl类、SysLogServiceImpl类]。
第4章 面向切面的Spring
在软件开发中,分布于应用中多处的功能被称为横切关注点(cross-cutting concerns)。将这些横切关注点与业务逻辑相分离正是面向切面编程(AOP)所要解决的。
切面实现了横切关注点(跨越多个应用对象的逻辑)的模块化
切面提供了取代继承和委托的另一种选择。
横切关注点可以被模块化为特殊的类,这些类称为切面。
描述切面的常用术语有通知(advice)、切点(pointcut)和连接点(join point)。
在AOP术语中,切面的工作被称为通知。
Spring切面可以应用5种类型的通知。
Before——在方法被调用之前调用通知。
After——在方法完成之后调用通知,无论方法执行是否成功。
After-returning——在方法成功执行之后调用通知。
After-throwing——在方法抛出异常之后调用通知。
Around——通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为。
连接点是在应用执行过程中能够插入切面的一个点。
一个切面并不需要通知应用的所有连接点。切点有助于缩小切面所通知连接点的范围。
切面(Aspect)是通知和切点的结合。通知和切点共同定义了关于切面的全部内容——它是什么,在何时和何处完成其功能。
引入(Introduction)允许我们向现有的类添加新方法或属性。
织入(Weaving)是将切面应用到目标对象来创建新的代理对象的过程。
AOP框架形成了现在的三足鼎立的格局:
AspectJ
JBoss AOP
Spring AOP
Spring提供了4种各具特色的AOP支持:
基于代理的经典AOP;
@AspectJ注解驱动的切面;
纯POJO切面;
注入式AspectJ切面(适合Spring各版本)

Spring的AOP配置元素简化了基于POJO切面的声明
AOP配置元素|描述
<aop:advisor>|定义AOP通知器
<aop:after>|定义AOP后置通知(不管被通知的方法是否执行成功)
<aop:after-returning>|定义AOP after-returning通知
<aop:after-throwing>|定义AOP after-throwing通知
<aop:around>|定义AOP环绕通知
<aop:aspect>|定义切面
<aop:aspectj-autoproxy/>|启用@AspectJ注解驱动的切面
<aop:before>|定义AOP前置通知
<aop:config>|顶层的AOP配置元素,大多数的<aop:*>元素必须包含在<aop:config>元素内
<aop:declare-parents/>|为被通知的对象引入额外的接口,并透明地实现
<aop:pointcut>|定义切点
项目中用到了:
<!--  配置参与事务的类 -->
<aop:config>
<aop:pointcut id="allTestServiceMethod" expression="execution(* com.poobo.*.service.*.*(..))"/>
<aop:advisor pointcut-ref="allTestServiceMethod" advice-ref="transactionAdvice" />
</aop:config>

<aop:aspectj-autoproxy/>  <!-- aop切面注解 -->
<aop:aspectj-autoproxy proxy-target-class="true" />  <!-- 通知spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller -->

第5章 征服数据库
5.1 Spring的数据访问哲学
服务对象本身并不会处理数据访问,而是将数据访问委托给DAO。DAO接口确保其与服务对象的松耦合
5.1.1了解Spring的数据访问异常
可能导致抛出SQLException的常见问题包括:
应用程序无法连接数据库;
要执行的查询有语法错误;
查询中所使用的表和(或)列不存在
试图插入或更新的数据违反了数据库的完整性约束。
JDBC的异常体系过于简单了,Hibernate的异常体系是其本身所独有的。我们需要的是,数据访问异常要具有描述性而且又与特定的持久化框架无关。
5.1.2数据访问模块化
Spring将数据访问过程中固定的和可变的部分明确划分为两个不同的类:模板(template)和回调(callback)。模板管理过程中固定的部分,而回调处理自定义的数据访问代码。
Spring的DAO模板类负责通用的数据访问功能。对于应用程序特定的任务,则会调用自定义的DAO回调对象。
5.1.3使用DAO支持类
5.2配置数据源
5.2.1使用JNDI数据源
5.2.2使用数据源连接池
5.2.3基于JDBC驱动的数据源
5.3在Spring中使用JDBC
5.3.1应对失控的JDBC代码
5.3.2使用JDBC模板
5.4在Spring中集成Hibernate
一些可用的框架提供了延迟加载(Lazy loading)、预先抓取(Eager fetching)、级联(Cascading)这样的服务。这些服务的通用名称是对象/关系映射(ORM)。在持久层使用ORM工具,可以节省数千行的代码和大量的开发时间。
5.4.1Hibernate概览
5.4.2声明Hibernate的Session工厂
使用Hibernate的主要接口是org.hibernate.Session。Session接口提供了基本的数据访问功能,如保存、更新、删除以及从数据库加载对象的功能。通过Hibernate的Session接口,应用程序的DAO能够满足所有的持久化需求。
获取Hibernate Session对象的标准方式是借助于Hibernate的SessionFactory接口的实现类。除了一些其他的任务,SessionFactory主要负责Hibernate Session的打开、关闭以及管理。
如果你选择在XML中定义对象与数据库之间的映射,那么需要在Spring中配置LocalSessionFactoryBean:
本书中是hibernate3,项目中是hibernate4
<!-- sessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<!-- 用于测试,在控制台实现sql语句 -->
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
</props>
</property>
<!-- 加载hibernate的映射文件-->
<property name="mappingDirectoryLocations">
<list>
<value>classpath:/com/poobo/entity/hbm*</value>
</list>
</property> 
</bean>
在配置LocalSessionFactoryBean时,我们使用了3个属性。
dataSource属性装配了一个DataSource Bean引用。
mappingDirectoryLocations 缺mappingResources属性装配了一个或多个的Hibernate映射文件,在这些文件中定义了应用程序的持久化策略。
hibernateProperties属性配置了Hibernate如何进行操作的细节。
如果你更倾向于使用注解的方式来定义持久化,那需要使用AnnotationSessionFactoryBean来代替LocalSessionFactoryBean[项目中持久化域对象是通过XML文件进行配置的]。
5.4.3构建不依赖于Spring的Hibernate代码
5.5 Spring与Java持久化API
5.5.1配置实体管理器工厂
5.5.2配置基于JPA的DAO

第7章 使用Spring MVC构建Web应用程序
7.1 Spring MVC起步
7.1.1跟踪Spring MVC的请求
7.1.2搭建Spring MVC
7.2编写基本的控制器
7.3处理控制器的输入
7.4处理表单
7.5处理文件上传







你可能感兴趣的:(Java Web开发笔记(2016-5-6 11:13、2016-5-10 11:13、2016-5-12 14:58))