第十章 JDBC(连数据库)




对于没有数据库基础的同学,重要通知:为快速入门,先学我的网站www.mark-to-win.com的数据库部分的mysql数据库!!!!!为什么?因为sql server和oracle的安装比较困难,而mysql安装简单,知识内容完全一样,我的本章程序后面附件都有sql server和oracle的程序版本。


第一节 理论基础

JDBC是什么?

马克-to-win:(视频下载) (全部书籍)JDBC即(java database connectivity数据连接)。JDBC是Sun公司编的一堆类和方法,都封装在java.sql包中。你可以利用这堆类和方法来把你的程序和数据库连通。




JDBC的优点:跨数据库性

通过使用JDBC,开发人员可以将SQL语句传送给几乎任何一种数据库。不必单独写一个程序访问Sybase,Oracle,或Microsoft的SQLServer。


JDBC的工作原理:
马克-to-win:(视频下载) (全部书籍)JDBC主要完成三件事:1)建立连接;2)发送SQL语句;3)处理返回的结果。紧接着,下节以实例仔细分析这三条。



第二节 JDBC HelloWorld例子

1.细述JDBC的工作原理

紧接着上节的JDBC的工作原理,下面我们就仔细讲讲这三条。

1)建立连接:
马克-to-win:JDBC靠java.sql.DriverManager.getConnection(dbUrl, user, password);和数据库连接。当DriverManager执行getConnection时,它会在内存当中寻找最合适的驱动类。(我们在给机器 装声卡时是不是也得先安装一个驱动程序? 道理一样,每一个数据库,都需要有一个专门和它相配的驱动程序。)所以我们需要事先就把驱动类加载进来。怎么加载?靠Class.forName (className),在我们以下的例子当中就是Class.forName("com.mysql.jdbc.Driver");马克-to- win:注意:这个类不在jdk的核心包当中,因为它只和Mysql这个数据库相关。如果jdk的核心包中包含这个类的话,那么microsoft公司的 sql server数据库,oracle,或sybase数据库等的驱动是不是都要包括在jdk的核心包中呢?如果是这样的话,jdk的核心包会不会变得很大 呢?所以这样的话就出现了一个问题。既然mysql的驱动类不在jdk的核心包中,我们需要专门在eclipse当中把它倒进我们的项目当中。注意在今天 之前的课程当中,我们从来没接触过导包,现在就教会大家在eclipse当中如何导包。在我的H盘根目录下,有个文件:mysql-connector- java-3.1.10-bin.jar,我们用WINRAR把它打开,就发现它里面有com.mysql.jdbc.Driver.class文件。右 键点击你的项目,找到Properties。在找Java Build Path。点中Libraries。再点中右边的Add External Jars。选中mysql-connector-java-3.1.10-bin.jar,如下图:


2)发送SQL语句;

马克-to-win:要想发送sql语句,就要提到一个叫Statement 的接口。Statement的中文含义是陈述。就利用这个叫“陈述”的接口。你的程序可以向数据库,义正言辞的“陈述”一条一条的sql语句。比如在我们 的程序中:resultSet = statement.executeQuery("select * from login");你觉得当时sun公司把这个接口起名叫“陈述”形象生动吗?现在问题来了,这个“陈述”是怎么来的?我要是java的设计者,我就让它从 刚才第一步获得的连接当中来。因为这样做非常顺理成章,第一步完了就第二步嘛!事实上,sun公司也确实是这么做的。在我们的程序中,就是以下这句: statement = connection.createStatement();

3)处理返回的结果。

马克-to-win:刚才的这句resultSet = statement.executeQuery("select * from login");是把select * from login这句sql语句发送给数据库。对数据库有所了解的人都知道,当我们直接向数据库输入sql语句:select * from login时,数据库会给我们返回一个表。现在其实也一样,当我们的程序向数据库发送一个ql语句时,也得到了一个表,只不过这个表现在完全放在 resultSet当中。我们通过一个循环while (resultSet.next()),就可以一行一行的处理这个表。再分别通过resultSet.getString("id") 和resultSet.getString("name"),我们就分别得到了id和name这两列数据。

在做以下的实验之前。我们的前提条件是:(视频下载) (全部书籍)必须先安装一个mysql数据库在电脑中,(因为这个数据库在所有的数据库当中,相对来讲是最简单的。适合初学者 使用和学习,而且这个数据库,现在在很多中小型公司,都还在使用。)而且数据库当中,要有一个表叫login。其中有两个字段,一个叫id,一个叫 name。两个字段都是string类型的。

例:2.1.1
public class TestMark_to_win {
    public static void main(String[] args) throws java.sql.SQLException,
            ClassNotFoundException {
        java.sql.Connection connection = null;
        java.sql.Statement statement = null;
        java.sql.ResultSet resultSet = null;
        Class.forName("com.mysql.jdbc.Driver");
        connection = java.sql.DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/test", "root", "1234");
        statement = connection.createStatement();
        resultSet = statement.executeQuery("select * from login");
        while (resultSet.next()) {
            System.out.println(resultSet.getString("id") + "--"
                    + resultSet.getString("name"));
        }
        resultSet.close();
        statement.close();
        connection.close();
    }
}

