java(22):JDBC详解(1):结合Servlet解释使用Mysql

本文介绍了Java Database Connectivity (JDBC)的概念、核心接口及其实现数据库操作的示例代码,包括连接数据库、执行SQL语句等关键步骤。

日期:2017/11/11

一、JDBC 之 概念

      java database conectivity,是一种用于执行SQL语句的Java API,可以为 多种关系数据库 提供 统一访问接口,它由一组用 Java语言编写的 类和接口 组成。 有了JDBC,向各种关系数据发送SQL语句就是一件很容易的事。换言之,有了 JDBC API,就不必为访问Sybase数据库专门写一个程序,为访问Oracle数据库又专门写一个程序,或为访问 Informix 数据库又编写另一个程序等等,程序员只需用 JDBC API 写一个程序就够了, 它可向相应数据库发送SQL调用

    简单地说,JDBC 可做三件事:与数据库建立连接、发送操作数据库的语句 并 处理结果

软件包 java.sql

提供使用 Java TM  编程语言访问并处理存储在数据源(通常是一个关系数据库)中的数据的 API。

接口摘要
ArraySQL 类型 ARRAY 在 Java 编程语言中的映射关系。
BlobSQL BLOB 值在 JavaTM 编程语言中的表示形式(映射关系)。
CallableStatement用于执行 SQL 存储过程的接口。
ClobSQL 类型 CLOB 在 JavaTM 编程语言中的映射关系。
Connection与特定数据库的连接(会话)。
DatabaseMetaData关于数据库的整体综合信息。
Driver每个驱动程序类必须实现的接口。
NClobSQL NCLOB 类型在 JavaTM 编程语言中的映射。
ParameterMetaData可用于获取关于 PreparedStatement 对象中每个参数标记的类型和属性信息的对象。
PreparedStatement表示预编译的 SQL 语句的对象。
RefJava 编程语言中 SQL REF 值的映射关系,它是到数据库中的 SQL 结构类型值的引用。
ResultSet表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。
ResultSetMetaData可用于获取关于 ResultSet 对象中列的类型和属性信息的对象。
RowIdSQL ROWID 值在 Java 编程语言中的表示形式(映射)。
Savepoint保存点的表示形式,保存点是可以从 Connection.rollback 方法引用的当前事务中的点。
SQLData该接口用于 SQL 用户定义类型 (UDT) 到 Java 编程语言中类的自定义映射关系。
SQLInput一个输入流,它包含表示 SQL 结构化类型或 SQL 不同类型的实例的值组成的流。
SQLOutput用于将用户定义类型的属性写回数据库的输出流。
SQLXMLSQL XML 类型在 JavaTM 编程语言中的映射关系。
Statement用于执行静态 SQL 语句并返回它所生成结果的对象。
Struct用于 SQL 结构化类型的 Java 编程语言中的标准映射关系。
Wrapper在相关实例实际上是代理类时提供获取委托实例能力的 JDBC 类的接口。
 

类摘要
Date一个包装了毫秒值的瘦包装器 (thin wrapper),它允许 JDBC 将毫秒值标识为 SQL DATE值。
DriverManager管理一组 JDBC 驱动程序的基本服务。
DriverPropertyInfo用于建立连接的驱动程序属性。
SQLPermissionSecurityManager 将用来检查在 applet 中运行的代码何时调用 DriverManager.setLogWriter 方法或 DriverManager.setLogStream(不建议使用)方法的权限。
Time一个与 java.util.Date 类有关的瘦包装器 (thin wrapper),它允许 JDBC 将该类标识为 SQL TIME 值。
Timestamp一个与 java.util.Date 类有关的瘦包装器 (thin wrapper),它允许 JDBC API 将该类标识为 SQL TIMESTAMP 值。
Types定义用于标识一般 SQL 类型(称为 JDBC 类型)的常量的类。


二、JDBC 之 常用接口

2.1 Connection接口

      Connection接口代表与数据库的连接, Connection接口实例相当于在 应用程序  和 数据库 之间建立了一条渠道。与特定数据库的连接(会话)。在连接上下文中执行 SQL 语句并返回结果。Connection 对象的数据库能够提供描述其表、所支持的 SQL 语法、存储过程、此连接功能等等的信息。此信息是使用 getMetaData 方法获得的。

     Connection接口 - Connection与特定数据库的连接(会话),在连接上下文中执行SQL语句并返回结果。
    - DriverManager的 getConnection() 方法建立在JDBC URL中定义的数据库Connection连接上
      -Mysql
        Connection con = DriverManager.getConnection("jdbc:mysql://host:port/database", "user", "password");
      -Oracle
        Connection con = DriverManager.getConnection("jdbc:oracle:thin@host:port/database", "user", "password");

