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语句会成功,一切都将被回滚。
* */
}
JDBC浅析
最新推荐文章于 2021-02-18 08:24:27 发布