输出结果:

1--q
2--qq

第三节 PreparedStatement

1.PreparedStatement的HelloWorld程序

除 了Statement以外,(视频下载) (全部书籍)Sun公司还提供了另外一个工具PreparedStatement,它们两个的效率比较,我们下一节再说,本节我们只讲 helloworld。PreparedStatement的用法就是:PreparedStatement中的SQL语句,可有一个或多个参数。每个参 数用一个问号(“?”)来占位。之后每个问号的值必须通过适当的setXXX方法来提供。



例:2.1.1

import java.io.IOException;
public class TestMark_to_win {
    public static void main(String[] args) throws java.sql.SQLException,
            ClassNotFoundException, IOException {
        java.sql.Connection connection = null;
        java.sql.PreparedStatement pstmt;
        Class.forName("com.mysql.jdbc.Driver");
        connection = java.sql.DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/test", "root", "1234");
        pstmt = connection.prepareStatement("UPDATE login SET name = ? WHERE id = ?");

        pstmt.setString(1, "qqq");
        pstmt.setString(2, "1");
/*缺了下面这句,id为1的这一列更新不了了 */
        pstmt.executeUpdate();

        pstmt.setString(1, "qqqq");
        pstmt.setString(2, "2");
        pstmt.executeUpdate();

        pstmt.close();
        System.out.println("ok");
        connection.close();
    }
}
 

2.PreparedStatement和Statement的效率比较

马克-to-win:(视频下载) (全部书籍)前面介绍的Statement接口提供了执行sql语句和获取结果的基本方法。注 意对于有种情况,即,需要反复执行相同的sql语句时,Sun公司就为我们提供了另外一种对象:PreparedStatement。它翻译过来就是: “准备好的Statement”。用它的好处就是:当数据库见到PreparedStatement的sql语句时,数据库端直接先到数据库缓冲区当中找 它,如找不到,则会编译它一次(就像把java文件编译成class文件似的,请问java文件能直接运行吗?所以你的“UPDATE login SET name = ? WHERE id = ?”也需要编译一下,才能执行)。如能找到,就直接用。下次再遇到,就省事了。而对于Statement对象,就没有这种待遇。次次见,次次编译。

注意:如果sql语句只执行一次,以后不再复用,则建议采用Statement,因为Statement不会对sql进行预编译。


例:2.2.1
import java.io.IOException;
public class TestMark_to_win {
    public static void main(String[] args) throws java.sql.SQLException,
            ClassNotFoundException, IOException {
        int i = 0;
        java.sql.Connection connection = null;
        java.sql.PreparedStatement pstmt;
        Class.forName("com.mysql.jdbc.Driver");
        connection = java.sql.DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/test", "root", "1234");
        pstmt = connection
                .prepareStatement("UPDATE login SET name = ? WHERE id = ?");
        long t = System.currentTimeMillis();
        for(i=0;i<10000;i++) {
            pstmt.setString(1, "qqqq");
            pstmt.setString(2, "2");
            pstmt.executeUpdate();
        }
        t = System.currentTimeMillis() - t;
        System.out.println("用了如下时间:" + t);
        pstmt.close();
        System.out.println("ok");
        connection.close();
    }
}
输出结果:
用了如下时间:4256
ok


import java.io.IOException;
public class TestMark_to_win {
    public static void main(String[] args) throws java.sql.SQLException,
            ClassNotFoundException, IOException {
        int i = 0;
        java.sql.Connection connection = null;
        java.sql.Statement statement;
        Class.forName("com.mysql.jdbc.Driver");
        connection = java.sql.DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/test", "root", "1234");
        statement = connection.createStatement();
        String sqlStringupdate = "UPDATE login SET name = 'qqqq'"+" WHERE id = '2'";
        long t = System.currentTimeMillis();
        for(i=0;i<10000;i++) {
            statement.executeUpdate(sqlStringupdate);
        }
        t = System.currentTimeMillis() - t;
        System.out.println("用了如下时间:" + t);
        statement.close();
        System.out.println("ok");
        connection.close();
    }
}


输出结果:
用了如下时间:6578
ok



第四节 存储过程(stored procedures)

1.java调用存储过程(stored procedures)的HelloWorld程序

马克-to-win:(视频下载) (全部书籍)有点数据 库基础的人都知道。存储过程(stored procedures)和java没什么关系。它是一段纯粹的数据库sql语言的程序,事先存储在数据库中。没有java程序调用,人家自己独立运行的也 挺好。现在的问题就是,你有一个java程序,你想调用现有的一段存储过程,如何做这件事儿?我们底下的实验就是先向数据库存进去一个名为p4的存储过 程,然后再编一段java程序去调用它。