java.sql 
接口 Connection

所有超级接口:
Wrapper

public interface Connection
   
   
    
    extends 
    
    Wrapper
   
   

 voidclose() 
          立即释放此 Connection 对象的数据库和 JDBC 资源,而不是等待它们被自动释放。
 StatementcreateStatement() 
          创建一个 Statement 对象来将 SQL 语句发送到数据库。
 StatementcreateStatement(int resultSetType, int resultSetConcurrency) 
          创建一个 Statement 对象,该对象将生成具有给定类型和并发性的 ResultSet 对象。
 StatementcreateStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) 
          创建一个 Statement 对象,该对象将生成具有给定类型、并发性和可保存性的 ResultSet 对象。
 PreparedStatementprepareStatement(String sql) 
          创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库。
 PreparedStatementprepareStatement(String sql, int autoGeneratedKeys) 
          创建一个默认 PreparedStatement 对象,该对象能获取自动生成的键。
 PreparedStatementprepareStatement(String sql, int[] columnIndexes) 
          创建一个能返回由给定数组指定的自动生成键的默认 PreparedStatement 对象。
 PreparedStatementprepareStatement(String sql, int resultSetType, int resultSetConcurrency) 
          创建一个 PreparedStatement 对象,该对象将生成具有给定类型和并发性的 ResultSet 对象。
 PreparedStatementprepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) 
          创建一个 PreparedStatement 对象,该对象将生成具有给定类型、并发性和可保存性的 ResultSet 对象。
 PreparedStatementprepareStatement(String sql, String[] columnNames) 
          创建一个能返回由给定数组指定的自动生成键的默认 PreparedStatement 对象。


2.2 Statement接口

    Statement接口用于创建 向数据库传递SQL语句 的对象,提供了 许多操作数据库的方法用于执行静态 SQL 语句并返回它所生成结果的对象。java.sql 

接口 Statement

所有超级接口:
Wrapper
所有已知子接口:
CallableStatementPreparedStatement

public interface Statement
   
   
    
    extends 
    
    Wrapper
   
   

 voidclose() 
          立即释放此 Statement 对象的数据库和 JDBC 资源,而不是等待该对象自动关闭时发生此操作。

 booleanexecute(String sql) 
          执行给定的 SQL 语句,该语句可能返回多个结果。
 booleanexecute(String sql, int autoGeneratedKeys) 
          执行给定的 SQL 语句(该语句可能返回多个结果),并通知驱动程序所有自动生成的键都应该可用于获取。
 booleanexecute(String sql, int[] columnIndexes) 
          执行给定的 SQL 语句(该语句可能返回多个结果),并通知驱动程序在给定数组中指示的自动生成的键应该可用于获取。
 booleanexecute(String sql, String[] columnNames) 
          执行给定的 SQL 语句(该语句可能返回多个结果),并通知驱动程序在给定数组中指示的自动生成的键应该可用于获取。
 ResultSetexecuteQuery(String sql) 
          执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。
 intexecuteUpdate(String sql) 
          执行给定 SQL 语句,该语句可能为 INSERTUPDATE 或 DELETE 语句,或者不返回任何内容的 SQL 语句(如 SQL DDL 语句)。
ConnectiongetConnection() 
          获取生成此 Statement 对象的 Connection 对象。
 intgetMaxRows() 
          获取由此 Statement 对象生成的 ResultSet 对象可以包含的最大行数。
 ResultSetgetResultSet() 
          以 ResultSet 对象的形式获取当前结果。



2.3  PreparedStatement 接口

     表示预编译的 SQL 语句的对象。SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。

java.sql 
接口 PreparedStatement

所有超级接口:
StatementWrapper
所有已知子接口:
CallableStatement

public interface PreparedStatement
   
   
    
    extends 
    
    Statement
   
   

 booleanexecute() 
          在此 PreparedStatement 对象中执行 SQL 语句,该语句可以是任何种类的 SQL 语句。
 ResultSetexecuteQuery() 
          在此 PreparedStatement 对象中执行 SQL 查询,并返回该查询生成的 ResultSet 对象。
