zoukankan      html  css  js  c++  java
  • JDBC

      JDBC是用于运行SQL的一种解决方案,开发人员使用JDBC的标准接口,数据库厂商对接口进行实现,这样开发人员就无需接触底层数据库驱动程序的差异性。

    1.连接数据库

      为了连接数据库系统,必须要有JDBC驱动程序,可以将驱动程序JAR包放在WEB应用的/WEB-INF/lib下。通常,要执行以下几个步骤:

      (1)加载驱动:

      可以通过java.lang.Class类的forName(),动态加载驱动。

    try{
    Class.forName("com.mysql.jdbc.Driver");
    }
    catch(ClassNotFoundException e) {
    System.out.println("找不到指定类");
    }

    一旦类被加载,DriverManager就会注册驱动类的实例,稍后要取得Connection实例,DriverManager就知道使用哪个实例来生产Connection实例。

      (2)提供JDBC URL

      JDBC URL定义了连接数据库时的协议、子协议、数据源等标识。

      Mysql的JDBC URL编写方式如下:

      jdbc:mysql://主机名:连接端口:/数据库名?参数=值&参数=值

      如果使用中文访问,还要给定参数useUnicode及characterEncoding。

      jdbc:mysql://localhost:3306/demo?user=root&password=123&useUnicode=true&characterEncoding=UTF-8

      (3)取得Connection实例

      要连接数据库,可以向DriverManager取得Connection对象。一个Connection对象就代表一个数据库连接。

    Connection conn = null;
    try {
    String url = "jdbc:mysql://localhost:3306/demo?" +
    "user=root&password=123456";
    conn = DriverManager.getConnection(url);
    ...
    }
    finally {
    if(conn != null) {
    try {
    conn.close();
    }
    catch(SQLException e) {
    ...
    }
    }
    }

    getConnection()也可以在参数上指定用户名与密码:

        String url = "jdbc:mysql://localhost:3306/demo" ; 
    String user = "root";
    String password = "123456";
    Connection conn = DriverManager.getConnection(url, user, password);

     

      由于取得Connection的方法依所使用的环境及程序需求有所不同,直接在程序代码中固定取得Connection的方式并不是明智之举。在Java EE的环境中,将取得连接等与数据库来源相关的行为规范在javax.sql.DataSource接口,而实际如何取得Connection则由实现接口的对象来负责。

      问题简化为如何取得DataSource实例。为了让应用程序在需要取得某些与系统相关的资源对象时,能与实际的系统资源配置、实体机器位置、环境架构等无关,在Java应用程序中可以通过JNDI来取得所需的资源对象。

    try {
    Context initContext = new InitialContext();
    Context envContext = (Context)initContext.lookup("java:comp/env");
    dataSource = (DataSource)envContext.lookup("jdbc/demo");
    } catch(NamingException e) {
    ...
    }

    假如有以下代码:DatabaseBean.java

    import java.sql.*;
    import java.util.logging.*;
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    import javax.sql.DataSource;

    public class DatabaseBean {
    private DataSource dataSource;

    public DatabaseBean() {
    try {
    Context initContext = new InitialContext();
    Context envContext = (Context)
    initContext.lookup("java:/comp/env");
    dataSource = (DataSource) envContext.lookup("jdbc/demo");
    } catch (NamingException ex) {
    Logger.getLogger(DatabaseBean.class.getName())
    .log(Level.SEVERE, null, ex);
    throw new RuntimeException(ex);
    }
    }

    public boolean isConnectedOK() {
    boolean ok = false;
    Connection conn = null;
    try {
    conn = dataSource.getConnection();
    if (!conn.isClosed()) {
    ok = true;
    }
    } catch (SQLException ex) {
    Logger.getLogger(DatabaseBean.class.getName())
    .log(Level.SEVERE, null, ex);
    } finally {
    if (conn != null) {
    try {
    conn.close();
    } catch (SQLException ex) {
    Logger.getLogger(DatabaseBean.class.getName())
    .log(Level.SEVERE, null, ex);
    }
    }
    }
    return ok;
    }
    }

    只看这里的代码,不会知道实际上使用了哪个驱动程序,数据库名称,密码是什么。这些都由数据库管理员或者服务器管理员设置,你唯一要知道的就是jdbc/demo这个JNDI名称,并且在web.xml中设置。

    <resource-ref>
    <res-ref-name>jdbc/demo</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>

    可以通过下面的代码测试这个类:

    <%@page contentType="text/html" pageEncoding="UTF-8"%>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <jsp:useBean id="db" class="DatabaseBean"/>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd"
    >

    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>测试数据库连接</title>
    </head>
    <body>
    <c:choose>
    <c:when test="${db.connectedOK}">连接成功!</c:when>
    <c:otherwise>连接失败!</c:otherwise>
    </c:choose>
    </body>
    </html>

    就一个Java开发者的角度,它的工作已经完成了。现在假设你是服务器管理员,负责设置JNDI相关资源,假设应用程序部署在Tomcat 6上,可以要求应用程序在封装为WAR时,在META-INF文件夹下包括一个context.xml。

    <?xml version="1.0" encoding="UTF-8"?>
    <Context antiJARLocking="true" path="/JDBCDemo">
    <Resource name="jdbc/demo" auth="Container" type="javax.sql.DataSource"
    maxActive
    ="100" maxIdle="30" maxWait="10000"
    username
    ="root" password="!123456" driverClassName="com.mysql.jdbc.Driver"
    url
    ="jdbc:mysql://localhost:3306/demo?useUnicode=true&amp;characterEncoding=UTF8"/>

    </Context>

    2.执行数据库操作

      要执行SQL,必须取得java.sql.Statement对象,取得之后金额以使用executeUpdate()和executeQuery()来执行SQL。

      executeUpdate()返回int值,表示数据变动的条数;executeQuery()返回java.sql.ResultSet对象,代表查询结果。
      

    import java.sql.*;
    import java.util.*;
    import java.util.logging.*;
    import javax.naming.*;
    import javax.sql.DataSource;

    public class GuestBookBean {
    private DataSource dataSource;

    public GuestBookBean() {
    try {
    Context initContext = new InitialContext();
    Context envContext = (Context)
    initContext.lookup("java:/comp/env");
    dataSource = (DataSource) envContext.lookup("jdbc/demo");
    } catch (NamingException ex) {
    Logger.getLogger(DatabaseBean.class.getName())
    .log(Level.SEVERE, null, ex);
    throw new RuntimeException(ex);
    }
    }

    public void setMessage(Message message) {
    Connection conn = null;
    Statement statement = null;
    try {
    conn = dataSource.getConnection();
    statement = conn.createStatement();
    statement.executeUpdate(
    "INSERT INTO t_message(name, email, msg) VALUES ('"
    + message.getName() + "', '"
    + message.getEmail() +"', '"
    + message.getMsg() + "')");
    } catch (SQLException ex) {
    Logger.getLogger(GuestBookBean.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
    try {
    if (statement != null) {
    statement.close();
    }
    } catch (SQLException ex) {
    Logger.getLogger(GuestBookBean.class.getName()).log(Level.SEVERE, null, ex);
    throw new RuntimeException(ex);
    }
    try {
    if (conn != null) {
    conn.close();
    }
    } catch (SQLException ex) {
    Logger.getLogger(GuestBookBean.class.getName()).log(Level.SEVERE, null, ex);
    throw new RuntimeException(ex);
    }
    }
    }

    public List<Message> getMessages() {
    Connection conn = null;
    Statement statement = null;
    ResultSet result = null;
    List<Message> messages = null;
    try {
    conn = dataSource.getConnection();
    statement = conn.createStatement();
    result = statement.executeQuery("SELECT * FROM t_message");
    messages = new ArrayList<Message>();
    while (result.next()) {
    Message message = new Message();
    message.setId(result.getLong(1));
    message.setName(result.getString(2));
    message.setEmail(result.getString(3));
    message.setMsg(result.getString(4));
    messages.add(message);
    }
    } catch (SQLException ex) {
    Logger.getLogger(GuestBookBean.class.getName()).log(Level.SEVERE, null, ex);
    throw new RuntimeException(ex);
    } finally {
    try {
    if (result != null) {
    result.close();
    }
    } catch (SQLException ex) {
    Logger.getLogger(GuestBookBean.class.getName()).log(Level.SEVERE, null, ex);
    throw new RuntimeException(ex);
    }
    try {
    if (statement != null) {
    statement.close();
    }
    } catch (SQLException ex) {
    Logger.getLogger(GuestBookBean.class.getName()).log(Level.SEVERE, null, ex);
    throw new RuntimeException(ex);
    }
    try {
    if (conn != null) {
    conn.close();
    }
    } catch (SQLException ex) {
    Logger.getLogger(GuestBookBean.class.getName()).log(Level.SEVERE, null, ex);
    throw new RuntimeException(ex);
    }

    }
    return messages;
    }
    }

    在使用完Connection、Statement或ResultSet时,要将之关闭以释放相关资源。

  • 相关阅读:
    IE里ActiveXObject的一些实践
    JS兼容性问题汇总
    js:apply/call
    mark 一些近来用过的js库
    (转)时序分析基本概念
    (转载) 使用TimeQuest时序分析器
    (转)Altera对应的时序概念
    有序符号表(二叉树实现,JAVA,算法(四))
    有序符号表(数组实现,JAVA,算法(四),二分法)
    无序符号表(链表实现,JAVA,算法(四))
  • 原文地址:https://www.cnblogs.com/liuping/p/2230667.html
Copyright © 2011-2022 走看看