以下就是我向我的数据库中,插入一个叫做p4的存储过程的截图。

下 面解释一下:delimiter是定义边界的意思。delimiter $就是定义$为边界。一个$和下一个$之间就像一个区域一样,在这个区域之间的东西才会被执行。mysql缺省默认来讲见到 ;就执行,但看到delimiter $ 以后,就只会忍饥挨饿盯着直到下一个$出现,才会执行两个$之间的命令。
最后的delimiter ; 就把分隔符从$换回到默认的 ;(注意 delimiter后边一定有一个空格)

create procedure p4(OUT cnt int)

--创建MySQL存储过程p4
--此存储过程的过程名是p4,该过程包含1个参数,
--是输出类型的(以OUT标示),参数名是cnt,类型是int

select count(*) into cnt from test.login;

--再查询表test.login中count(*),将其输出到输出类型的参数cnt里面

call p4(@a);

调用p4存储过程,下面的@a是个mysql中的临时变量,就对应刚才的cnt。

顺便,如果想删除一个procedure,我们就用drop procedure p4;


mysql> use test
mysql> delimiter $
mysql> create procedure p4(OUT cnt int)
-> begin
-> select count(*) into cnt from test.login;
-> end
-> $
Query OK, 0 rows affected (0.00 sec)

-> delimiter ;

mysql> call p4(@a);
Query OK, 0 rows affected (0.00 sec)
mysql> select @a;
+------+
| @a |
+------+
| 2 |
+------+
1 row in set (0.00 sec)


下面的java程序就调用上面的p4存储过程。


例:4.1.1
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;

public class TestMark_to_win {
    public static void main(String[] args) throws ClassNotFoundException,
            SQLException {
        String dbUrl = "jdbc:mysql://localhost:3306/test";
        String user = "root";
        String password = "1234";

        Class.forName("com.mysql.jdbc.Driver");
        Connection con = DriverManager.getConnection(dbUrl, user, password);
        System.out.println("Connection is ok");

        CallableStatement cs = con.prepareCall("{call p4(?)}");
        cs.registerOutParameter(1, Types.INTEGER);
        cs.execute();
/*int getInt(int parameterIndex)
    Retrieves the value of the designated JDBC INTEGER parameter as an int in the Java programming language.
    Parameters:
        parameterIndex - the first parameter is 1, the second is 2, and so on */
        System.out.println(cs.getInt(1));
        
        cs.close();
        con.close();
    }
}

result is:

Connection is ok
2



第五节 Scrollable和Updatable ResultSet

马克-to-win:(视频下载) (全部书籍)在前面的jdbc的Helloworld程序当中,我们接触了最简单的 Statement。那种Statement的光标只能向前移。意思就是访问完2,只能继续访问3,不能再回过头来访问1。还有就是当我们查询数据库的时 候,我们不能同时修改数据库。但在现实生活当中,我们确实有这种需求,就是如果当我们正在查询一个数据库的时候,发现某个数据有问题,想当时就修改它。对 付这种情况,sun公司专门提供了一种新的Statement。即Scrollable(可滚动的,可向前可向后)和Updatable(可更新的)的 Statement。即con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);


1.Update(更新) a row程序

以下这个程序就把第二条row的id更改成了“11”。

例:5.1.1

/*when do this experiment, if it is sql server,pls make sure you have a primary key in your table.*/
import java.sql.*;
public class TestMark_to_win {
    public static void main(String[] args) throws SQLException,
            ClassNotFoundException {

            Class.forName("com.mysql.jdbc.Driver");
            Connection con = java.sql.DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/test", "root", "1234");
            String s = "select * from login";
        /* A default ResultSet object is not updatable and has a cursor that
             * moves forward only. Thus, you can iterate through it only once
             * and only from the first row to the last row. It is possible to
             * produce ResultSet objects that are scrollable and/or updatable.
             */
            Statement stm = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
                            ResultSet.CONCUR_UPDATABLE);
            ResultSet rs = stm.executeQuery(s);
            /* boolean absolute(int row) Moves the cursor to the given row
             * number in this ResultSet object.who is 1? experimentally,but
             * undocumentally, the order is based on the primary key column.
             */
            rs.absolute(2);
     /* public void updateString(String columnName,string s)throws SQLException
             * Updates the designated column with a string value. The updater
             * methods are used to update column values in the current row or
             * the insert row. The updater methods do not update the underlying
             * database; instead the updateRow or insertRow methods are called
             * to update the database. */
            rs.updateString("id", "11");
            // rs.cancelRowUpdates();
            /* public void updateRow() throws SQLException Updates the
             * underlying database with the new contents of the current row of
             * this ResultSet object.*/
            rs.updateRow();
            rs.close();
            stm.close();
            con.close();
    }
}


2.insert a row程序 

