zoukankan      html  css  js  c++  java
  • 使用标记文件更新和查询数据库

    在开发复杂的企业应用程序时,很多人更喜欢使用企业 JavaBean (EJB) 技术,让应用服务器来管理对象可持续性。其他人可能更喜欢使用 Java 数据库连接 (JDBC) 标准 API,以便手动地优化数据库访问。这些解决方案可能不适合于简单的由数据库支持的网站,这种网站只需使用 JSP 尽可能快地进行原型开发。如果您只需要查询和更新一个简单的数据库,则提供数据库访问特性的标记库可能是最佳的解决方案。

    JSTL 具有一系列简单的 SQL 标记,我们将在以下的示例中使用它们。不要直接从您的页面调用 JSTL SQL 标记,而使用标记文件将表达与数据库访问脚本相分离是个好办法。这种分离允许您以后能够方便地切换到另一个数据库连接解决方案,以便提高应用程序的性能和可伸缩性。

    JSTL 不是唯一提供数据库访问特性的标记库。Oracle 应用程序开发框架 (ADF) 提供了一个称为商务组件数据标记的 JSP 库,它包含一系列与数据库相关的更加高级的 JSP 标记。注意,ADF 特性集的范围更广泛,使得 Oracle ADF 适合于简单的和复杂的应用程序。Oracle ADF 与 JDeveloper 10g 绑定在一起,后者具有用于 ADF 的可视设计工具。

    以下的六个示例创建一个表、插入三行、更新一行、删除另一行、执行一些查询再删除该表。这一切都是利用通用标记文件完成的,这些标记文件不依赖于表的结构。

    第 1 步:创建表。本示例的 JSP 页 (create.jsp) 调用标记文件 (create.tag) 来创建表,该表的结构以 <db:create> 自定义标记的主体内容提供。表的属性指定了表名 (People)。在创建表后,JSP 页输出一条消息,通知用户该操作已完成:

    <db:create table="People">
    userID INTEGER,
    name VARCHAR2(60),
    email VARCHAR2(60)
    </db:create>
    
    <p> Table created.</p>
    

    create.tag 文件包含一个标记片段 (init.tagf),该片段利用 JSTL 的 <sql:setDataSource> 标记,在应用程序范围内设置一个名为 tags_db_dataSource 的 javax.sql.DataSource 变量。只有当该变量尚未存在,并且将要与 JSTL 的 <sql:update> 标记(该标记执行其主体中的 SQL 语句)一同在标记文件中使用时,才会创建该变量。create.tag 文件动态地创建 CREATE TABLE 语句,利用 ${table} 获取表名,并利用 <jsp:doBody> 插入表的结构:

    <sql:update dataSource="${tags_db_dataSource}">
    CREATE TABLE ${table} ( <jsp:doBody/> )
    </sql:update>
    

    为了运行示例,您必须配置一个名为 dbtags 的数据源。在 Web 应用程序的描述器 (web.xml) 中声明了对该资源的引用:

    <resource-ref>
    <res-ref-name>jdbc/dbtags</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    </resource-ref>
    

    init.tagf 片段从一个初始化参数那里获得资源的路径,这个初始化参数也是在 web.xml 中定义的:

    <context-param>
    <param-name>tags_db_dataSource</param-name>
    <param-value>jdbc/dbtags</param-value>
    </context-param>
    

    如果您要使用另一个数据源,只需在 web.xml 文件中将 dbtags 替换为您的数据源名称。

    init.tagf

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
    
    <c:if test="${applicationScope.tags_db_dataSource == null}">
    <sql:setDataSource
    dataSource="${initParam.tags_db_dataSource}"
    var="tags_db_dataSource" scope="application"/>
    </c:if>
    

    create.tag

    <%@ tag body-content="scriptless" %>
    <%@ attribute name="table" required="true" %>
    <%@ include file="init.tagf" %>
    
    <sql:update dataSource="${tags_db_dataSource}">
    CREATE TABLE ${table} ( <jsp:doBody/> )
    </sql:update>
    

    create.jsp

    <%@ taglib prefix="db" tagdir="/WEB-INF/tags/db" %>
    
    <db:create table="People">
    userID INTEGER,
    name VARCHAR2(60),
    email VARCHAR2(60)
    </db:create>
    
    <p> Table created.</p>
    

    第 2 步:插入。在您拥有表之后,可以使用 <db:insert> 标记每次插入一行,该标记利用以下语法调用标记文件 (insert.tag):

    <db:insert table="..." column1="value1" column2="value2" .../>
    

    一个示例 JSP 页 (insert.jsp) 使用 <db:insert> 将三行插入到 People 表中。在每次调用时,标记文件使用以下语法创建和执行一条 SQL 语句:

    INSERT INTO table (column1, column2, ...)VALUES (value1, value2, ...) 
    

    列名和值被指定为动态属性,因而 <db:insert> 可用于任何表,而无论表的列是如何命名的。标记文件使用 <c:forEach>,对 java.util.Map 实例 (columnAttr) 的项目进行迭代,该实例持有 <db:insert> 的动态属性。每个动态属性的名称表示一个列名,并且利用 ${v_entry.key} 而获得。标记文件利用 ${v_entry.value} 获得那些必须被插入到表中的值。

    在 <sql:update> 的主体内,标记文件创建一个列名的列表 (v_columnNames) 和另一个包含参数标志的列表 (v_paramMarkers)。JSTL 的 <sql:param> 标记与传送 SQL 参数值的 <sql:update> 协作。在执行了不产生任何输出的 <c:forEach> 循环之后,标记文件利用以下语句产生 SQL 语句

    INSERT INTO ${table} (${v_columnNames}) VALUES (${v_paramMarkers})
    

    当 insert.jsp 调用标记文件时,<sql:update> 标记求出其主体所得的值

    INSERT INTO People (userID, name, email) VALUES (?, ?, ?)
    

    然后,<sql:update> 使用 JDBC API 并传递由 <sql:param> 所发送的参数值,执行以上的 SQL 语句。注意,列及其相应的值可能以不同的顺序出现,因为它们是从 java.util.Map 实例中检索出来的。因此,我们必须确保 SQL 语句不依赖于列的顺序。

    insert.tag

    <%@ tag body-content="empty" dynamic-attributes="columnAttr" %>
    <%@ attribute name="table" required="true" %>
    <%@ include file="init.tagf" %>
    
    <c:set var="v_columnNames" value=""/>
    <c:set var="v_paramMarkers" value=""/>
    <c:set var="v_separator" value=""/>
    <sql:update dataSource="${tags_db_dataSource}">
    <c:forEach var="v_entry" items="${columnAttr}">
    <sql:param value="${v_entry.value}"/>
    <c:set var="v_columnNames"
    value="${v_columnNames}${v_separator}${v_entry.key}"/>
    <c:set var="v_paramMarkers"
    value="${v_paramMarkers}${v_separator}${'?'}"/>
    <c:set var="v_separator" value=", "/>
    </c:forEach>
    INSERT INTO ${table} (${v_columnNames})
    VALUES (${v_paramMarkers})
    </sql:update>
    

    insert.jsp

    <%@ taglib prefix="db" tagdir="/WEB-INF/tags/db" %>
    
    <db:insert table="People" userID="1" name="John Smith"
    email="JohnSmith@company.com" />
    
    <db:insert table="People" userID="2" name="Mark Johnson"
    email="MarkJohnson@company.com" />
    
    <db:insert table="People" userID="3" name="Bill Davis"
    email="BillDavis@company.com" />
    
    <p> Rows inserted.</p>
    

    第 3 步:更新。update.jsp 页使用 <db:update> 来更改那些利用 insert.jsp 插入的行中的某一行的 email 值。update.tag 文件类似于 insert.tag,但此时 JSTL 的 <sql:update> 标记用于执行 UPDATE 语句:

    UPDATE table SET column1=value1, column2=value2, ...WHERE ...
    

    使用以下语法将列及其值指定为动态属性:

    <db:update table="..." column1="value1" column2="value2" ... 
    where="..."/>
    

    标记文件使用动态属性来创建一个包含 column=? 结构的列表 (v_setList)。利用前面示例中的 <sql:param>,将列值传送到 <sql:update>。然后,update.tag 利用以下语句生成 SQL 语句

     
    UPDATE ${table} SET ${v_setList} WHERE ${where}
    

    当 update.jsp 调用标记文件时,<sql:update> 标记求出其主体所得的值

    UPDATE People SET email=?WHERE userID=2
    

    不同于每次只能用于插入一行的 <db:insert> 标记,<db:update> 标记可用于在单次调用中更新多行。

    update.tag

    资源

    使用以下资源来测试这些示例,并了解有关 JSP 2.0 标记文件以及 JSTL 核心和 SQL 标记的更多信息。

    下载源代码
    tagfiles_src.zip 文件包含了本文中的示例。为运行这些示例,您需要 J2SE、J2EE 1.4 应用服务器、JSTL 1.1 以及数据库服务器。

    下载 OC4J 10g
    Oracle Application Server Containers for J2EE 10g 充分实施了包括 JSP 2.0 在内的 J2EE 1.4 规范。你可以使用 OC4J 10g (10.0.3) 来测试这些示例。它可用于所有主要的数据库服务器 — 当然 — 包括 Oracle 数据库。

    下载 JSTL 1.1
    在部署示例之前,下载 JSTL 并将 jstl.jar 和 standard.jar 复制到 Web 应用程序的 WEB-INF/lib 目录。此外,不要忘记配置 dbtags 数据源,并确保可以使用正确的数据库驱动程序。

    阅读 JSP 2.0 规范
    JSP 2.0 规范中有整整一章专门针对标记文件(“第一部分:JSP 章节。8 标记文件”)。JSP 2.0 所推出的新的标准操作在另一章(“第一部分:JSP 章节。5 标准操作”)中予以说明。

    阅读 JSTL 1.1 规范
    JSTL 规范说明了本文示例中所使用的 <c:set>、<c:if>、<c:forEach>、<sql:setDataSource>、<sql:query>、<sql:update> 和 <sql:param> 标记。

    相关文章与下载

    如何:向 JDeveloper 10g 添加自定义的 JSP 标记库

    Oracle JDeveloper 10g

    JSP 示例代码

    教程:了解 JSP 2.0 的新特性,“标记文件”模块

    <%@ tag body-content="empty" dynamic-attributes="columnAttr" %>
    <%@ attribute name="table" required="true" %>
    <%@ attribute name="where" required="false" %>
    <%@ include file="init.tagf" %>
    
    <c:set var="v_setList" value=""/>
    <c:set var="v_separator" value=""/>
    <sql:update dataSource="${tags_db_dataSource}">
    <c:forEach var="v_entry" items="${columnAttr}">
    <sql:param value="${v_entry.value}"/>
    <c:set var="v_setList"
    value="${v_setList}${v_separator}${v_entry.key}=?"/>
    <c:set var="v_separator" value=", "/>
    </c:forEach>
    UPDATE ${table} SET ${v_setList}
    <c:if test="${!empty where}"> WHERE ${where} </c:if>
    </sql:update>
    

    update.jsp

    <%@ taglib prefix="db" tagdir="/WEB-INF/tags/db" %>
    
    <db:update table="People"
    email="markj@company.com" where="userID=2"/>
    
    <p> Row updated.</p>
    

    第 4 步:删除。以下的标记文件 (delete.tag) 可用于删除一行或多行,它位于 delete.jsp 页中。

    delete.tag

    <%@ tag body-content="empty" %>
    <%@ attribute name="table" required="true" %>
    <%@ attribute name="where" required="false" %>
    <%@ include file="init.tagf" %>
    
    <sql:update dataSource="${tags_db_dataSource}">
    DELETE FROM ${table}
    <c:if test="${!empty where}"> WHERE ${where} </c:if>
    </sql:update>
    

    delete.jsp

    <%@ taglib prefix="db" tagdir="/WEB-INF/tags/db" %>
    
    <db:delete table="People" where="userID=1"/>
    
    <p> Row deleted.</p>
    

    第 5 步:选择。下一个标记文件 (select.tag) 使用 JSTL 的 <sql:query> 标记来执行 SELECT 语句。<db:select> 的语法包括在下面:

    <db:select var="row" table="..." columns="..." 
    where="..." groupBy="..." having="..." orderBy="...">
    
    process the result of the query, one row at a time
    
    </db:select>
    

    <db:select> 标记创建和执行以下的 SQL 语句,其子句被指定为标记的属性。

    SELECT columns FROM table WHERE ... 
    GROUP BY ...HAVING ...ORDER BY ...
    

    当 <db:select> 出现在 JSP 页中时,利用 select.tag 的 <jsp:doBody> 操作为每行调用它的主体。JSP 页从一个由标记文件与 JSTL 所创建的 java.util.Map 中获取行数据。例如,当前行的值可以利用类似 ${row.userID}、${row.name} 和 ${row.email} 的 JSP 结构而获得,此时假定 JSP 页调用的标记文件指定应该将持有数据的变量命名为 row

    <db:select var="row" table="People" columns="*">
    ${row.userID} ...${row.name} ...${row.email} 
    </db:select>
    

    select.jsp 页两次调用了标记文件。首先它使用 <db:select> 来迭代关系表的行,生成一个 HTML 表,然后 JSP 页使用 <db:select> 来计算 People 表的行数。

    select.tag

    <%@ tag body-content="scriptless" %>
    <%@ attribute name="var" required="true" %>
    <%@ variable name-from-attribute="var"
    alias="v_row" scope="NESTED" %>
    <%@ attribute name="table"   required="true"  %>
    <%@ attribute name="columns" required="false" %>
    <%@ attribute name="where"   required="false" %>
    <%@ attribute name="groupBy" required="false" %>
    <%@ attribute name="having"  required="false" %>
    <%@ attribute name="orderBy" required="false" %>
    <%@ include file="init.tagf" %>
    
    <sql:query dataSource="${tags_db_dataSource}" var="v_result">
    SELECT ${empty columns ?"*" : columns} FROM ${table}
    <c:if test="${!empty where}">   WHERE    ${where}   </c:if>
    <c:if test="${!empty groupBy}"> GROUP BY ${groupBy} </c:if>
    <c:if test="${!empty having}">  HAVING   ${having}  </c:if>
    <c:if test="${!empty orderBy}"> ORDER BY ${orderBy} </c:if>
    </sql:query>
    
    <c:forEach var="v_row" items="${v_result.rows}">
    <jsp:doBody/>
    </c:forEach>
    

    select.jsp

    <%@ taglib prefix="db" tagdir="/WEB-INF/tags/db" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
    <table border="2" cellspacing="1" cellpadding="3">
    <tr>
    <th> User ID </th>
    <th> Name </th>
    <th> Email </th>
    </tr>
    <db:select var="row" table="People" orderBy="name">
    <tr>
    <td> ${row.userID} </td>
    <td> ${row.name} </td>
    <td> ${row.email} </td>
    </tr>
    </db:select>
    </table>
    
    <db:select var="c" table="People" columns="count(*) as n">
    <p> ${c.n} people.</p>
    </db:select>
    

    输出

    图 7

    第 6 步:删除表。如果您希望再次执行 JSP 示例,则必须利用 drop.jsp 页删除表,该页使用了 drop.tag 文件。

    drop.tag

    <%@ tag body-content="scriptless" %>
    <%@ attribute name="table" required="true" %>
    <%@ include file="init.tagf" %>
    
    <sql:update dataSource="${tags_db_dataSource}">
    DROP TABLE ${table}
    </sql:update>
    

    drop.jsp

    <%@ taglib prefix="db" tagdir="/WEB-INF/tags/db" %>
    
    <db:drop table="People"/>
    
    <p> Table dropped.</p>
    

    引自http://www.oracle.com/technology/global/cn/pub/articles/cioroianu_tagfiles.html
  • 相关阅读:
    2019.8.15刷题统计
    2019.8.12刷题统计
    2019.8.11刷题统计
    2019.8.10刷题统计
    2019.8.9刷题统计
    2019.8.8刷题统计
    2019.8.7刷题统计
    2019.8.6刷题统计
    xuezhan.org 6.28
    xuezhan.org 6.27
  • 原文地址:https://www.cnblogs.com/huhu/p/133240.html
Copyright © 2011-2022 走看看