`
peter.kong
  • 浏览: 57382 次
  • 来自: ...
社区版块
存档分类
最新评论

DataBase Connection in Struts

阅读更多
一、JDBC的工作原理

Struts在本质上是java程序,要在Struts应用程序中访问数据库,首先,必须搞清楚Java Database Connectivity API(JDBC)的工作原理。正如其名字揭示的,JDBC库提供了一个底层API,用来支持独立于任何特定SQL实现的基本SQL功能。提供数据库访问的基本功能。它是将各种数据库访问的公共概念抽取出来组成的类和接口。JDBC API包括两个包:java.sql(称之为JDBC内核API)和javax.sql(称之为JDBC标准扩展)。它们合在一起,包含了用Java开发数据库应用程序所需的类。这些类或接口主要有:
Java.sql.DriverManager
Java.sql.Driver
Java.sql.Connection
Java.sql.Statement
Java.sql.PreparedStatement
Java.sql.ResultSet等

这使得从Java程序发送SQL语句到数据库变得比较容易,并且适合所有SQL方言。也就是说为一种数据库如Oracle写好了java应用程序后,没有必要再为MS SQL Server再重新写一遍。而是可以针对各种数据库系统都使用同一个java应用程序。这样表述大家可能有些难以接受,我们这里可以打一个比方:联合国开会时,联合国的成员国的与会者(相当我们这里的具体的数据库管理系统)往往都有自己的语言(方言)。大会发言人(相当于我们这里的java应用程序)不可能用各种语言来发言。你只需要使用一种语言(相当于我们这里的JDBC)来发言就行了。那么怎么保证各成员国的与会者都听懂发言呢,这就要依靠同声翻译(相当于我们这里的JDBC驱动程序)。实际上是驱动程序将java程序中的SQL语句翻译成具体的数据库能执行的语句,再交由相应的数据库管理系统去执行。因此,使用JDBC API访问数据库时,我们要针对不同的数据库采用不同的驱动程序,驱动程序实际上是适合特定的数据库JDBC接口的具体实现,它们一般具有如下三种功能:
  • 建立一个与数据源的连接
  • 发送SQL语句到数据源
  • 取回结果集

    那么,JDBC具体是如何工作的呢?

    Java.sql.DriverManager装载驱动程序,当Java.sql.DriverManager的getConnection()方法被调用时,DriverManager试图在已经注册的驱动程序中为数据库(也可以是表格化的数据源)的URL寻找一个合适的驱动程序,并将数据库的URL传到驱动程序的acceptsURL()方法中,驱动程序确认自己有连接到该URL的能力。生成的连接Connection表示与特定的数据库的会话。Statement(包括PreparedStatement和CallableStatement)对象作为在给定Connection上执行SQL语句的容器。执行完语句后生成ResultSet结果集对象,通过结果集的一系列getter就可以访问表中各列的数据。

    这里,是讲的JDBC的基本工作过程,实际应用中,往往会使用JDBC扩展对象如DataSource等,限于篇幅,就不在此详细讨论了。

    二、访问数据库所要做的基本配置

    我们以访问MS SQL Server2000数据库为例,介绍其基本的配置情况。首先,要到微软网站去下载JDBC的驱动程序,运行setup.exe将得到的三个文件:msbase.jar、mssqlserver.jar及msutil.jar放在<catalina_home></catalina_home>/webapps/mystruts/WEB-INF/lib目录下。

    在struts-config.xml文件中配置数据源

    这里,有一点要引起大家的注意的,就是,struts-config.xml中配置的各个项目是有一定的顺序要求的,几个主要项目的顺序大致是这样的:

    <ccid_nobr></ccid_nobr>
    <ccid_code></ccid_code>data-sourcesform-beansaction-mappingsmessage-resourcesplug-in


    在配置时要遵守上述顺序

    <ccid_nobr></ccid_nobr>
    <ccid_code></ccid_code><data-sources>    <data-source key="A" type="org.apache.commons.dbcp.BasicDataSource">      <set-property property="driverClassName"          value="com.microsoft.jdbc.sqlserver.SQLServerDriver" />      <set-property property="url"          value="jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=mystruts;SelectMethod=cursor" />      <set-property property="username" value="sa" />      <set-property property="password" value="yourpwd" />      <set-property property="maxActive" value="10" />      <set-property property="maxWait" value="5000" />      <set-property property="defaultAutoCommit" value="false" />      <set-property property="defaultReadOnly" value="false" />    </data-source>  </data-sources>


    我们来对这段配置代码做一个简单的说明:

    <data-source key="A" type="org.apache.commons.dbcp.BasicDataSource"></data-source>这句中,如果您的struts应用程序中只配置一个数据源则key="A"可以不要,而配置多个数据源时就要用这个键值区别,也就是说,可以为一个应用程序配置多个数据源让它访问多个数据库。

    <ccid_nobr></ccid_nobr>
    <ccid_code></ccid_code><set-property property="url"         value="jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=mystruts;        SelectMethod=cursor" />


    这句中的sqlserver://127.0.0.1:1433;DatabaseName=mystruts;的数据库服务器名(本例是用代表本机的ip地址)和数据库名称要与您的具体情况相同。同时,还要注意访问数据库的用户名和口令也要合乎您的实际情况。

    <set-property property="maxActive" value="10"></set-property>表示最大的活动连接数,这也说明这些连接是池化(pooling)的。

    <set-property property="defaultAutoCommit" value="false"></set-property>表示对数据库的增、删、改操作必须显式地提交。即必须使用connect.commit();这样的命令才能真正让数据库表中的记录作相应的改变。设置成这样方便用户组织自己的数据库事务。

    三、现在我们就来扩展前面我们讲的那个登录的例子,让它访问存储在数据库表中的用户名和口令信息,同时也让它给出的出错信息更明确一些。

    为此,我们先要做一些准备工作,如果您还没有安装MS SQL Server2000请先安装,并下载最新的补丁包。再建一个名为mystruts的数据库,并在该数据库中建一个名为userInfo的表,该表有两个字段既:username和password,它们的字段类型都为varchar(10),其中username为主键。在该表中输入一条记录,username和password的字段值分别为lhb和awave。到此准备工作就基本做好了。

    为了访问数据库,首先,要修改Action类,修改后的代码清单如下:

    <ccid_nobr></ccid_nobr>
    <ccid_code></ccid_code>package action;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import javax.servlet.http.HttpServletResponse;import org.apache.struts.action.Action;import org.apache.struts.action.ActionError;import org.apache.struts.action.ActionErrors;import org.apache.struts.action.ActionForm;import org.apache.struts.action.ActionForward;import org.apache.struts.action.ActionMapping;import org.apache.struts.action.ActionServlet;import bussness.UserInfoBo;import entity.UserInfoForm;import javax.sql.DataSource;import java.sql.Connection;import java.sql.SQLException;public final class LogonAction extends Action {  public ActionForward execute(ActionMapping mapping,         ActionForm form,         HttpServletRequest request,         HttpServletResponse response)         throws IOException, ServletException {    UserInfoForm userInfoForm = (UserInfoForm) form;    //从web层获得用户名和口令    String username = userInfoForm.getUsername().trim();    String password = userInfoForm.getPassword().trim();    //声明错误集对象    ActionErrors errors = new ActionErrors();    //声明数据源和连接对象    DataSource dataSource;    Connection cnn=null;    //校验输入    if(username.equals("")){      ActionError error=new ActionError("error.missing.username");      errors.add(ActionErrors.GLOBAL_ERROR,error);    }    if(password.equals("")){      ActionError error=new ActionError("error.missing.password");      errors.add(ActionErrors.GLOBAL_ERROR,error);    }    //调用业务逻辑    if(errors.size()==0){      String validated = "";      try{        //取得数据库连接        dataSource = getDataSource(request,"A");        cnn = dataSource.getConnection();        UserInfoBo userInfoBo=new UserInfoBo(cnn);        validated =userInfoBo.validatePwd(username,password);        if(validated.equals("match")){          //一切正常就保存用户信息并转向成功的页面          HttpSession session = request.getSession();          session.setAttribute("userInfoForm", form);                return mapping.findForward("success");        }      }      catch(Throwable e){        //处理可能出现的错误        e.printStackTrace();        ActionError error=new ActionError(e.getMessage());        errors.add(ActionErrors.GLOBAL_ERROR,error);      }    }    //如出错就转向输入页面,并显示相应的错误信息    saveErrors(request, errors);    return new ActionForward(mapping.getInput());  }}


    注意:dataSource = getDataSource(request,"A");这句中,如果配置中只有一个数据源,且没有key="A",则这句应写为dataSource = getDataSource(request);

    从清单上可以看出,主要就是增加了访问数据库的代码。同时,我们的业务对象的形式也发生了一个变化,原来没有参数,现在有一个代表数据库连接的参数cnn,因此我们也要对业务对象进行适当地修改。

    更改后的业务对象代码清单如下:

    <ccid_nobr></ccid_nobr>
    <ccid_code></ccid_code>package bussness;import entity.UserInfoForm;import java.sql.Connection;import java.sql.SQLException;import java.lang.Exception;import db.UserInfoDao;public class UserInfoBo {  private Connection cnn=null;  public UserInfoBo(Connection cnn){    this.cnn=cnn;  }  public String validatePwd(String username,String password){    String validateResult="";       try{      UserInfoDao userInfoDao = new UserInfoDao(cnn);      validateResult=userInfoDao.validatePwd(username,password);      if(validateResult.equals("error.logon.invalid")){        //如果用户名与口令不匹配则报此错        throw new RuntimeException("error.logon.invalid");       }      else if(validateResult.equals("error.removed.user")){        //如果找不到用户则报此错,这样用户看到的出错信息会更详细        throw new RuntimeException("error.removed.user");       }    }    catch(Exception e){      throw new RuntimeException(e.getMessage());    }    finally{      try{        if(cnn!=null){          cnn.close();        }      }      catch(SQLException sqle){        sqle.printStackTrace();        throw new RuntimeException("error.unexpected");      }    }    return validateResult;  }}


    这个业务对象的代码还是比较简单的,重点要讲的就是它在validatePwd方法中调用了一个名叫UserInfoDao的对象,它就是真正进行数据库操作的数据访问对象。其代码清单如下:

    <ccid_nobr></ccid_nobr>
    <ccid_code></ccid_code>package db;import entity.UserInfoForm;import java.sql.*;public class UserInfoDao {  private Connection con;  public UserInfoDao(Connection con) {    this.con=con;  }    public String validatePwd(String username,String password){    PreparedStatement ps=null;    ResultSet rs=null;    String validated="error.logon.invalid";    UserInfoForm userInfoForm=null;    String sql="select * from userInfo where username=?";    try{      if(con.isClosed()){        throw new IllegalStateException("error.unexpected");      }      ps=con.prepareStatement(sql);      ps.setString(1,username);      rs=ps.executeQuery();      if(rs.next()){        if(!rs.getString("password").trim().equals(password)){          return validated;//口令不正确返回口令不匹配信息                  }        else{          validated = "match";//口令正确返回口令匹配信息          return validated;        }      }else{                validated="error.removed.user";//没有找到该用户        return validated;              }    }catch(SQLException e){        e.printStackTrace();        throw new RuntimeException("error.unexpected");    }finally{      try{        if(ps!=null)          ps.close();        if(rs!=null)          rs.close();      }catch(SQLException e){        e.printStackTrace();        throw new RuntimeException("error.unexpected");      }    }  }}


    下面,简单地分析一下数据访问对象的工作过程:

    要访问数据库,一般要经历的如下几个步骤:
  • 获得到数据库的连接
  • 创建SQL语句
  • 执行SQL语句
  • 管理结果集

    其中,得到数据库的连接本例中是在Action类中完成的,代码如下:
    dataSource = getDataSource(request,"A");
    cnn = dataSource.getConnection();

    Action在调用业务对象时将连接作为一个参数传给业务对象,再由业务对象传给数据库访问对象。

    要说明一点的是,要将struts-legacy.jar文件放在<catalina_home></catalina_home>/webapps/mystruts/WEB-INF/lib目录下。

    我们要在<catalina_home></catalina_home>/webapps/mystruts/WEB-INF/classes目录下再建一个名叫db的子目录,将数据访问类以UserInfoDao.java文件名保存在该子目录中。按照上篇文章介绍的方法,编译各个包中的.java文件。就可以启动Tomcat重新运行您的程序了。

    细心一点的读者可能都注意到了,到目前为止,我们程序中的各种消息都不是用中文表示的,在下一篇文章中,我们将讨论Struts的国际化编程即所谓的i18n编程,对我们在编程中经常遇到的乱码问题也一同作些分析。 
  •  

    分享到:
    评论

    相关推荐

      struts环境配置手记

      Connection conn = DriverManager.getConnection(connURL); Statement stmt = conn.createStatement(); // 查询语句... }catch(Exception e){ e.printStackTrace(); } ``` - 上述代码展示了如何使用JDBC...

      struts数据源配置用到的4个jar

      2. **commons-dbcp-1.2.1.jar**:Apache Commons DBCP(Database Connection Pool)是一个基于Apache Commons Pool对象池机制的数据库连接池。在Struts应用中,DBCP负责管理数据库连接,避免频繁创建和关闭数据库...

      Struts2-Crud+JdbcDemo最简单的Struts2+jdbc学习曾删改查程序

      JDBC(Java Database Connectivity)是Java中用于访问数据库的标准API,提供了连接、查询、插入、更新和删除数据的能力。这个"Struts2-Crud+JdbcDemo"项目是一个基础的学习示例,涵盖了如何使用Struts2和JDBC进行...

      Struts1.x-Jdbc,学习Struts1.的曾删改查

      在Struts1.x中,JDBC(Java Database Connectivity)是常用于与数据库交互的技术,它允许开发者通过Java代码来执行SQL语句,实现数据的增删改查操作。下面将详细探讨Struts1.x框架结合JDBC进行数据库操作的知识点。 ...

      j2ee项目练习 jdbc+struts

      这个项目练习的核心是结合JDBC(Java Database Connectivity)和Struts框架来实现数据的存储与展示。 **JDBC** 是Java语言访问数据库的标准API,它允许程序员以一种统一的方式与各种关系数据库进行交互。在JDBC中,...

      Struts增删改查

      在Struts中,数据库连接通常通过JDBC(Java Database Connectivity)来建立。这涉及到驱动加载、数据库URL、用户名和密码的配置,以及Connection、Statement、PreparedStatement和ResultSet等对象的使用。 7. **...

      struts2数据库常用操作

      这个类通常使用JDBC(Java Database Connectivity)API,通过加载数据库驱动并调用`Connection`对象的方法来建立与数据库的连接。例如: ```java public static Connection getConnection() { // 加载数据库驱动 ...

      Struts2+SQL Server实现登录

      为了与SQL Server 2008通信,我们需要使用JDBC(Java Database Connectivity)API。在Java代码中,我们先加载数据库驱动,然后创建连接,再通过Statement或PreparedStatement对象执行SQL查询。例如,我们可以编写一...

      struts web的登录项目

      然后,使用`Class.forName()`加载驱动,`DriverManager.getConnection()`建立连接,`Statement`或`PreparedStatement`执行SQL语句,最后通过`ResultSet`处理查询结果。在登录场景下,通常会有一个SQL查询用于验证...

      struts2(包括增删改查的实现,及登录实现。jdbc连接。适合struts2初学者)

      JDBC(Java Database Connectivity)是Java中用于与各种数据库进行通信的API。在这个示例中,JDBC被用来建立数据库连接,执行SQL语句,并处理查询结果。开发者需要配置数据库连接参数(如URL、用户名、密码),创建...

      struts+jdbc增删改查

      Struts是一个MVC(Model-View-Controller)框架,用于构建结构清晰、易于维护的Web应用程序,而JDBC(Java Database Connectivity)则是Java标准库中用于与各种数据库进行交互的API。下面将详细介绍这两个技术及其在...

      struts2+jdbc连接mysql

      JDBC(Java Database Connectivity)是Java中用于与数据库进行交互的API,它允许程序通过SQL语句来操作数据。MySQL则是一种流行的开源关系型数据库管理系统,因其高效、稳定和易于使用而受到开发者青睐。 本示例中...

      基于struts2.0的考勤系统

      在系统中,Tomcat的DBCP(Database Connection Pool)连接池起到了至关重要的作用。DBCP是Tomcat内置的一个数据库连接池组件,用于管理数据库连接。通过DBCP,系统可以在多用户并发访问时高效地分配和重用数据库连接...

      struts2增删改查

      1. 数据库连接:使用JDBC(Java Database Connectivity)驱动建立与Oracle数据库的连接。 2. SQL语句:编写INSERT(增)、DELETE(删)、UPDATE(改)和SELECT(查)语句执行数据库操作。 3. PreparedStatement:预...

      基于Struts2+JDBC的网上购物

      JDBC(Java Database Connectivity)是Java中访问数据库的标准API,它允许程序连接到数据库、执行SQL语句并处理结果。在这个项目中,JDBC被用来实现数据的持久化,比如存储商品信息、用户信息以及订单详情等。开发者...

      struts2 jdbc

      而JDBC(Java Database Connectivity)是Java语言连接数据库的标准API,它允许Java程序与各种类型的数据库进行交互。在Struts2框架中集成JDBC,可以方便地实现数据的CRUD(创建、读取、更新和删除)操作,为Web应用...

      Struts2 + Jdbc + mysql

      接下来,Jdbc(Java Database Connectivity)是Java语言中用于与数据库交互的API。它提供了一个统一的接口,使得开发者可以访问不同类型的数据库。使用Jdbc的关键步骤包括: 1. **加载驱动**:通过Class.forName()...

      Struts2+jdbc+mysq分页Demo

      1. **JDBC连接MySQL**:Java Database Connectivity (JDBC) 是Java语言访问数据库的标准API。在本示例中,我们首先需要配置数据库连接信息,包括URL、用户名、密码等。然后通过`Class.forName()`加载JDBC驱动,使用`...

      struts2连接mysql多表查询

      Struts2是一个基于MVC(Model-View-Controller)设计模式的Java Web框架,它主要用于构建企业级的Web应用程序。在Struts2中,我们常常需要与数据库进行交互,MySQL是一个广泛使用的开源关系型数据库管理系统,它在...

    Global site tag (gtag.js) - Google Analytics