JDBC浅析

package JDBC;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
 * 数据库URL制定:
 * 
 * -------------------------------------------------------------------
 * 
 * 流行的JDBC驱动程序名和数据库的URL:
 * RDBMS	JDBC驱动程序的名称	                   URL 格式
 * MySQL    com.mysql.jdbc.Driver              jdbc:mysql://hostname/ databaseName
 * ORACLE   oracle.jdbc.driver.OracleDriver    jdbc:oracle:thin:@hostname:port Number:databaseName
 * DB2      COM.ibm.db2.jdbc.net.DB2Driver     jdbc:db2:hostname:port Number/databaseName
 * Sybase   com.sybase.jdbc.SybDriver          jdbc:sybase:Tds:hostname: port Number/databaseName
 * */

public class DB
{
	private Connection con;
	private PreparedStatement pstm;

	private String url="jdbc:mysql://localhost:3306/db_chaoshi";
	private String user="root";
	private String password="root";
	private String className="com.mysql.jdbc.Driver";
	
//	private String user = "sa";
//	private String password = "sa";
//	private String className = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
//	private String url = "jdbc:sqlserver://localhost:1433;databaseName=db_chaoshi";

	/**
	 * 注册JDBC驱动程序,有三种方法
	 * 方法一:Class.forName()
	 * 注册一个驱动程序中最常用的方法是使用Java的Class.forName()方法来动态加载驱动程序的类文件到内存中,它会自动将其注册。这种方法是可取的,因为它允许使驱动注册配置,便于携带。
	 * 
	 * 通过Class把类先装载到java的虚拟机中,并没有创建Driver类的实例。
	 * -------------------------------------------------------------------
	 * 方法二:new com.mysql.jdbc.Driver() 或  DriverManager.registerDriver()
	 * 这里不需要这样写DriverManager.registerDriver(new com.mysql.jdbc.Driver()),原因是com.mysql.jdbc.Driver类的静态代码快里面已经进行了修改的操作。我们通过Driver类的源码可以了解到,Driver类中就有一个静态的代码块,只要我们执行了Driver类中的静态代码块,并把驱动的实例放入到Drivers的一个数组列表中,我们再调用方法registerDrever就相当于又向drivers列表中放了一次driver驱动,虽然这并不影响我们程序,但是这样做实在是没有必要,还会影响程序的运行。
	 * 
	 * 由new com.mysql.jdbc.Driver()可以知道,这里需要创建一个类的实例。创建类的实例就需要在java文件中将该类通过import导入,否则就会报错,即采用这种方式,程序在编译的时候不能脱离驱动类包,为程序切换到其他数据库带来麻烦
	 * -------------------------------------------------------------------
	 * 方法三:System.setProperty("jdbc.drivers","com.mysql.jdbc.Driver");
	 * 可以同时导入多个jdbc驱动,中间用冒号“:”分开
	 * 比如System.setProperty("jdbc.drivers","XXXDriver:XXXDriver:XXXDriver");
	 * 这样就一次注册了三个数据库驱动
	 * 
	 * demo:
	 * System.setProperty("jdbc.driver","com.mysql.jdbc.Driver");//系统属性指定数据库驱动  
	 * String url="jdbc:mysql://localhost:3306/databasename";//数据库连接子协议  
	 * Connection conn=DriverManager.getConnection(url,"username","password"); 
	 * -------------------------------------------------------------------
	 * jdbc是使用桥的模式进行连接的。DriverManager就是管理数据库驱动的一个类,java.sql.Driver就 是一个提供注册数据库驱动的接口,而com.microsoft.sqlserver.jdbc.SQLServerDriver()是 java.sql.Driver接口的一个具体实现。
	 * */
	public DB()
	{
		try
		{
			Class.forName(className); 
		} catch (ClassNotFoundException e)
		{
			System.out.println("加载数据库驱动失败!");
			e.printStackTrace();
		}
	}

	/** 
	 * 创建数据库连接
	 * 
	 * 当加载的驱动程序,可以建立程序中使用DriverManager.getConnection()方法的连接:
     * 
     * 1、getConnection(String url)
     * 
     * 在这种情况下,数据库的URL,包括用户名和密码,并具有以下的一般形式:jdbc:oracle:driver:username/password@database
     * demo:
     * String URL = "jdbc:oracle:thin:username/password@amrood:1521:EMP";
     * Connection conn = DriverManager.getConnection(URL);
     * -------------------------------------------------------------------
     * 
     * 2、getConnection(String url, Properties prop)
     * 
     * 需要一个数据库URL和一个Properties对象。Properties对象,保存一组关键字 - 值对。它被用来调用getConnection()方法时驱动程序属性传递给驱动程序。
     * demo:
     * String URL = "jdbc:oracle:thin:@amrood:1521:EMP";
     * Properties info = new Properties( );
     * info.put( "user", "username" );
     * info.put( "password", "password" );
     * Connection conn = DriverManager.getConnection(URL, info);
     * -------------------------------------------------------------------
     * 
     * 3、getConnection(String url, String user, String password)
     * 
     * demo:
     * String URL = "jdbc:oracle:thin:@amrood:1521:EMP";
     * String USER = "username";
     * String PASS = "password"
     * Connection conn = DriverManager.getConnection(URL, USER, PASS); 
	 *  
	 * */
	public Connection getCon()
	{
		try
		{
			con = DriverManager.getConnection(url, user, password); // 打开一个连接
		} catch (SQLException e)
		{
			System.out.println("创建数据库连接失败!");
			con = null;
			e.printStackTrace();
		}
		return con;
	}