下 面的程序在第二个row的后面插入了一个新的row(因为rs.absolute(2);)实际上,当你取回一个ResultSet后,和这个 ResultSet联系在一起的,还有一个叫InsertRow的特殊的row。它就像是一个特殊的缓冲区。rs.moveToInsertRow(); 就把你的光标指向它了,接着你把你要插入的数据先放在这个缓冲区里。当你执行rs.insertRow()的时候,这个特殊的row里的数据,就被插入到 数据库当中了。

例:5.2.1

/*when do this experiment, if it is sql server,pls make sure you have a primary key in your table.*/
import java.sql.*;
public class TestMark_to_win {
    public static void main(String[] args) throws SQLException,
            ClassNotFoundException {

        Class.forName("com.mysql.jdbc.Driver");
        Connection con = java.sql.DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/test", "root", "1234");
        String s = "select * from login";
        /*
         * A default ResultSet object is not updatable and has a cursor that
         * moves forward only. Thus, you can iterate through it only once and
         * only from the first row to the last row. It is possible to produce
         * ResultSet objects that are scrollable and/or updatable.
         */
        Statement stm = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
                ResultSet.CONCUR_UPDATABLE);
        ResultSet rs = stm.executeQuery(s);
        rs.absolute(2);
        /* public void moveToInsertRow() throws SQLException Moves
         * the cursor to the insert row. The current cursor position is
         * remembered while the cursor is positioned on the insert row. The
         * insert row is a special row associated with an updatable result set.
         * It is essentially a buffer where a new row may be constructed by
         * calling the updater methods prior to inserting the row into the
         * result set.
         */
        rs.moveToInsertRow();
        rs.updateString("id", "2.5");
        rs.updateString("name", "qqq");
        /* public void insertRow() throws SQLException Inserts the contents of
         * the insert row into this ResultSet object and into the database.
         */
        rs.insertRow();


        rs.close();
        stm.close();
        con.close();

    }
}


第六节 DataSource(数据源)

马克-to-win:(视频下载) (全部书籍)在前面 的jdbc的Helloworld程序当中,我们用DriverManager来获取数据库连接。事实上通过这种方法获取数据库连接,是比较耗费计算机资 源的。当然了,这也是没有办法的事儿。就像我们买贵书必须花大价钱一样。原因是书本身就那么贵,也确实没有办法。但如果有1万个学生看书,我们能不能建立 一个小型图书馆?我们只需买100本书。而不是像没有图书馆的情况下,共买1万本书,人手一本。大家毕了业以后,每个人都销毁自己的书。这就造成了极大的 浪费。但要注意的是,每个人看完书以后,把书要还回图书馆。数据源就像这里的图书馆。里面开始也是费劲巴拉的建立了一堆连接。之后谁用谁就可以,获取一个 连接。但是用完以后,并不是销毁连接,而是把连接简单的返还给数据源,以供别的用户再用(在我的参考目录下,有个连接池实现程序,看看它的close方法,ds.getConnection返回的Connection的实例和前面jdbc helloworld的Connection实例不一样。因为Connection只是一个接口,所以每次的实例的实现都是不一样的。)。你可以想象,如果有很多客户,都需要用连接的话,数据源技术,无 疑是一个非常好的选择。在互联网的环境下,成千上万的用户,从不同的机器上,访问一台机器,从它的数据库当中获取信息。在这种情况下,数据源发挥了极大的 优势。如果用DriverManager连接完一次,销毁一次连接的话,一定是一场噩梦。


1.DataSource的HelloWorld程序


例:6.1.1

import java.sql.*;
import javax.sql.*;
import com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource;
public class TestMark_to_win {
    public static void main(String args[]) throws SQLException {
        MysqlConnectionPoolDataSource ds = new MysqlConnectionPoolDataSource();
        ds.setURL("jdbc:mysql://localhost:3306/test");
        ds.setUser("root");
        ds.setPassword("1234");
        Connection con = ds.getConnection();
        Statement stmt = con.createStatement();
        ResultSet rs = stmt.executeQuery("select * from login");
        while (rs.next()) {
            System.out.println(rs.getString("id"));
            System.out.println(rs.getString("name"));
        }
        System.out.println("ok");
    }
}

结果是:

11
q
2
qq
3
qqq
ok




2.DataSource的单态模式(SingleTon)程序

咱们还接着上面的例子来说。(视频下载) (全部书籍)1万个人要看书。千万确保要只建立一个图书馆。要是一不留神,建了两个或三个图书馆,那可就亏大发了。对于数据源来讲,最重要的是要保证在内存当中只有一个实例。如果存在多个实例,那就亏大了。

例:6.2.1

import com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource;
import java.sql.*;
import javax.sql.*;
public class DatabaseConn {

    static private MysqlConnectionPoolDataSource ds;
    private Connection con;

    private DatabaseConn() {
        ds = new MysqlConnectionPoolDataSource();
        ds.setURL("jdbc:mysql://localhost:3306/test");
        ds.setUser("root");
        ds.setPassword("1234");
    }

