get some basic knowledge about rss from rss.sina

 ?什么是RSS???2004年最热门的互联网词汇之一:RSS 2005年1月03日 (http://wm23.com/resource/R01/Internet_1005.htm)

 ?RSS利于发布什么样的内容 2005年3月11日(http://www.donews.net/walaqi/archive/2005/03/11/298648.aspx)

 ?利用RSS进行项目沟通 2005年3月16日(http://blog.csdn.net/wangchinaking/archive/2005/03/16/321270.aspx)

 ?深度:中国RSS现状调查 2005年1月13日(http://www.ccw.com.cn/news2/look/htm2005/20050113_09EL8.htm)

 ?主流Blog程序 2005年2月08日(http://www.blogchina.com/new/display/64629.html)

 ?RSS列表 2005年3月16日(http://www.donews.net/sogoo/archive/2005/03/16/303272.aspx)

  There are several questions give me strong impression:

  1.Rss is the trend of the content exchanging,although this maybe impact ad business(by this reason,some website don't provide rss service.)

  2.Rss can make people avoid the garbage information from the internet,such as spam,harmful information,ad information;

  3.迪斯尼 has build a inner knowledge sharing platform successfully with Blog and Rss technique,this is a successful example in this area-(knowledage sharing),the successful example is very rare now.

we can do something out of network

for example:we can orgernize the members in same city hold party every year.And,invite some learning experts make some speech about learning.etc..

in order to make our website going on(better ISP service),we can build some business about learning service,for example,sale books,cd,and recieve some software developing task.

(转帖)用JSTL实现JSP应用程序快速开发 作者

转帖者注:由于本站留言板只有管理员才能查看,且没有明确的说明这个限制。致使hard在留言板中提交的这篇文章不能被大家看见,真是对不起。我会在留言板上明确标明这个限制。以后的留言板也许会作一些改进。

以下是hard提交文章的正文。

标题: 用JSTL实现JSP应用程序快速开发  作者: hard  创建时间: 2005-09-03 11:03:27  删除 

内容

在这篇文章中,我将为大家介绍一种基于JSP且灵活有趣的技术,那就是JSTL.JSTL全称为Java Server Pages Standard Tag Library.虽然JSP已经变的非常流行,但JSTL在基于SQL数据库的简单、快速的前后台开发中还是没有被广泛的应用。一旦你了解了JSTL,你就会了解到它的优点,并发现在你作为程序员的日常工作中,它已经被应用到了很多方面。我这里假设你已经熟悉HTML,能理解基本的SQL语句,和Jsp的基础知识。因为下面的内容要涉及到这些知识。

  JSTL是一个已经被标准化的标记库集合,她支持迭代、条件、XML文档的解析,国际化,和利用SQL与数据库交互的功能。起初,JSTL规范一直由JCP(Java Community process program)组织下的JSR #52 发展完善,"JCP肩负着Java 技术发展的重任"--官方网站这样评价。JCP作为一个开放性的组织,他同时吸收正式的会员和非正式会员.JCP对于Java技术规范的形成与发展发挥了重要的主导作用。JSTL主要包括四个基本部分的标记库:Core,XML,国际化,和对SQL的支持。由于这篇文章的主要是以其中的SQL部分的应用来快速了解JSTL,所以我们这篇文章只介绍了 Core和SQl标签库的一些基本功能。

  这项技术简单而且功能强大,足以和PHP、ColdFusion一较高下.他在拓展Java的应用领域方面有足够的能力,这些领域不只包括大型的可再升级的Web应用程序,对于仅拥有简单主页的Web程序一样没问题。这允许你在建立站点的时候可以避免那些经常考虑的XML的集成和与数据库的连接。正如我刚才提到的一样,JSTL的关键点就是简单易用。还有,那就是JSTL是基于JSP构建的, 他允许我们使用所有的Java技术,这一点我们有必要记住。

  开始之前,我们需要弄清楚怎样才能运行JSTL.由于是基于JSP技术的,所以我们运行它就需要一个能够编译JSP的容器,这里我们使用免费的JSP容器:TOMCAT(http://jakarta.apache.org/tomcat/index.html).至于如何安装这个产品已经超出了本文所讲述的范围。毫无疑问,这个软件产品现在已经很普及了,而且关于如何安装的文档资料也是很多。这里假设您已经安装并成功配置了这个容器,你只需再安装JSTL运行所需文件即可,它可以从这里下载http://jakarta.apache.org/taglibs/doc/standard-doc/intro.html你不需要真正的安装它,只需要将其中的.JAR文件包含到你的应用程序的WEB-INF/lib目录下即可,稍后我会具体说到该怎么做.

  因为我们要在一个支持标准SQL的数据库上运行程序,你需要在你的电脑上安装有一个数据库。数据库的类型有许多种,这里我选择了MySql。我之所以选择他的原因在于首先,我们需要展示JSTL对于构造简单快速的应用程序领域所起的作用,同时能和一直在这个领域处于主导地位的PHP+MySql有所比较;第二点那就是MySql是可以免费下载并包含有一个针对JAVA的JDBC驱动.总之,为了使用下面的例子,你需要下载一个MYSQL服务器(http://www.mysql.com/products/mysql/index.html; MySql Connector/J JDBC驱动程序http://www.mysql.com/products/connector-j/index.html;还有就是MySql control center http://www.mysql.com/products/connector-j/index.html),这个产品可以让你非常容易的操作管理Mysql数据库文件。全部下载完成后,你需要安装mysql和mysql Control Center。另外还有就是mysql的JDBC驱动需要放到你的web应用程序中的/Web-INF/lib目录中。

  在创建程序代码之前,你需要创建并填写数据库表。关于这方面的主题文章也相当广泛,具体如何操作超出了本文的范围。这里我推荐给你我们上面提及的一个可视化的管理工具 MySQL Control Center.你可以用他来创建一个用来运行程序的测试用户,数据库以及创建一个测试表,并填写若干记录。关于登陆名及密码 数据库名称这些配置环境参数,你应该记住他们,稍后需要应用到我们的代码中。

  现在,你就可以准备创建自己的第一个JSTL应用程序了它需要我们做下面一些事情:

  整个实例程序代码包括两个文件Hello.jsp和 Continue.jsp

  Hello.jsp文件允许你输入数据库名称、登陆名称、登陆密码、数据库表名。Continue.jsp:接受Hello.jsp中的数据信息并且连接数据库,并对数据库中的表执行一个Select请求.

  下面是这个系统所有的代码文件,我将逐一进行解释。这些代码相当简单,对于代码的结构,我相信你即使没有我的解释你也能理解的.

1: <!-- Hello.jsp -->

2: <html>

3: <head>

4: <title>Hello</title>

5: </head>

6: <body bgcolor="#ffffff">

7: <h1>Please, enter all necessary information and click OK.</h1>

8: <form method="post" action="Continue.jsp">

9: <br>Your login to database:

<input type="text" name="login" size="15">

10: <br>Your password to database:

<input type="password" name="password" size="15">

11: <br>Your database name:

<input type="text" name="database" size="15">

12: <br>Your database table:

<input type="text" name="table" size="15">

13: <br><br><input type="submit" name="submit" value=" OK ">

14: </form>

15: </body>

16: </html>

  (请注意文本左侧的数字只是为你提供一些标记信息,你不需要将他们输入到你的代码文件中。)

  上面就是所有Hello.jsp的源代码,很惊奇吧,他仅仅是纯粹的HTML代码,就这么简单,我想应该没有注释的必要了.我之所以将这些代码片段包含进文章中就是为了展示一下JSTL集成到那些需要快速扩充额外功能的HTML站点中是多么的简单.让我再为你展示一下Continue.jsp的全部代码,看过之后,你就会对 JSTL有些了解了。

1: <!-- Continue.jsp -->

2: <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>

3: <@ taglib prefix="sql" uri="http://java.sun.com/jstl/sql" %>

4: <c:set var="h" value="localhost"/>

5: <c:set var="l" value="${param.login}"/>

6: <c:set var="p" value="${param.password}"/>

7: <c:set var="d" value="${param.database}"/>

8: <c:set var="t" value="${param.table}"/>

9: <html>

10: <head>

11: <title>Continue</title>

12: </head>

13: <body bgcolor="#ffffff">

14: <sql:setDataSource driver="com.mysql.jdbc.Driver"

url="jdbc:mysql://${l}/${d}?user=${u}&password=${p}"/>

15: <sql:query var="result">

16: SELECT * FROM <c:out value="${t}"/>

17: </sql:query>

18: <c:forEach var="row" items="${result.rowsByIndex}">

19: <c:out value="${row[0]}"/> <br>

20: </c:forEach>

21: </body>

22: </html>

(请注意文本左侧的数字只是为你提供一些标记信息,你不需要将他们输入到你的代码文件中。)

  这就是我们所有的代码了,是不是非常不错?现在我门来解释一下上面这些代码的作用。

  行1 是 HTML 的注释说明。

  行2--3 这些 JSP 标签是为了引用外部的 标签库,更确切的说这里是引用了JSTL库中的 Core 和SQL标签库部分。我们为他们都设置了前缀名称,以便于我们通过这些前缀名称访问被引入的标签库中的功能方法。

  行4---8正如 Hello.jsp 真正运行的样子,他将请求continue.jsp,Continue.jsp获得请求后就需要得到并解析来自Hello.jsp的若干变量,我们使用了这样的方式${param.YOUR_VAR}。在第4行<c:set标签,将变量${h}设置为 "localhost",第五行变量${l}将获取我们在 Hello.jsp中的login文本域中输入的信息,第6,7,8行的变量将分别获得来自Hello.jsp中用户所输入的密码,数据库名称,数据表名称。

  行9--13是一些我经常用来常见HTML网页头的简单的HTML标签,马上,重要的功能马上要到了。

  行14,我们试图用我们先前获得的mysql驱动程序(com.mysql.jdbc.Driver)建立数据库连接,在URL中,我们指明数据库连接所需要的参数,象数据库名称,主机名称,登陆名及登陆密码。依此,我们可以用其它任何的JDBC驱动程序连接其相对的数据库。如果我们需要连接其他的SQL数据库,只需更改这个 URL就够了。

  行15--17 这里我们执行了一个Select 查询,请特别注意第16行,我们使用了另一个JSTL功能函数<c:out 用来输出我们所获取的数据表名称,这里我们同样可以使用其他的SQL命令,比如说 INSERT,DELETE,等等。要执行这些没有返回值的查询请求,你就需要使用<sql:update JSTL功能函数了。他可以直接执行他们就象<SQL:query一样,只是执行它是不需要特别指定结果变量来存储语句执行返回的结果。

  行18--20 既然我们执行了上面的SELECT查询语句,我们就应该把他的返回结果显示出来。<c:forEach 就是JSTL 中一个具有迭代功能的函数,执行它时,我们通过${result.rowsByIndex}将返回的每一个数据行信息返回给变量${row},紧接着在第19行, 我们通过<c:out value="${row[0]}"/>显示返回的每个数据行的第一个数据列中的值。只要你的数据表中包含的字段,你都可以通过改变变量 ${row}中的数字大小来对请求表中的任意一个字段中的值对他们进行访问。

  行21--22是HTML 页脚

  在你亲自创建JSTL应用程序过程中,可能你还没有发现它有多么的强大,但你应该能够意识到JSTL的功能函数的简单和高效性,试想有了JSTL,整合出一个基于SQL的新闻专栏是何等的快速,集成你现有的web站点是何等的容易。

  很好,我们的代码很容易理解的,即使一个非专业程序员的话,打个比方就算是一个设计师也能够读懂它,理解它,还可能进行部分的修改,起码是页面布局上的修改。

  正如我们开始的时候所提到的,为了使我们的JSTL代码正常的运行,我们需要安装Mysql Connector/J 中的JAR 文件,当然还有 JSTL。因为我们使用了Tomcat这个JSp 容器,你需要在Tomcat的文件目录Webapps下创建你自己的文件夹,将你的Hello.jsp 、Continue.jsp文件放在你创建的文件目录中,在你创建的目录中你还要创建一个叫做WEB-INF 的文件夹,将你的配置文件Web.xml放在里面,web.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app

PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app />

  接下来我们还需要在WEB-INF下创建一个叫做lib的子目,并将下列文件放进去:

jstl.jar

saxpath.jar

standard.jar

mysql-connector-java-3.0.9-stable-bin.jar (注意,这个名称依据你的Mysql Connector/J版本不同可能会有所变化)

  所有的这些信息您能够在JSTL或Tomcat手册中查阅的到,如果你想理解他们具体是如何运行而又为什么这么运行你就应该研读一下这些手册。不过为了帮助你快速的掌握JSTL的基本操作,相关的知识我已经作了介绍。

  如果你使用的是其他的Jsp 容器,那么就需要你阅读他们相关的手册资料。

  罗罗索索这么多,我还想再说明一点,这篇文章只是对JSTL技术的基本的介绍,并不是完全手册。JSTL中包含有许多功能丰富的函数用法来帮助你以简捷快速的方式完成你的Jsp开发,我建议大家读一些有关JSTL功能以及它如何与JavaBeans协同工作的更详细的文档资料,到最终你可能会发现他就是你期待已久的开发平台。通过阅读本篇文章,你应该已经能够创建一些简单的基于SQL 数据库的前后台应用了。

 

敬请作者关注:学习日记使用方法

非常感谢lian的热心支持,敬请关注学习日记使用方法:

一)、数据结构:http://www.learndiary.com/aboutMe.html

     采用的结构:目标-->评论目标,目标-->日记,日记-->评论日记

二)、使用方法:http://www.learndiary.com/help.html

    1>在"您的目标"链接页面中点击"添加新目标",订立自己想要实现的目标。(强烈建议订立自己的目标前先检索一下,看是否别人已经订了类似的目标,这样你就可以加入这个目标,形成朝这个目标前进的集体效应。)

2>在"所有目标"链接页面中点击"加入",添加别人订立而自己也想要实现的目标。

3>在上述两个页面中都可以对目标进行评论,以目标为中心写日记,对日记进行评论。

4>在"您的目标"链接页面中点击"改变目标状态"下的选择菜单可以对自己的所有目标进行管理。

5>在您发写帖子时请尽量写出你撰写内容所引用的资源,以便大家共享。

比如:您的两个目标可以分别归类到:

目标“学习Hibernate (11篇) ”http://www.learndiary.com/disGoalContentAction.do?goalID=401

像这样:http://www.learndiary.com/disDiaryContentAction.do?goalID=1101

目标:“一起学习Struts(MVC) (19篇)”http://www.learndiary.com/disGoalContentAction.do?goalID=167

像这样:http://www.learndiary.com/disDiaryContentAction.do?goalID=1102

再次感谢lian的热心支持,新版的学习日记会对使用方法作出程序流程上的显而易见的提示。

(转贴)实际项目中的StrutsPlugIn插件扩展 作者: l

作者:冰莲如水

本文讲述Struts应用在实际项目中的插件类开发技术。在我们的learndiaryV1.0项目中已经有了很好的应用。通过对它的讲解,我们可以了解在应用开发中这一技术的实做经验。首先说明Struts插件扩展技术的特点:

Struts框架的一大优势在于它允许开发人员根据实际需要来扩展框架,定制客户化的功能。

Struts1.1框架提供了动态插入和加载组件的功能,这种组件被称为Struts插件。Struts插件实际上就是一个Java类,它在Struts应用启动时Struts框架调用每个插件的init()方法进行初始化,在插件的初始化阶段可以完成一些初始化的操作,如建立数据库连接,和远程系统建立连接,在当前的应用范围内加入插件类自身的实例等。在应用关闭时Struts框架会调用每个插件的 destroy()方法,destroy()方法可以用来完成释放资源的任务,如关闭数据库连接,断开与远程的连接等。任何作为插件的Java类都应该实现org.apache.struts.action.PlugIn接口。PlugIn接口包括两个方法:

       public interface PlugIn {

        /**

        *当struts应用启动时,下面的方法将被调用执行

        */

        public void init(ActionServlet servlet, ApplicationConfig config)

              throws ServletException;

       /**

       *当struts应用关闭时,将调用下面的方法,以释放资源。

       */

        public void destroy();

       } 

相关资源

 

相关评论

标题: 实际项目中的StrutsPlugIn插件扩展  作者: lian  创建时间: 2005-08-30 16:03:36  最近更新: 2005-08-30 16:03:36  编辑  删除 

内容

我们在learndiaryV1.0这个项目中使用了Struts框架的PlugIn插件扩展来实现ServiceFactory类。ServiceFactory为应用中的业务逻辑工厂类,它将提供创建各种业务逻辑类实例的方法,我们是通过对业务逻辑类实例的方法调用最终实现后台的商业逻辑及业务数据的检索和持久化的。关于持久层的存取更新请参阅《Hibernate 存取及批量更新删除》这一章节。ServiceFactory 工厂类实现了 Struts 的 PlugIn 接口并在 Struts 的配置文件struts-config中对其进行了配置描述,使其在Struts系统启动时自动被加载。而在 ServiceFactory 工厂类所覆盖的 PlugIn 的 init() 方法中,此工厂类将其自身加入到应用的 ServletContext 实例当中去。在具体的项目中,因为ServiceFactory 工厂类已经被启动并加载,在加载的过程中init() 方法又将ServiceFactory 工厂类自身的实例加入到ServletContext当中,我们便可以通过servlet.getServletContext().getAttribute(Constants.SERVICE_FACTORY_KEY)这样的方法对此ServiceFactory工厂类进行引用。通常我们也可以在struts-config文件中的ServiceFactory工厂类插件配置项<plug-in>中加入插件类的启动参数<set-property>,在当前的应用中我们没有采用这样的方式。听上去可能会糊里糊途的,我们还是从代码中找到灵感吧! 

相关资源 

标题: 实际项目中的StrutsPlugIn插件扩展  作者: lian  创建时间: 2005-08-30 16:04:34  最近更新: 2005-08-30 16:04:34  编辑  删除 

内容

首先我们构建出你的ServiceFactory类所要去实现的接口类,这有利于实现商业应用的面向接口的编程,这是一种良好的JAVA开发规范。在今后的开发环节当中我们还会遇到类似的开发案例。

  

        package com.learndiary.website.services;

import java.lang.IllegalAccessException;

import java.lang.ClassNotFoundException;

import java.lang.InstantiationException;

/**

 * 业务逻辑工厂的接口

 * 应用程序开发后期将会扩充此工厂接口,

 * 设置各种createService()方法,

 * 返回均为此业务逻辑方法的接口。

 */

public interface IServiceFactory {

public IBusinessService createService() throws ClassNotFoundException,

IllegalAccessException,InstantiationException;

public IUserService createUserService(String serviceName) throws ClassNotFoundException,

IllegalAccessException,InstantiationException;

public IUserService createUserService() throws ClassNotFoundException,

    IllegalAccessException,InstantiationException;

public void destroy();

}

你会发现上面的代码中所有方法返回的实例都定义为业务逻辑接口形式,如IBusinessService createService() 。在各类的IBusinessService接口中我们定义了这一类业务逻辑接口所要实现的方法。例如IUserService接口为我们定义了如下的一些方法。 

相关资源 

标题: 实际项目中的StrutsPlugIn插件扩展  作者: lian  创建时间: 2005-08-30 16:05:43  最近更新: 2005-08-30 16:05:43  编辑  删除 

内容

      public interface IUserService extends IBusinessService{

public User saveUser (User user) throws BusinessException;

public User findUserById(Long id) throws BusinessException;

public User findUserByName(String name) throws BusinessException;

public User findUserByEmail(String email) throws BusinessException;

public User findUserByPassword(String name, String password) throws BusinessException ;

public void saveOrUpdateUser(User user) throws BusinessException;

public List getUsers() throws BusinessException;

public int getAllUserNum() throws BusinessException;

}

此外IServiceFactory接口的定义中还存在着IUserService createUserService()的重载形式IUserService createUserService(String serviceName),这是为了方便大家对于这一应用形式的重构和扩展。

ServiceFactory的具体实现类如下:

  package com.learndiary.website.services;

import javax.servlet.ServletException;

import java.lang.InstantiationException;

import java.lang.IllegalAccessException;

import org.apache.struts.action.ActionServlet;

import org.apache.struts.action.PlugIn;

import org.apache.struts.config.ModuleConfig;

import com.learndiary.website.Constants;

import net.sf.hibernate.*;

import net.sf.hibernate.cfg.Configuration;

/**

 *业务逻辑工厂,ServiceFactory工厂类实现了struts 的PlugIn接口,

 *使其将在系统启动时,自动被加载;在工厂类所覆盖的PlugIn的init()方法中,

 *此工厂类将其自身加入到应用的ServletContext实例当中去。

 */

public class ServiceFactory implements IServiceFactory,PlugIn {

    

//由init()方法中传入ActionServlet实例

private ActionServlet servlet =null;

private String serviceClassname = "com.learndiary.website.services.ORMService";

/*

* 创建业务逻辑实例的模板

*/

public IBusinessService createService() throws ClassNotFoundException,

IllegalAccessException, InstantiationException {

IBusinessService serInstance =

(IBusinessService)Class.forName(serviceClassname).newInstance();

serInstance.setServletContext(servlet.getServletContext());

return serInstance;

}

/*

* 根据给定的服务类名,创建服务类的对象。

* 以接口IBusinessService型式返回。

*/

public IUserService createUserService(String serviceName) throws ClassNotFoundException,

IllegalAccessException, InstantiationException{

IUserService serInstance=

(IUserService)Class.forName(serviceName).newInstance();

serInstance.setServletContext(servlet.getServletContext());

return serInstance;

}

public IUserService createUserService() throws ClassNotFoundException,

    IllegalAccessException,InstantiationException{

IUserService serInstance = new UserService();

serInstance.setServletContext(servlet.getServletContext());

return serInstance;

}

public void destroy() {

}

/*

* 扩展Struts PlugIn接口的 init()方法

* Struts框架会在启动系统时,自动加载扩展了PlugIn接口的组件。

* 并调用此组件中的init()方法,对其进行初始化。

*

*/

public void init(ActionServlet svt, ModuleConfig conf)

throws ServletException {

this.servlet = svt;

/*

* 此处,利用组件初始化时,将本工厂实例保存于当前的ServletContext中。

* 此后,我们便可以在应用当中,调用此工厂实例。即调用ServiceFactory。

*/

servlet.getServletContext().setAttribute(Constants.SERVICE_FACTORY_KEY,this);

}



相关资源 

标题: 实际项目中的StrutsPlugIn插件扩展  作者: lian  创建时间: 2005-08-30 16:07:10  最近更新: 2005-08-30 16:07:10  编辑  删除 

内容

其中的public IBusinessService createService() throws ClassNotFoundException,

IllegalAccessException, InstantiationException {

IBusinessService serInstance =

(IBusinessService)Class.forName(serviceClassname).newInstance();

serInstance.setServletContext(servlet.getServletContext());

return serInstance;

}

为构建业务逻辑实现类的模板。业务逻辑实现类的具体的实例采用IBusinessService serInstance =

(IBusinessService)Class.forName(serviceClassname).newInstance();

的方式构建。关于具体的业务逻辑实现类是怎么样实现业务功能的,将在后续的章节中介绍。

在你的应用中加入了以上ServiceFactory工厂类之后,我们要把它作为Struts应用的插件加入到Struts配置文件当中, Struts框架在启动时将根据插件类相关的配置信息来初始化插件。与插件对应的配置元素为 <plug-in>,在struts-config.xml中对ServiceFactory插件类进行的如下配置:

  

  <plug-in className="com.learndiary.website.services.ServiceFactory">

  </plug-in>

根据Struts 配置文件的DTD 定义,在Struts配置文件中, <plug-in>元素必须位于其他配置元素的后面,此外,如果在配置文件中布署了多个插件, Struts框架将按照它们在配置文件中的先后顺序来依次初始化它们。

合理的使用好Struts的插件类扩展,将使我们的应用更加健壮,功能上具有良好的可扩展性和可移植性。在本文中也许存有疏漏错误之处,请开发员朋友们不吝恩教,吾人当励行而改之!

以上代码均为开源社区learndiary.com 1.0版本下测试通过的实际应用代码,你可以联系作者取得相关原码文件。

联系本文作者:QQ 284508610 

(转贴)Hibernate 存取及批量更新删除 作者: lian

            Hibernate 存取及批量更新删除

作者:冰莲如水

Hibernate是介于JAVA应用逻辑层与数据库层之间的一类开源的ORM中间件。ORM(即Object-Relation Mapping)从字面意义上讲就是对象-关系映射,ORM模式指的是在单个组件中负责所有实体域对象的持久化。其重点就在于把实体域对象通过一定规则上的映射机制,转化为数据库中所对应的记录,即持久化。为了更好的理解持久化,我们可以回想一下,以前所用到的通过JDBC API来对实体域对象实现的持久化。例如:

    Connetion con = null;

    PreparedStatement stmt = null;

     try{

        con = getConnection();

        con.setAutoCommit(false);

        stmt = con.prepareStatement(“insert into customers (ID, NAME, AGE) values (?,?,?)”);

        stmt.setLong(1, new Long(1));

        stmt.setString(2, new String(“ping”));

        stmt.setInt(3, new Integer(20));

        stmt.execute();

       }catch(SQLException sqlex){

           con.rollback();

         }catch(Exception e){

         …… }

        finally{

           try{

              stmt.close();

              con.close();

           }catch(Exception ex){

             …….

            }

          }

        }

 

相关资源

 

相关评论

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 01:57:52  最近更新: 2005-08-30 01:57:52  编辑  删除 

内容

     在上面的JDBC持久化模式中,业务逻辑层的过程域对象中业务逻辑和数据访问代码是混杂在一起的,并未能完全实现面向对象的编程思路,且程序结构不清晰,当关系数据模型发生变更时,软件的维护难度会大幅增加。而且这种模式中的SQL语句如果存在语法错误,在编译时是不能检查出来的,增加了调试程序时的难度。

    Hibernate的出现,将在业务逻辑层与数据库层之间再次构建出一个持久化层。Hibernate作为ORM中间件,封装了数据访问细节,我们只要通过Hibernate提供的对象-关系映射服务 ,便可在程序中实现域对象到关系数据的保存,或从数据库提取业务数据并转化为实体对象形式。

    对于要被持久化的JAVA对象,它在内存中的生命周期是从new语句创建了这个对象时开始,当不再有任何引用变量引用它时,这个对象的生命中期就将结束,所占用的内存将被JVM的垃圾回收器(GC)回收。 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 01:58:57  最近更新: 2005-08-30 01:58:57  编辑  删除 

内容

  对于Hibernate所要操作的持久化对象,在它的生命周期中,可处于三种状态:

? 临时状态(transient): 用new语句新建的对象,还没有被持久化,此时它不处于任何的Hibernate 的Session之中。处于临时状态的JAVA对象被称为临时对象。

? 持久化状态(persistent):这类对象已经被持久化,已处于(被加入)Session的缓存中。处于持久化状态的JAVA对象被称为持久华对象。

? 游离状态(detached):已经被持久化,但不再处于Session(被扔出或是Session自行关闭了)的缓存当中。处于游离状态的JAVA对象被称为游离对象。

Session接口是Hibernate向应用程序提供的操作数据库的最主要的接口,它提供了基本的面向对象的保存,更新,删除和查询方法。它由SessionFactory工厂类创建。 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 01:59:40  最近更新: 2005-08-30 01:59:40  编辑  删除 

内容

* Session 的save()方法:

    save()方法使一个临时对象转变为持久化对象。例如:

         Customer customer = new Customer();

         customer.setId( new Long(9));

         customer.setName(“Tom”);

         Session session = sessionFactory.openSession();

         Transaction tx = session.beginTransaction();

         Session.save(customer);

         tx.commit();

         session.close();

  Session 的save()方法所要注意的问题,1.在实际的对象持久化保存中,新建对象的ID应在此对象的类的映射文件中设置其生成方式,无需在程序中再对ID进行赋值。

例如以上的Customer类的映射文件Customer.hbm.xml中对ID生成方式的设置:

      <id name=”id” column=”ID”>

         <generator class=”increment”/>

      </id>

如果希望由应用程序来为新的对象指定ID,可以调用save()的另一个重载方法:

      save( customer, new Long(1));

   但此种方法在程序中不推荐使用。

2.在应用程序中不应该把持久化对象或游离对象传给save()方法。

 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 02:00:47  最近更新: 2005-08-30 02:00:47  编辑  删除 

内容

* Session 的update()方法

     update()方法使一个游离对象转变为持久化对象。以下代码在session1中保存一个 Customer 对象,然后在session2中更新这个 Customer对象:

     Customer customer = new Customer();

     customer.setName(“Tom”);

     Session session1 = sessionFactory.openSession();

     Transaction tx1 = session1.beginTransaction();

     session1.save(customer);

     tx1.commit();

     session1.close(); // 此时Customer对象变为游离对象,因为session1已经关闭。

      

     Session session2 = sessionFactory.openSession();

     Transaction tx2 = session2.beginTransaction();

     costomer.setName(“Linda”); //在与session2关联之前修改Customer对象的属性,

                            //这不是必须的一步,你也可以不修改,或修改更多属性。

     session2.update(customer); //在session2中加载 customer游离对象,并使其再次转为

                           //持久化对象。

     customer.setName(“Jack”); //在与session2关联之后再次修改了Customer对象的属性,

     tx2.commit();

     session2.close(); 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 02:01:52  最近更新: 2005-08-30 02:01:52  编辑  删除 

内容

在上面的例子中,customer先是被session1持久化后,session1关闭,customer变成

游离对象,再次与session2关联后,customer又变成持久对象。其中我们不厌其烦的修改Customer对象的属性,为了要证明当Customer对象与新的session2关联以后,修改了其属性,并不需要再次执行session2.save(customer),Session在清理缓存时,会根据最近一次的更新组装成update语句并执行数据库更新。

* Session的saveOrUpdate()方法

  saveOrUpdate()方法同时包含了save() 和update()方法的功能。如果传入的参数是临时对象,就调用save()方法;如果传入的是游离对象,就调用update()方法;如果传入的参数是持久化对象,就直接返回。以下的示例程序中,customer起初为游离对象, anotherCustomer起初为临时对象,session2的saveOrUpdate()方法分别将它们变为持久化对象:

     ……

Session session2 = sessionFactory.openSession();

Transaction tx2 = session2.beginTransaction();

Customer anotherCustomer = new Customer(); // anotherCustomer为临时对象

anotherCustomer.setName(“Tom”);

session2.saveOrUpdate(customer); //使customer游离对象被session2关联

session2.saveOrUpdate(anotherCustomer); //使anotherCustomer临时对象被session2关联

tx2.commit();

session2.close(); 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 02:02:34  最近更新: 2005-08-30 02:02:34  编辑  删除 

内容

* Session 的load()和 get()方法

    load()和 get()方法都能根据给定的OID从数据库中加载一个持久化对象,这两个方法的区别在于:当数据库中不存在与对象的OID相同的记录时,load()方法抛出net.sf.hibernate.ObjectNotFoundException异常,而get()方法返回null。示例如下:

    Session session1 = sessionFactory.openSession();

    Transaction tx1 = session1.beginTransaction();

    Customer a = (Customer)session1.load(Customer.class, new Long(1));

    Customer b= (Customer)session1.get(Customer.class. new Long(2));

   

    tx1.commit();

    session1.close();

    当执行了session1.load(Customer.class, new Long(1))这样的代码以后,就把OID为1的Customer对象载到session1的缓存里。我们可以在tx1.commit()执行之前对加载后的Customer对象a进行属性的修改。这些修改并不会马上被执行,而是在Session清理缓存时,会根据持久化对象的属性变化来同步更新数据库。

 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 02:03:27  最近更新: 2005-08-30 02:03:27  编辑  删除 

内容

*Session 的delete()方法

   delete()方法用于从数据库中删除与Java对象对应的记录。如果传入的参数是持久化对象,Session就计划执行一个delete语句。如果传入的参数是游离对象,先使游离对象被Session关联,使它变为持久化对象,然后计划执行一个delete语句。而真正的删除语句的执行是在Session清理缓存时。示例代码如下,首先加载了一个持久化对象,然后通过delete()方法将它删除。

     Session session1 = sessionFactory.openSession();

     Transaction tx1 = session1.beginTransaction();

     //加载一个持久化对象,因为Session 的get()和load()方法返回的永远是持久化对象。

     Customer customer = (Customer)session1.get(Customer.class, new Long(1));

     session1.delete(customer);

session1.close();

如果customer是游离对象时,下面的代码显示将此游离对象删除:

Session session2 = sessionFactory.openSession();

Transaction tx2 = session2.beginTransaction();

//在删除前,此游离对象customer先与session2关联,成为持久对象,然后将计划

//执行对其删除的SQL语句

session2.delete(customer);

tx2.commit();

session2.close();

 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 02:04:17  最近更新: 2005-08-30 02:04:17  编辑  删除 

内容

关于Hibernate的批量检索,批量更新和批量删除,所执行的操作并不尽遵循相同的规律。这一点使目前的Hibernate2.0还显得有些不够规格化和强健。但以后的版本中,期望其可以突破这几个屏障。

   首先说明批量查询,我们已经了解到,Session 的load(), get() , find() 方法都可实现对业务数据的查询,其中load()会因所要查询的对象类的映射文件(比如Customer.hbm.xml文件)中设置的检索策略,而实现立即检索或延迟检索。get()方法和find()方法却不受这种控制,它们总是会执行立即检索。那么象load()这样的方法,当其被设置为使用延迟检索时,它会返回什么样的实例呢?当使用延迟检索时返回为这一对象的代理类实例,代理类实例也有一个标志性的OID, 但没有被实例化,其所有属性为默认初始值或为空。关于延迟检索和对象类的映射方式,这里不做多余解释。提到检索,load() 和get()方法都是用指定了OID的方式检索并返回一个与数据库中记录相对应的实例对象。如Customer customer = (Customer)session.get(Customer.class, new Long(1)) 将会返回一个Customer实例对象customer. 而 find()可以实现批量的检索,其返回类型为List的对象集合。例如:

     List customerList = session.find( “from Customer as c”);

注意,其中的”from Customer as c” 为HQL查询语句, Customer 并不是象普通的SQL语句中对表名的引用那样可以对大小写不敏感,这里的查询是基于对象类的,Customer为待查询的对象类,你要写正确你的类名,c是你为这个类在这里所取的别名。Hibernate是通过你对Customer这个对象类的映射文件Customer.hbm.xml中的设置得知此对象类与哪一个表对应。它可能正是对应了CUSTOMERS这个表。那么Hibernate又如何知道你所用的对象类与表的映射,到底是哪一个数据库中的表呢?这个对数据库名的映射是在Hibernate的配置文件hibernate.cfg.xml文件中给出的。相关的一些问题请查阅Hibernate的配置和映射章节。 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 02:05:00  最近更新: 2005-08-30 02:05:00  编辑  删除 

内容

    以上的session.find( “from Customer as c”)方法,Hibernate最终会执行这样的SQL语句执行数据库的查询(立即检索方式):

    select * from CUSTOMERS ;

或者你也可以按如下的方式进行查询:

    List customerList = session.find(“from Customer as c where c.age > 24”);

最终Hibernate所执行的SQL语句为:

     select * from CUSTOMERS where AGE > 24 ;

如果担心一次检出Customer类对象的量会过大,可以在Customer.hbm.xml文件中设置一次批量检索的检出量batch-size:

    <class name=”mypack.Customer” table=”CUSTOMERS” batch-size=”4”>

对于一对一,一对多的关联也存在着集合(set. list ,bag, map)的延迟检索或立即检索,对于这种关联集合的检索,也存在着批量检索的设置,如在类的映射文件中的一对多的关联集合set中设置延迟检索时的批量检索尺寸:

   <class name=”mypack.customer” table=”CUSTOMERS”>

      ……..

      <set name=”topics” inverse=”true” lazy=”true” batch-size=”3”>

       …..

      </set>

   </class>

对于这类检索本文不做过多解释。有兴趣的读者可参阅Hibernate的关联映射与检索类型。

关于批量删除,可以采用Session 的delete()方法的重载形式,以HQL语句作为参数执行批量的删除:

    session.delete(“from Customer c where c.age > 24”) ;

  但是Hibernate最终并不会为我们构建这样的SQL并执行:

      select * from CUSTOMERS where AGE > 24 ;

  Session 的delete()方法首先通过以下select 语句把所有附合查询条件的Customer对象加载到内存中:select * from CUSTOMERS where AGE > 24 ;

  然后再逐一执行对这些对象的删除工作:

        delect from CUSTOMERS where ID = 1;

        delect from CUSTOMERS where ID = 2;

        delect from CUSTOMERS where ID = 3;

        …….

        delect from CUSTOMERS where ID = 10000; 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 02:06:15  最近更新: 2005-08-30 02:06:15  编辑  删除 

内容

 这有可能造成对一万条数据的加载和逐一删除。如此将会严重消耗内存,影响系统性能。此时最佳的方案又回到了使用JDBC API执行批量的删除工作。在此我们暂不举其实例。

下面探讨在Hibernate中的批量更新。Hibernate中Session的update()方法的各种重载形式,一次都只能更新一个对象,那么我们可不可以使用Session 的find()方法先检索出要更新的所有的对象,再用轮询的方法逐一对其进更新呢?比如:

     Session session = sessionFactory.openSession();

     Transaction tx = session.beginTransaction();

     Iterator customers = session.find(“from Customer c where c.age >24”) .iterator() ;

     while(customers.hasNext()){

        Customer customer = (Customer)customers.next();

        customer.setAge(customer.getAge() + 1);

        session.flush();

        session.evict(customer);

     }

    tx.commit();

    session.close();

 以上的程序只是实现了批量检索并更新对象的目的,依旧没有注意内存的占用及系统的性能问题。我们还是回到原始却又是最有效的方法,使用JDBC API来实现业务数据的批量更新。幸好Hibernate只是对JDBC进行了轻量的封装,我们在程序中依旧可以引用JDBC API:

    …….

    tx = session.beginTransaction();

    Connection con = session.connection(); //取得当前session使用的数据库连接

    PreparedStatement stmt = con.prepareStatement(“update CUSTOMERS set AGE=AGE + 1 ” + “where AGE >24”);

    stmt.executeUpdate();

    tx.commit(); 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 02:06:54  最近更新: 2005-08-30 02:06:54  编辑  删除 

内容

如果你使用的底层的数据库(如Oracle)支持存储过程,也可以通过存储过程来执行批量更新。Oracle中的存储过程的设置参考如下:

       create or replace procedure batchUpdateCustomer(p_age in number) as

         begin

            update CUSTOMERS set AGE = AGE + 1 where AGE > p_age ;

         end;

   上面的存储过程中的参数p_age代表一个数值型的传入参数,表示客户的年龄。我想你用它甚至可以查出一个上千年的老妖 :)

    在我们的应用程序中可以对这个存储过程进行如下的调用:

         ……..

tx = session.beginTransaction();

         Connection con = session.connection();

         String procedure = “ {call batchUpdateCustomer(?)}”;

         CallableStatement cstmt = con.prepareCall(procedure);

         cstmt.setInt(1, 24);

         cstmt.executeUpdate();

         tx.commit();

与此类同,Hibernate的批量删除也可以采用程序中调用JDBC API的方式,进行操作。你可以把上面的存储过程改一下,试着去执行它。

总结:Hibernate让我们在面对复杂多变的业务数据时,真正的体验到了面向对象编程的快意高效,但同时它自已也知道自身的不足之处在哪里,给我们留下了充分的空间去选择最适合的开发模式,而Hibernate为我们提供了对这些常规开发模式的支持。也许有一天,国人也能参与到这样经典的大型开源组件的设计当中去,做出我们引领时带的开源品牌,一同努力吧!这的确需要大部分人的努力和奉献。