	/**
	 * 执行sql语句
	 * 
	 * 在JDBC Statement, CallableStatement 和 PreparedStatement 接口定义的方法和属性,使可以发送SQL或PL/SQL命令和从数据库接收数据。
	 * 
	 * 接口                                                推荐使用
	 * Statement	                     使用通用访问数据库。当在运行时使用静态SQL语句。 Statement接口不能接受的参数。
	 * PreparedStatement	当计划多次使用SQL语句。 那么可以PreparedStatement接口接收在运行时输入参数。
	 * CallableStatement	当要访问数据库中的存储过程中使用。 CallableStatement对象的接口还可以接受运行时输入参数。
	 * 
	 * -------------------------------------------------------------------
	 * 创建Statement对象:
	 * 在可以使用Statement对象执行SQL语句,需要使用Connection对象的createStatement( )方法创建一个
	 * demo:
	 * Statement stmt = null;
	 * try {
	 *    stmt = conn.createStatement( );
	 *    . . .
	 * }
	 * catch (SQLException e) {
	 *    . . .
	 * }finally {
	 *    . . .
	 * }
	 * 一旦创建了一个Statement对象,然后可以用它来与它的三个执行方法之一执行SQL语句。
	 * boolean execute(String SQL):
	 * 如果ResultSet对象可以被检索返回布尔值true,否则返回false。使用这个方法来执行SQL DDL语句,或当需要使用真正的动态SQL。
	 * 
	 * int executeUpdate(String SQL):
	 * 返回受影响的SQL语句执行的行的数目。使用此方法来执行,而希望得到一些受影响的行的SQL语句 - 例如,INSERT,UPDATE或DELETE语句。
	 * 
	 * ResultSet executeQuery(String SQL):
	 * 返回ResultSet对象。当希望得到一个结果集使用此方法,就像使用一个SELECT语句。
	 * 
	 * -------------------------------------------------------------------
	 * 创建PreparedStatement对象
	 * PreparedStatement接口扩展了Statement接口,让过一个通用的Statement对象增加几个高级功能。statement提供动态参数的灵活性。
	 * PreparedStatement pstmt = null;
	 * try {
	 *    String SQL = "Update Employees SET age = ? WHERE id = ?";
	 *    pstmt = conn.prepareStatement(SQL);
	 *    . . .
	 * }   
	 * catch (SQLException e) {   
	 *    . . .   
	 * }  
	 * finally {   
	 *    . . .   
	 * }
	 * 在JDBC中所有的参数都被代表?符号,这是已知的参数标记。在执行SQL语句之前,必须提供值的每一个参数。
	 * setXXX()方法将值绑定到参数,其中XXX表示希望绑定到输入参数值的Java数据类型。如果忘了提供值,将收到一个SQLException。
	 * 每个参数标记是由它的序号位置引用。第一标记表示位置1,下一个位置为2 等等。这种方法不同于Java数组索引,以0开始。
	 * execute()
	 * executeQuery()
	 * executeUpdate() 
	 * 
	 * -------------------------------------------------------------------
	 * 创建CallableStatement对象:
	 * 
	 * 正如一个Connection对象创建Statement和PreparedStatement对象,它也创造了CallableStatement对象这将被用来执行调用数据库存储过程。
	 * 三种类型的参数:IN,OUT和INOUT。 PreparedStatement对象只使用IN参数。 CallableStatement对象可以使用所有三个。
	 * 参数	          描述
	 * IN	          它的值是在创建SQL语句时未知的参数。将值绑定到与setXXX()方法的参数。
	 * OUT	          其值由它返回的SQL语句提供的参数。从OUT参数的getXXX()方法检索值。
	 * INOUT	同时提供输入和输出值的参数。绑定的setXXX()方法的变量,并使用getXXX()方法检索值。
	 * 
	 * String变量的SQL表示存储过程,使用参数占位符。
	 * 使用CallableStatement对象是就像使用PreparedStatement对象。必须将值绑定到所有的参数执行该语句之前,否则将收到一个SQLException。
	 * 如果有IN参数,只要按照适用于PreparedStatement对象相同的规则和技巧;使用对应于要绑定的Java数据类型的setXXX()方法。
	 * 当使用OUT和INOUT参数就必须采用额外的CallableStatement及registerOutParameter()方法。registerOutParameter()方法JDBC数据类型绑定到数据类型的存储过程应返回。
	 * 一旦调用存储过程,用适当的getXXX()方法的输出参数检索值。这种方法投射SQL类型的值检索到Java数据类型。
	 * */
	//
	public void doPstm(String sql, Object[] params)
	{
		if (sql != null && !sql.equals(""))
		{
			if (params == null)
				params = new Object[0];

			getCon();
			if (con != null)
			{
				try
				{
					System.out.println(sql);
					pstm = con.prepareStatement(sql,
							ResultSet.TYPE_SCROLL_INSENSITIVE,
							ResultSet.CONCUR_READ_ONLY);
					for (int i = 0; i < params.length; i++)
					{
						pstm.setObject(i + 1, params[i]);
					}
					pstm.execute();
				} catch (SQLException e)
				{
					System.out.println("doPstm()方法出错!");
					e.printStackTrace();
				}
			}
		}
	}