    public static Connection getConnection() throws Exception {
        if (ds == null) {
/*DatabaseConn的目的是让ds有值,和con无关*/           
            new DatabaseConn();
        }
        Connection con = null;
        con = ds.getConnection();
        return con;
    }
}
}


以下是测试程序:

import java.sql.*;
import javax.sql.*;
public class TestMark_to_win {
    public static void main(String args[]) throws Exception {
        Connection con= DatabaseConn.getConnection();
        Statement stmt = con.createStatement();
        ResultSet rs = stmt.executeQuery("select * from login");
        while (rs.next()) {
            System.out.println(rs.getString("id"));
            System.out.println(rs.getString("name"));
        }
        System.out.println("ok");
   
        Connection con1= DatabaseConn.getConnection();
        Statement stmt1 = con1.createStatement();
        ResultSet rs1 = stmt1.executeQuery("select * from login");
        while (rs1.next()) {
            System.out.println(rs1.getString("id"));
            System.out.println(rs1.getString("name"));
        }
        System.out.println("ok");
    }
}



结果是:
11
q
2
qq
3
qqq
ok
11
q
2
qq
3
qqq
ok

后序:

jdbc的事务在后面并发那章讲。



作业:

1)建立一个数据库jdbc,里面有两个表,Login (LoginID,username,password)和Particulars(PersonID,degree,age,address)
   第一步做一Java Application,用参数输入username 和password, 如正确,就继续。如错误就退出。
2)续第一步,如正确,根据参数可修改自己的Particulars.
(提示:for(int i=0;i<args.length;i++) {l.add(args[i]);}

课外作业:

3) transfer the data in the file to a table in the database.(mysql and Singleton)

课外阅读:

本章有太多内容(又没时间讲),所以只能提供可运行的代码,供学有余力的同学参考。 

refer to: H:\java教程\java下教程\jdbc\src

 

1.sql server的helloworld例子:(视频下载) (全部书籍)


import java.sql.*;

public class JdbcHelloSqlServer {
  public static void main(String[] args) {
    String dbUrl= "jdbc:jtds:sqlserver://localhost:1433/Northwind";String user = "sa";String password = "1234";
//    String   dbUrl="jdbc:mysql://localhost:3306/test"; String user = "root";String password = "1234";
    String createString;
    Statement stmt;
    createString = "select * from orders";
    try {
      /*this method attempts to locate, load,
       and link the class or interface. The specified class loader is
       used to load the class or interface. If the parameter loader is
       null, the class is loaded through the bootstrap class loader.
       about soundBlaster driver?when you talk to the microphone, it can
        record into the computer and save as a file. your sound is
       transfered into 01 signal and save as a file. all these are done by driver.
       the same thing,  using DB? you also need driver.
       */
       Class.forName("net.sourceforge.jtds.jdbc.Driver");
//       Class.forName("com.mysql.jdbc.Driver");
      /*      When the method
       getConnection is called, the DriverManager will attempt to
       locate a suitable driver from amongst those loaded at initialization
       */
      Connection con = DriverManager.getConnection(dbUrl, user, password);
      System.out.println("Connection is ok");
      /* Statement object is a workspace to create SQL queries, execute them, and retrieve any results that are returned.
 tube has track,vehicle is on the track for coal.  vehicle is only suitable for  this track , not for any other track.
       */
      stmt = con.createStatement();
// stmt.execute(createString);
      /* Resultset object contains the table produced by the SQL query
       */
      ResultSet rs = stmt.executeQuery(createString);
      System.out.println("qixybefore");
      //获得元数据
      //获得元数据
      ResultSetMetaData meta = rs.getMetaData();
      for (int i = 1; i <= meta.getColumnCount(); i++) {
        if (meta.getColumnType(i) == java.sql.Types.INTEGER) { // if it is CHAR
          System.out.println("Types.INTEGER is " +i +" " + meta.getColumnName(i)); // display the name
        }

        System.out.println(meta.getColumnName(i)); //字段名称
      }
      System.out.println("qixylater");
/*boolean next()  throws SQLException  Moves the cursor down one row from its current position. A ResultSet cursor is initially
 positioned before the first row; the first call to the method next makes the first row the current row; the second call makes
 the second row the current row, and so on.  Returns:true if the new current row is valid; false if there are no more rows */
      while (rs.next()) {
        String name = rs.getString("OrderID");
        System.out.println(name);
      }

      stmt.close();
      con.close();

    }
    catch (Exception e) {
     e.printStackTrace();
    }
  }
}

2.oracle的helloworld例子:(视频下载) (全部书籍)

