服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

数据源在jdbc中的应用(2)


  下面详细介绍一下数据源和javax.sql.datasource接口。在数据源中存储了所有建立数据库连接的信息。就象通过指定文件名你可以在文件系统中找到文件一样,通过提供正确的数据源名称,你可以找到相应的数据库连接。javax.sql.datasource接口定义了如 何实现数据源。在该接口中定义了九个属性。表一列出了对这些属性的描述。由于本文是以8i为例,在8i中没有实现rolename属性,所以在表中没有对此属性做描述。
  表一:数据源标准属性
  属性名称
  属性数据类型 描述
  databasename string 数据库名称,即数据库的sid。
  datasourcename string 数据源接口实现类的名称。
  description string 对数据源的描述。
  networkprotocol string 和服务器通讯使用的网络协议名。在8i中,该属性只在使用oci驱动程序时有效,缺省协议是tcp协议。
  password string 用户登录密码。
  portnumber int 数据库服务器使用的端口,缺省值为1521。
  servername string 数据库服务器名称。
  user string 用户登录名。
  在javax.sql.datasource接口中定义了以下方法:
  * public synchronized void setdatabasename(string dbname)
  * public synchronized string getdatabasename()
  * public synchronized void setdatasourcename(string dsname)
  * public synchronized string getdatasourcename()
  * public synchronized void setdescription(string desc)
  * public synchronized string getdescription()
  * public synchronized void setnetworkprotocol(string np)
  * public synchronized string getnetworkprotocol()
  * public synchronized void setpassword(string pwd)
  * public synchronized void setportnumber(int pn)
  * public synchronized int getportnumber()
  * public synchronized void setservername(string sn)
  * public synchronized string getservername()
  * public synchronized void setuser(string user)
  * public synchronized string getuser()
  通过这些方法,程序员可以获得建立连接需要的所有信息。需要注意的是,程序员不可以获取登陆密码,这就在一定程度上保证了安全性。需要注意的另一点是所有的方法都是synchronized方法,这是为了保证应用程序的线程安全(thread-safe)。如果在调用 该方法时,即使数据源实例发生变化不会影响程序的正确运行。
  除了实现由sun定义的属性和方法外,8i还提供了自己的数据源属性和方法。这些方法和 属性是在oracle.jdbc.pool.datasource中实现的。 8i扩展数据源属性如表二所示:
  表二:
  属性名称 属性数据类型 描述
  drivertype string 使用的 jdbc驱动程序的类型,包括oci8, thin和kprb
  url string 数据库连接的url。
  tnsentry string tns条目名称
  在oracle.jdbc.pool.datasource中除了实现javax.sql.datasource接口中定义的方法外
  ,还实现了以下方法:
  * public synchronized void setdrivertype(string dt)
  * public synchronized string getdrivertype()
  * public synchronized void seturl(string url)
  * public synchronized string geturl()
  * public synchronized void settnsentryname(string tns)
  * public synchronized string gettnsentryname()
  同时,datasource还实现了java.io.serializable和javax.naming.referenceable接口 。
  独立使用数据源实际应用中,你可以把datasource注册到jndi,也可以单独使用。下面先给出一个单独 使用datasource的例子:
  // 初始化数据源实例
  datasource ods = new datasource();
  ods.setdrivertype("thin");
  ods.setservername("chicago");
  ods.setnetworkprotocol("tcp");
  ods.setdatabasename("chidb");
  ods.setportnumber(1521);
  ods.setuser("guest");
  ods.setpassword("guest");
  // 从数据源中获取数据库连接
  connection conn = ods.getconnection();
  // 通过数据库连接进行数据操作
     ………………
  使用datasource时有几点需要注意:
  如果使用的时服务器端内部驱动程序(server-side internal driver),drivertype属
  性会被设置为kprb,其它所有属性失效。
  如果使用thin或oci驱动程序:
  url中可以包括用户登录名和用户登录密码。例如:
  jdbcracle:thin:guest/guest@chicago:1521:chidb;
  如果设定了url属性,tnsentry, drivertype, portnumber, networkprotocol, server
  name,和databasename属性将失效。
  在没有设定url属性的情况下,如果设定了tnsentry属性,portnumber, networkprotoc
  ol, servername,和databasename属性将失效。
  如果使用oci驱动程序,并且networkprotocol属性被设定为ipc,除user和password外的
  所有其他属性将失效。
  通过jndi使用数据源在本节首先给出了一个实际程序,然后通过程序来讲解如何通过jndi查询数据源。
  import java.sql.*;
  import javax.sql.*;
  import oracle.jdbc.driver.*;
  import oracle.jdbc.pool.datasource;
  import javax.naming.*;
  import javax.naming.spi.*;
  import java.util.hashtable;
  public class datasourcejndi
  {
  public static void main (string args [])
  throws sqlexception
  {
  // 初始化名称服务环境
  context ctx = null;
  try
  {
  hashtable env = new hashtable (5);
  env.put (context.initial_context_factory,
  "com.sun.jndi.fscontext.reffscontextfactory");
  env.put (context.provider_url, "file:jndi");
  ctx = new initialcontext(env);
  }
  catch (namingexception ne)
  {
  ne.printstacktrace();
  }
  bind(ctx, "jdbc/chidb");
  lookup(ctx, "jdbc/chidb");
  }
  static void bind (context ctx, string ln)
  throws namingexception, sqlexception
  {
  // 创建一个datasource实例
  datasource ods = new datasource();
  ods.setdrivertype("thin");
  ods.setservername("chicago");
  ods.setnetworkprotocol("tcp");
  ods.setdatabasename("chidb");
  ods.setportnumber(1521);
  ods.setuser("guest");
  ods.setpassword("guest");
  // 把datasource实例注册到jndi中
  system.out.println ("doing a bind with the logical name : " + ln);
  ctx.bind (ln,ods);
  system.out.println ("successfully bound");
  }
  static void lookup (context ctx, string ln)
  throws namingexception, sqlexception
  {
  // 从jndi中查询datasource实例
  system.out.println ("doing a lookup with the logical name : " + ln);
  datasource ods = (datasource) ctx.lookup (ln);
  system.out.println ("successful lookup");
  // 从查询到的datasource实例中获取数据库连接
    connection conn = ods.getconnection();
    // 进行数据库操作
  getusername(conn);
  // 关闭连接
  conn.close();
  conn = null;
  }
  static void getusername(connection conn)
  throws sqlexception
  {
  // 生成一个statement实例
  statement stmt = conn.createstatement ();
  // 从addressbook表中选中姓名列
  resultset rset = stmt.executequery ("select name from addressbook");
  // 列出addressbook表所有人的姓名
  while (rset.next ())
  system.out.println ("name is " + rset.getstring (1));
  // 关闭rseultset实例
  rset.close();
  rset = null;
  // 关闭statement实例
  stmt.close();
  stmt = null;
  stmt = null;
  }
  }
  程序首先生成了一个context实例。javax.naming.context接口定义了名称服务环境(n aming context)及该环境支持的操作。名称服务环境实际上是由名称和对象间的相互映 射组成。程序中初始化名称服务环境的环境工厂(context factory)是com.sun.jndi.
  fscontext.reffscontextfactory(该类在fscontext.jar中可以找到,由于fscontext.
  jar中包含的不是标准的api,用户需要从www.javasoft.com中的jndi专区下载一个名为
  fscontext1_2beta3.zip的压缩文件,在该文件中可以找到fscontext.jar)。环境工厂的
  作用是生成名称服务环境的实例,javax.naming.spi.initialcontextfactory接口定义 了环境工厂应该如何初始化名称服务环境。在初始化名称服务环境时还需要定义环境的 url。程序中使用的是"file:jndi",也就是把环境保存在本地硬盘的jndi目录下。
  初始化了名称服务环境后,就可以把数据源实例注册到名称服务环境中。注册时调用javax.naming.context.bind()方法,参数为注册名称和注册对象。注册成功后,在jndi目 录下会生成一个.binding文件,该文件记录了当前名

扫描关注微信公众号