ParameterMetaDatagetParameterMetaData() 
          获取此 PreparedStatement 对象的参数的编号、类型和属性。



2.4  DriverManager 接口

管理一组 JDBC 驱动程序的基本服务。
注:DataSource 接口是 JDBC 2.0 API 中的新增内容,它提供了连接到数据源的另一种方法。使用 DataSource 对象是连接到数据源的首选方法。

java.sql 

类 DriverManager

java.lang.Object
  继承者 java.sql.DriverManager

public class DriverManager
   
   
    
    extends 
    
    Object
   
   

static ConnectiongetConnection(String url) 
          试图建立到给定数据库 URL 的连接。
static ConnectiongetConnection(String url, Properties info) 
          试图建立到给定数据库 URL 的连接。
static ConnectiongetConnection(String url, String user, String password) 
          试图建立到给定数据库 URL 的连接。
static DrivergetDriver(String url) 
          试图查找能理解给定 URL 的驱动程序。


2.5  ResultSet 接口

     类似于临时表,用于暂存数据库查询操作获得的结果集。表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。ResultSet 对象具有指向其当前数据行的光标。最初,光标被置于第一行之前。next 方法将光标移动到下一行;因为该方法在 ResultSet 对象没有下一行时返回 false,所以可以在 while 循环中使用它来迭代结果集。
     默认的 ResultSet 对象不可更新,仅有一个向前移动的光标。因此,只能迭代它一次,并且只能按从第一行到最后一行的顺序进行。可以生成可滚动和/或可更 新的 ResultSet 对象。

java.sql 
接口 ResultSet

所有超级接口:
Wrapper
所有已知子接口:
CachedRowSetFilteredRowSetJdbcRowSetJoinRowSetRowSetSyncResolverWebRowSet

public interface ResultSet
   
   
    
    extends 
    
    Wrapper
   
   
 voidclose() 
          立即释放此 ResultSet 对象的数据库和 JDBC 资源,而不是等待该对象自动关闭时发生此操作。
 ArraygetArray(int columnIndex) 
          以 Java 编程语言中 Array 对象的形式获取此 ResultSet 对象的当前行中指定列的值。
 ArraygetArray(String columnLabel) 
          以 Java 编程语言中 Array 对象的形式获取此 ResultSet 对象的当前行中指定列的值。
 StatementgetStatement() 
          获取生成此 ResultSet 对象的 Statement 对象。
 booleannext() 
          将光标从当前位置向前移一行。



三、JDBC 之 代码讲解

(1)通用形式:

package srevletTest;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletMySQL extends HttpServlet{

	@SuppressWarnings("null")
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("in doGet()... hahaha");
		String user = "root";
		String password = "";
		String url = "jdbc:mysql://localhost:3306/test";
		String driver = "com.mysql.jdbc.Driver";
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;		
		PrintWriter out = response.getWriter();		
		out.println("<table border=1>");
		out.println("<tr><td>Contend:</td></tr>");
		try{
			System.out.println("222 in doGet()... hahaha");
			Class. forName(driver);//加载驱动,Class.forName
			System.out.println("333 driver successfully... hahaha");
//			conn = DriverManager.getConnection(url, user, password);//建立连接
			conn = DriverManager.getConnection("jdbc:mysql://localhost/test?user=root&password=");
			System.out.println("444 connection successfully...hahaha");
			//内存泄露
//			rs = stmt.executeQuery("select * from classtable");
			rs = stmt.executeQuery("USE TEST");
			rs = stmt.executeQuery("select name from classtable");
			System.out.println("select name from classtable  :");
//			Collection c = new ArrayList();
			while(rs.next()){
				System.out.println("show result...kkkk");
				out.println("<tr>");
				out.println("<td>" + rs.getString("name") + "</td>");
				out.println("</tr>");
				System.out.println("After**");
//				int a1 = rs.getInt(1);
//				String a2 = rs.getString(2);
//				String a3 = rs.getString(3);
//				int a4 =  rs.getInt(4);
//				String a5 = rs.getString(5);
//				int a6 =  rs.getInt(6);
//				System.out.println(a1+" "+a2 +" "+a3 +" "+a4+" "+a5+" "+a6);
//				c.add(a1);c.add(a2);c.add(a3);c.add(a4);c.add(a5);c.add(a6);
//				System.out.println(c);
//				Iterator it = c.iterator();
//				while(it.hasNext()){
//					out.println("<tr>");
//					out.print("<td>");
//					out.print(it.next());
//					out.print("</td>");
//					out.println("</tr>");
//				}
			}
		}catch(SQLException | ClassNotFoundException e1){
			e1. printStackTrace();
		}finally{
			try{
				if(rs != null) rs.close();
				if(stmt != null) stmt.close();
				if(conn != null) conn.close();
			}catch(SQLException e){
				System.out.println(e. getMessage());
			}
		}				
	}

	@Override
	public void destroy() {
        super.destroy();
        try{
            DriverManager.deregisterDriver(DriverManager.getDrivers().nextElement());
        }catch(Exception e){
            e.printStackTrace();
        }
	}
	
	
	
}