import java.sql.*;
public class OracleHello{
    public static void main(String args[]) {
        Connection con;
        String createString;
        createString = "select EMPNO from EMP";
        Statement stmt;
        try {
/*see above, import sun.jdbc.odbc.JdbcOdbcDriver;*/
/*see above, import sun.jdbc.odbc.JdbcOdbcDriver;for kkk this kind of url connection string, you must
            use sun.jdbc.odbc.JdbcOdbcDriver. if you wan to use oracle.jdbc.driver.OracleDriver, you must use
            jdbc:oracle:thin:@localhost:1521:qixy */
/*a sound blaster hardware need a driver to function, software draw awave, then when play,
through the driver, hardware can change it to sound you can hear. here your statement can
be sent to the database.

 public static Class forName(String className)
                      throws ClassNotFoundExceptionReturns the Class object associated with the class or interface with the given string name. Invoking this method is equivalent to:
   Class.forName(className, true, currentLoader)
  where currentLoader denotes the defining class loader of the current class.
 For example, the following code fragment returns the runtime Class descriptor for the class named java.lang.Thread:

    Class t = Class.forName("java.lang.Thread")
  A call to forName("X") causes the class named X to be initialized.


 */
            Class.forName("oracle.jdbc.driver.OracleDriver");
            con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:qixy", "scott", "tiger");
            System.out.println("Connection is ok");
            stmt = con.createStatement();
  //          stmt.execute(createString);
            ResultSet rs=stmt.executeQuery(createString);
            while(rs.next())
            {     String no=rs.getString("EMPNO");
                  System.out.println(no);
            }
            stmt.close();
            con.close();        }
        catch (Exception ex) {
            ex.printStackTrace();
        }    }}

3.sql server的stored procedure例子:(视频下载) (全部书籍)

import java.sql.*;

public class StoredProc0 {
public static void main(String[] args) {
String dbUrl = "jdbc:jtds:sqlserver://localhost:1433/qixytest";
String user = "sa";
String password = "";

try {
Class.forName("net.sourceforge.jtds.jdbc.Driver");
Connection con = DriverManager.getConnection(dbUrl, user, password);
System.out.println("Connection is ok");
CallableStatement cs = con.prepareCall("{call all_books}");
ResultSet rs = cs.executeQuery();

while(rs.next()){
System.out.println(rs.getString("BookName") + "\t" +
rs.getString("Authorname") + "\t" +
rs.getInt("numbersold"));
}
rs.close();
cs.close();
con.close();

}
catch (Exception e) {
e.printStackTrace();
}
}
}

第二个例子:
import java.sql.*;
public class StoredProc {
  public static void main(String[] args) {
    String dbUrl = "jdbc:jtds:sqlserver://localhost:1433/qixytest";
    String user = "sa";    String password = "";
    try {
      Class.forName("net.sourceforge.jtds.jdbc.Driver");
      Connection con = DriverManager.getConnection(dbUrl, user, password);
      System.out.println("Connection is ok");
      CallableStatement cs = con.prepareCall("{call getInStockByBookName(?,?)}");
              cs.registerOutParameter(2,Types.INTEGER);
              cs.setString(1,"core java");
/*qixy: note execute,executeQuery and executeUpdate are roughly the same, the only
 difference lies in their return value. Documentation: the "execute" method handles
 these complex statements as well as the simpler form of statements handled by the
 methods  executeQuery and executeUpdate.

 public ResultSet executeQuery() Executes the SQL query in this PreparedStatement
 object and returns the ResultSet object generated by the query.

 public int executeUpdate()  Executes the SQL statement in this PreparedStatement
 object, which must be an SQL INSERT, UPDATE or DELETE statement; or an SQL statement
 that returns nothing, such as a DDL statement.
Returns:  either (1) the row count for INSERT, UPDATE, or DELETE statements or
 (2) 0 for SQL statements that return nothing */
              cs.execute();    System.out.println(cs.getInt(2));
              cs.close();  con.close();
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

 

4. sql server的dataSource的helloworld:(视频下载) (全部书籍)

import java.sql.*;
import javax.sql.*;
import net.sourceforge.jtds.jdbcx.*;

public class SimpleDataSource{
public static void main(String[] args){
try{
JtdsDataSource ds = new JtdsDataSource();
ds.setServerName("localhost");
ds.setDatabaseName("pubs");
ds.setUser("sa");
ds.setPassword("");

Connection con = ds.getConnection();
Statement s = con.createStatement();
ResultSet rs = s.executeQuery("select count(*) from authors");
if(rs.next())
System.out.println("There are " + rs.getInt(1) + " records in authors table.");
}catch(Exception e){

}
}
}

result is:
There are 23 records in authors table.


5.SQLServer DataSource and SingleTon:(视频下载) (全部书籍)


import net.sourceforge.jtds.jdbcx.*;
import java.sql.*;
import javax.sql.*;

public class SqlserverSingletonDataSource {
static private JtdsDataSource ds;
private Connection con;
private SqlserverSingletonDataSource() {

try {
ds = new JtdsDataSource();
ds.setServerName("localhost");
ds.setDatabaseName("pubs");
ds.setUser("sa");
ds.setPassword("");
}
catch (Exception e) {
}
}

public static Connection getConnection() throws Exception {
if (ds == null) {
new SqlserverSingletonDataSource();
}
Connection con =null;
try {
con = ds.getConnection();
} catch (SQLException ex) {
}

return con;
}
}


测试程序:



/*when you use single step to debug the program, you can find that Singleton only
is executed once.*/
import java.sql.*;
import javax.sql.*;

public class testSqlserverSingletonDataSource {

public static void main(String args[]) {
Connection con;

try {
con = SqlserverSingletonDataSource.getConnection();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select * from authors");
while (rs.next()) {
System.out.print(rs.getString("au_id") + " ");
System.out.println(rs.getString("au_lname"));
}

}
catch (Exception e) {
}

System.out.println("the following is the second time ");

try {
con = SqlserverSingletonDataSource.getConnection();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select * from authors");
while (rs.next()) {
System.out.print(rs.getString("au_id") + " ");
System.out.println(rs.getString("au_lname"));
}

}
catch (Exception e) {
}

}

}


result is:
172-32-1176 White
213-46-8915 Green
238-95-7766 Carson
267-41-2394 O'Leary
274-80-9391 Straight
}
}

6.Oracle DataSource and SingleTon: (视频下载) (全部书籍)

import oracle.jdbc.pool.OracleDataSource;
import java.sql.Connection;
import java.sql.*;

public class OracleSingletonDataSource {
  static private OracleDataSource ods;
  private OracleSingletonDataSource() {
    try{
        ods = new OracleDataSource();
        ods.setURL("jdbc:oracle:thin:@localhost:1521:qixy");
        ods.setUser("scott");
        ods.setPassword("tiger");
            }catch(Exception e){
            e.printStackTrace();
            }
  }
  public static Connection getConnection() throws Exception {
    if (ods==null)
       {
           new OracleSingletonDataSource();
          // ods.getConnection();

      }
      Connection con =null;
      try {
          con = ods.getConnection();
      } catch (SQLException ex) {
        ex.printStackTrace();
      }
       return  con;
      }

}

测试程序:

import java.sql.*;
public class testOracleSingletonDataSource {