	//获取结果集
	public ResultSet getRs() throws SQLException
	{
		return pstm.getResultSet();
	}

	//huoqu 
	public int getCount() throws SQLException
	{
		return pstm.getUpdateCount();
	}

	//关闭连接池
	public void closed()
	{
		try
		{
			if (pstm != null)
				pstm.close();
		} catch (SQLException e)
		{
			System.out.println("关闭pstm对象失败!");
			e.printStackTrace();
		}
		try
		{
			if (con != null)
			{
				con.close();
			}
		} catch (SQLException e)
		{
			System.out.println("关闭con对象失败!");
			e.printStackTrace();
		}
	}
	
	/**
	 * JDBC事务
	 * 如果JDBC连接是在自动提交模式下,它在默认情况下,那么每个SQL语句都是在其完成时提交到数据库。
	 * 这可能是对简单的应用程序,但有三个原因,你可能想关闭自动提交和管理自己的事务:
	 * 为了提高性能
	 * 为了保持业务流程的完整性
	 * 使用分布式事务
	 * 
	 * 若要控制事务,以及何时更改应用到数据库。它把单个SQL语句或一组SQL语句作为一个逻辑单元,而且如果任何语句失败,整个事务失败。
	 * 若要启用,而不是JDBC驱动程序默认使用auto-commit模式手动事务支持,使用Connection对象的的setAutoCommit()方法。如果传递一个布尔值false到setAutoCommit(),关闭自动提交。可以传递一个布尔值true将其重新打开。
	 * 
	 * 例如,如果有一个名为conn Connection对象,以下代码来关闭自动提交:
	 * conn.setAutoCommit(false);
	 * 
	 * -------------------------------------------------------------------
	 * 提交和回滚
	 * 一旦已经完成了变化,要提交更改,然后调用commit(在连接对象)方法,如下所示:
	 * conn.commit( );
	 * 否则回滚更新对数据库所做的使用命名连接conn,使用下面的代码:
	 * conn.rollback( );
	 * 
	 * demo:
	 * try{
	 *    conn.setAutoCommit(false);
	 *    Statement stmt = conn.createStatement();
	 *    String SQL = "INSERT INTO Employees  " +
	 *                 "VALUES (106, 20, 'Rita', 'Tez')";
	 *    stmt.executeUpdate(SQL);  
	 *    String SQL = "INSERTED IN Employees  " +
	 *                 "VALUES (107, 22, 'Sita', 'Singh')";
	 *    stmt.executeUpdate(SQL);
	 *    conn.commit();
	 * }catch(SQLException se){
	 *    conn.rollback();
	 * }
	 * 在这种情况下没有上述INSERT语句会成功,一切都将被回滚。
	 * 
	 * -------------------------------------------------------------------
	 * 使用保存点
	 * 新的JDBC3.0保存点的接口提供了额外的事务控制。他们的环境中,如Oracle的PL/ SQL中的大多数现代的DBMS支持保存点。
	 * 当设置一个保存点在事务中定义一个逻辑回滚点。如果发生错误,过去一个保存点,则可以使用rollback方法来撤消要么所有的改变或仅保存点之后所做的更改。
	 * Connection对象有两个新的方法,可帮助管理保存点:
	 * setSavepoint(String savepointName): 定义了一个新的保存点。它也返回一个Savepoint 对象。
	 * releaseSavepoint(Savepoint savepointName): 删除一个保存点。请注意,它需要一个Savepoint 对象作为参数。这个对象通常是由setSavepoint()方法生成一个保存点。
	 * 有一个rollback ( String savepointName ) 方法回滚工作到指定的保存点。 
	 * 
	 * demo:
	 * try{
	 *    conn.setAutoCommit(false);
	 *    Statement stmt = conn.createStatement();
	 *    Savepoint savepoint1 = conn.setSavepoint("Savepoint1");
	 *    String SQL = "INSERT INTO Employees " +
	 *                 "VALUES (106, 20, 'Rita', 'Tez')";
	 *    stmt.executeUpdate(SQL); 
	 *    String SQL = "INSERTED IN Employees " +
	 *                 "VALUES (107, 22, 'Sita', 'Tez')";
	 *    stmt.executeUpdate(SQL);
	 *    conn.commit();
	 * }catch(SQLException se){
	 *    conn.rollback(savepoint1);
	 * }
	 * 
	 * 在这种情况下没有上述INSERT语句会成功,一切都将被回滚。
	 * */
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值