(2)javabean封装好后,在继承servlet类后进行返回调用:


package srevletTest;
import java.sql.*;
public class DB {
	public static Connection getConn(){
		Connection conn = null;
		try{
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection("jdbc:mysql://localhost/test?user=root&password=");
			}catch(ClassNotFoundException e){
				e.printStackTrace();
			}catch(SQLException e ){
				e.printStackTrace();
			}
		return conn;
	}
	
	public static Statement getStatement(Connection conn){
		Statement stmt = null;
		try{
			if(conn != null){
				stmt = conn.createStatement();
			}
		} catch (SQLException e){
			e.printStackTrace();			
		}
		return stmt;
	}
	
	public static ResultSet getResultSet(Statement stmt,String sql){
		ResultSet rs = null;
		try {
			if (stmt != null){
				rs = stmt.executeQuery(sql);
			}
		} catch (SQLException e){
			e.printStackTrace();
		}
		return rs;
	}
	
	public static void closeConn(Connection conn){
		try{
			if(conn != null){
				conn.close();
				conn = null;
			}
		} catch (SQLException e){
			e.printStackTrace();
		}
	}
	
	public static void closeStatement(Statement stmt){
		try{
			if(stmt != null){
				stmt.close();
			}
		} catch(SQLException e){
			e.printStackTrace();
		}
	}
	
	public static void closeRs(ResultSet rs){
		try {
			if(rs != null){
				rs.close();
				rs = null;
			}
		} catch(SQLException e){
			e.printStackTrace();
		}
	}

}

package srevletTest;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DBtest extends HttpServlet{
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("in doGet()!!");
		PrintWriter out = response.getWriter();
		Connection conn = DB.getConn();
		Statement stmt = DB.getStatement(conn);
		ResultSet rs = DB.getResultSet(stmt, "SELECT * FROM classtable");
		out.println("<table border=1>");
		out.println("<tr><td>Contend:</td></tr>");
		try{
			while (rs.next()){
				out.println("<tr>");
				out.println("<td>" + rs.getString("name") + "</td>");
				out.println("</tr>");
			}			
		}catch (SQLException e){
			e.printStackTrace();
		}finally{
			DB.closeConn(conn);
			DB.closeRs(rs);
			DB.closeStatement(stmt);		
			System.out.println("allover..");
		}
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		System.out.println("in doPost()!!");
		doGet(req,resp);
	}

	@Override
	public void destroy() {
		System.out.println("destory()...");
	}

	@Override
	public void init() throws ServletException {
		System.out.println("init()...");
	}
	
	
	
	

}

PS:一、 Class.forName 有什么意思?

答: (1)这里面涉及了java的重要特性 --- 反射机制:能够 在运行时对类进行装载 或 运行时动态的创建类的对象。在反射机制中,Class 是非常重要的类;

java.lang
类 Class<T>
      java.lang.Object
      继承者 java.lang.Class<T>

static Class<?>forName(String className) 
          返回与带有给定字符串名的类或接口相关联的 Class 对象。

      (2)因此,创建对象处理new一个,还能反射机制创建。

见下例子:

package com.reflection;

class Base{
	public void f(){
		System.out.println("Base");
	}
}

class Sub extends Base{
	public void f(){
		System.out.println("Sub");
	}
}

public class ReflectionTest {
	public static void main(String[] args){
		try{
			Class c = Class. forName("Sub");
//报错:没有为类型 Class 定义方法 f()
			Base b = (Base) c.newInstance();
			b.f();
		}catch (Exception e){
			e.printStackTrace();
		}
		
	}

}

输出结果(理论上):

Sub





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后台技术汇

对你的帮助,是对我的最好鼓励。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值