  public static void main(String args[]) {
    Connection con;
    Statement stm = null;
ResultSet rs = null;
    try {
/* DatabaseConnection's "static private OracleDataSource ods;" is always in the memory once it is created becasue it is static..*/
con = OracleSingletonDataSource.getConnection();
stm = con.createStatement();
rs = stm.executeQuery("select ename from emp");
  while(rs.next())
  {
        String name=rs.getString("ename");
        System.out.println(name);

  }
  rs.close();
  stm.close();
  con.close();
}

    catch (Exception e) {
      e.printStackTrace();
    }

//    System.out.println("the following is the second time ");

  }
}
 

7.jdbc的transaction例子:(视频下载) (全部书籍)

import java.sql.*;

public class MySQlTransaction1 {

  public static void main(String[] args) throws SQLException {
/*in my sql: create table Accounts(
                ID int(4) not null,
                NAME varchar(15),
                BALANCE int(4),
                primary key(ID)
            )  type=INNODB;
  insert into Accounts values(1,'wangwu',100);
  insert into Accounts values(3,'zhangsan',300);
  insert into Accounts values(4,'lisi',400);
     */
    Connection con = null;
    Statement s = null;
    try {
      Class.forName("com.mysql.jdbc.Driver");
      con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root", "1234");
      //s = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
/*by default, whenever execute a sql, it will commit automatically,
public void setAutoCommit(boolean autoCommit) throws SQLException
Sets this connection's auto-commit mode to the given state. If a connection is in auto-commit
mode, then all its SQL statements will be executed and committed as individual transactions.
Otherwise, its SQL statements are grouped into transactions that are terminated by a call to
 either the method commit or the method rollback. By default, new connections are in
  auto-commit mode.        */

      s = con.createStatement();

      s.executeUpdate("update ACCOUNTS set BALANCE=508 where ID=3");
      System.out.println("333333");
/*下一步中本来应为where ID=4, 但是却误写成了www ID=4, 所以有错,所以到catch中,但rollback时
 , 却做不成功, 因为是autocommited模式,所以上一句ID=3,就做真改成508了。*/     
      s.executeUpdate("update ACCOUNTS set BALANCE=608 www ID=4");
      System.out.println("444444");

      System.out.println("con = " + con);
     }
    catch (Exception e) {
      try{
        con.rollback();
        System.out.println("rollback successfully");
      }catch (Exception ex)
      {
        ex.printStackTrace();
      }
    }
    finally {
      s.close();
      con.close();
      System.out.println("successfully in finally");
    }
  }

}

第二个例子:

/*refer to MySQlTransaction1.java first.*/
import java.sql.*;

public class MySQlTransaction {

  public static void main(String[] args) throws SQLException {

    Connection con = null;
    Statement s = null;
    try {
      Class.forName("com.mysql.jdbc.Driver");
      con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root", "1234");
      //s = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);


      s = con.createStatement();

      s.executeUpdate("update ACCOUNTS set BALANCE=511 where ID=3");
      System.out.println("333333");
/*by default, whenever execute a sq, it will commit automatically,
public void setAutoCommit(boolean autoCommit) throws SQLException
Sets this connection's auto-commit
mode to the given state. If a connection is in auto-commit mode, then all its SQL statements will be
executed and committed as individual transactions. Otherwise, its SQL statements are grouped into
transactions that are terminated by a call to either the method commit or the method rollback. By
 default, new connections are in auto-commit mode.
qixy: the following setAutoCommit actually set the starting boundry
 */
      con.setAutoCommit(false);
      s.executeUpdate("update ACCOUNTS set BALANCE=903 where ID=1");
      System.out.println("11111111");
/*when experiment, we change where ID=4 to www ID=4, then see the result. two lose together*/
      s.executeUpdate("update ACCOUNTS set BALANCE=1105 www ID=4");
      System.out.println("222222222");
      con.commit();
      System.out.println("con = " + con);
     }
    catch (Exception e) {
      try{
        con.rollback();
        System.out.println("rollback successfully");
      }catch (Exception ex)
      {
        ex.printStackTrace();
      }
    }
    finally {
      s.close();
      con.close();
      System.out.println("successfully in finally");
    }
  }
}

8.JNDI用来查找dataSource的例子:(视频下载) (全部书籍)

import javax.naming.InitialContext;
import javax.naming.Context;

import com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource;

import java.util.Properties;
import net.sourceforge.jtds.jdbcx.*;
public class ClassPut {
        public static void main(String a[]) {
                try {
/*                  JtdsDataSource dataSource=new  JtdsDataSource();
                        dataSource.setServerName("localhost");
                        dataSource.setDatabaseName("NorthWind");
                        dataSource.setUser("sa");
                        dataSource.setPassword("1234");
*/
                    MysqlConnectionPoolDataSource ds = new MysqlConnectionPoolDataSource();
                    ds.setURL("jdbc:mysql://localhost:3306/test");
                    ds.setUser("root");
                    ds.setPassword("1234");                     
                       
                       
                        Properties prop = new Properties();
                        prop.setProperty(Context.INITIAL_CONTEXT_FACTORY,
                                        "com.sun.jndi.fscontext.RefFSContextFactory");

                        Context ctx=new InitialContext(prop);
/*here the following statement writes a file .bindings under the f Disk. because this project is under the f disk.*/
                        ctx.rebind("abc",ds);


                } catch (Exception e) {
                        e.printStackTrace();
                }
        }
}
上面的程序只是存入硬盘,想查找出来得用下面的程序:

import javax.naming.InitialContext;
import javax.naming.Context;

import com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
import net.sourceforge.jtds.jdbcx.*;
public class ClassGet {
        public static void main(String a[]) {

                try {
                        Properties prop = new Properties();
                        prop.setProperty(Context.INITIAL_CONTEXT_FACTORY,
                                        "com.sun.jndi.fscontext.RefFSContextFactory");
                        Context ctx=new InitialContext(prop);
/*it will lookup things under the f disk---.bindings file, lookup will directly instantiate
 an object of net.sourceforge.jtds.jdbcx.JtdsDataSource in memory.                         */
                        Object obj=ctx.lookup("abc");
                        System.out.println(obj);
                        MysqlConnectionPoolDataSource ds = (MysqlConnectionPoolDataSource)obj;
                        Connection con = ds.getConnection();
                        Statement s = con.createStatement();
                        ResultSet rs = s.executeQuery("select count(*) from books");
                        if(rs.next())
                                System.out.println("There are " + rs.getInt(1)
                                                   + " records in books table.");
                        con.close();
                } catch (Exception e) {
                        e.printStackTrace();
                }
        }

}

9.sqlserver2008's problem:

1)java连接sql server 2008遇到的问题之一:
使用 sql server 2008 时,无法使用SA用户登陆(应该是所有sql server版本都会出现这样的问题)
解决方法:
1、打Microsoft Sql Server Management Studio,以windows验证方式登陆,打开服务器属性窗口(在数据库服务器图标上点右键选"属性"(right click the server name,choose property)),选择"安全性"选项,
2、服务器验证方式选择SQL SERVERTT和windows验证方式,确认
3、然后再到"安全性-登陆名"处设置SA用户属性,
4、设置密码
5、状态-启用SA用户
做完这五个操作后,we can now login as "sa" in Sql Server Management Studio.



2) sqlserver2008默认情况下是禁用了tcp/ip连接。启动tcp/ip连接的方法,

开始 \Microsoft SQL Server 2008\配置工具\目录下的SQL Server Configuration Manager,选择\sqlserver network configuration\mssqlserver协议,

然后右边窗口有个tcp/ip协议,然后启动它,在启动TCP/IP协议后还要把其属性

中的TCP端口号改为1433,,把sqlserver