11月30日——培训第9天

来源:互联网 发布:全国地址查询软件 编辑:程序博客网 时间:2024/04/27 19:27

新的一周开始了,今天是11月的最后一天了,新的课程也开始了,是
有关JDBC的……

搞不好一会儿位图索引还得我来说呢……
------------------------------

课程开始:

看来老师忘了位图索引的事情,哈哈!直接讲JDBC了。

数据库服务器(EIS层)、J2EE服务器(Web层、业务层),客户端机器(客户层)三层结构,EIS层主要用于从数据库中提取数据。

EIS:Enterprise Information System。

JDBC和ODBC:Open Database Connection(开放数据库连接,建立在C语言基础上)
            但是不具备跨平台功能,只在本地系统起作用。JDBC和ODBC都是
            建立在SQL/CLI规范之上的。不同的数据库提供给程序使用的接口
            都不一样,为了跨平台,定义了一套统一的接口标准。

CLI:Core Level Interface 

驱动程序特点:向上提供统一的接口,向下则连接不同的数据库。
              针对不同的数据库提供不同的驱动,但是向上统一定义一个
              相同的接口。

汗啊……老师又把位图索引的事情想起来了,下节课还得讲,烦啊……

老师随便出了一道接口题目,下面的代码哪里错了??
public interface Job
{
 public abstract String jobTitle();
}

public class JobImpl implements Job
{
 String jobTitle()
 {
   return "Teacher";
 }
}

注意:接口中的方法默认就是公共的且抽象的,所以public abstract
可以不写,但是呢,JobImpl中的jobTitle()方法必须也得是公共的才可以,
因为被继承的方法的访问权限只能够增大,不能够缩小。

也就是如果父类中的方法是保护级别的,那么继承了它的子类的同名方法必须
保证访问级别在protect以上!!!

就JDBC来说,我们定义的接口都是统一的Job,但是实现的具体驱动程序
是不同的,驱动程序的作用就是连接具体数据库!!!驱动程序就是一个个
不同的类。

驱动程序管理器:管理多个驱动程序,向程序提供不同的驱动程序返回的
                具体连接。

在oracle中的ora92中的jdbc中的lib中有oracle驱动程序,其中ojdbc14.jar
是oracle提供的最新的驱动程序,在jdbc中还有一个文档,里面的
oracle.jdbc.driver中的OracleDriver和oracle.jdbc.OracleDriver,后者是前者
的子类,所以尽量使用oracle.jdbc.OracleDriver!!

新建一个记事本程序
import java.sql.* ;
C语言中的include是直接把那些头文件粘贴过来,java中的import和C中的
include作用不一样,*的作用类似于命名空间,也就是java.sql下面的所有类
都可以可见,也就是可用,但是并不是直接引进来。

说用java.sql.*不好并不是处于运行性能的考虑,主要是处于可读性的考虑,
方便读代码的人最终定位到具体的引用类。

import java.sql.*;
import oracle.jdbc.OracleDriver;
public class Demo
{
 public static void main(String[] args)
 {
  Driver driver = new OracleDriver();
 }
};

如果直接运行的话,是找不到oracle那个类的
这么写:

javac -classpath E:/oracle/ora92/jdbc/lib/ojdbc14.jar Demo.java
就可以编译了,如果不写classpath的话,jdk只能找到自己目录中的lib和
classpath环境变量下面的类……

如果不想写的麻烦的话,就把上述的路径配置到环境变量中,
注意:如果路径中有空格的话,一定要把上面那个路径目录用双引号括起来!

----------------
使用eclipse较为方便:

快捷键ctrl+shift+O用来快速引进包。

package aw;
import java.io.*;
import java.util.*;
import java.sql.Driver;
import oracle.jdbc.OracleDriver;


public class Aaa {
 public static void main(String[] args)
 {      
  String driver="jdbc:oracle:thin:@localhost:1521:orcl";
                Properties prop = new Properties();
                prop.put("user","hr"); //user是oracle需要的键
   prop.put("password","hr");//password也是oracle需要的键
//注意:put的第一个参数要在oracle的jdbc帮助文档里面查!!
  Driver driver = new Oracledriver();
  Connection conn = driver.connect();
  try
  {
   if(driver.acceptsURL(driver))
   {
   System.out.println("accept");
   Connection conn = driver.connect(driver,prop);
   DriverPropertyInfo[] pi =
     driver.getPropertyInfo(driver,prop);
   //上面这句话很重要!!!
   for(int i=0;i<pi.length;i++)
   {
    System.out.println(pi[i].name+":"+pi[i].value);
   //注意:上面这个循环里面是读不出东西的
                        //因为oracle不支持,但是mysql支持
                        //驱动程序接受哪些属性??
   }
   conn.close(); 关闭连接
   }
  }
  catch(SQLException e)
  {
   e.printStackTrace();
  }
 }
}

DriverPropertyInfo

connect中要有两个参数,一个是jdbc的url,一个是info参数,
url:jdbc:oracle:<drivertype>:@<database>

也就是jdbc:oracle:thin:hr/hr@localhost:1521:orcl
这是connect中的第一个参数,

oracle的drivertype总共有两类,一类是thin,另一类是oci

thin  纯java驱动程序
oci   本地接口驱动程序 oracle call interface

Properties是 Hashtable的一种类型,键值对方式存储。
所以也有put的方法。


mysql的url:jdbc:mysql://localhost:3306/test?characterEncoding=gbk

注意:
删除mysql,先卸载,再删除注册表中的相关键值,再删除本地目录,然后重启

当然也可以prop.put("characterEncoding","gbk");
这样的话就不用在url后面加上?characterEncoding=gbk了。

-------------------------
课间休息:


-------------------------
休息结束,开始邢啸屹的位图索引讲解:

这个玩意儿离我太远我不想深究了,所以这里就不记了,反正网上
资料多的是,到时候再说把。

编码:8位的编码对应256个字符,汉字的话6万多个,包括简体和繁体,
必须要16位(65536个编码),英文是8位,中文16位,所以会有乱码问题。

老师让我们装了一下mysql,并尝试使用,决定中午好好整一整……

net start mysql
net stop mysql

mysql -uroot -p
然后输入密码即可

 

 


------------------------
田老师上午课上的源代码:!!!!
这是应用程序和驱动程序之间取数据库连接!
teacher tian 
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.util.Properties;

public class Demo {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  Properties prop = new Properties();
  prop.put("user", "hr");
  prop.put("password", "hr");
  //prop.put("characterEncoding", "UTF");
  //prop.put("internal_logon", "sysdba");
  /*System.out.println(prop.getProperty("password"));
  System.out.println(prop.put("user", "hr"));
  
  Driver driver = new OracleDriver();
  String url = "jdbc:oracle:thin:@localhost:1521:orcl";*/
  
  String url = "jdbc:mysql://localhost:3306/test";
  try {
   Driver driver = new com.mysql.jdbc.Driver();
   if(driver.acceptsURL(url)) {
    System.out.println("accept");
    //Connection conn = driver.connect(url, prop);
    DriverPropertyInfo[] pi = driver.getPropertyInfo(url, prop);
    for(int i=0; i<pi.length; i++) {
     System.out.println(pi[i].name + " : " + pi[i].value);
    }
    //conn.close();
   }
   
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

}
 
--------------------------------------------------------------------
中午和同寝室的同学去北大西门照相,刚回来……就上课了……呜……
---------------------------------------
show databases;(显示所有的数据库)
use test;   (使用test数据表)
show tables;(显示所有的数据表)
desc emp(emp是具体的表)


mysql中的schema对应的就是数据库,而oracle中对应的则是用户。

使用MySQL Query Browser 来进入mysql图形化界面

好困啊,中午果然不能到处瞎逛的
-----------------------------------------
jdbc中的驱动程序管理器:DriverManager
里面所有的方法都是静态的!!

注意:不能在import中同时import oracle和mysql的driver!!!
看看下面源代码总是如何处理mysql的driver的!
使用DriverManager:
这是驱动程序管理器和应用程序之间的
这是第二种获取数据库连接的写法:


import java.sql.Driver;
import oracle.jdbc.OracleDriver;

public class DemoDriverManager
{
 public static void main(String[] args)
 {
  String url = "jdbc:oracle:thin:hr/hr@localhost:1521:orcl";
  String url2 = "jdbc:oracle:thin:@localhost:1521:orcl";
  String mysqlUrl="jdbc:mysql://localhost:3306/j2ee?user=root&
                      password=root";
  try
  {
  Driver orclDriver=new OracleDriver();
  Driver mysqlDriver=new com.mysql.jdbc.Driver();//很重要!
  DriverManager.registerDriver(orclDriver);
  DriverManager.registerDriver(mysqlDriver);
  
  Connection orclConn = DriverManager.getConnection(url);
  Connection mysqlConn =  DriverManager.getConnection(mysqlUrl);

  orclConn.close();
  mysqlConn.close();
  }
  catch(Exception ex)
  {}
 }

}

Connection分Set和List两类
Set不允许重复,List是有序的!
------------------------------------
下面这段源代码是DriverManager中的getConnection的具体方法的实现!!

Set drivers;
Iteration it = drivers.iterator();
Driver target = null;
while(it.hasNext()) //迭代
{
 target = (Driver)it.next();
 if(target.acceptsURL(url))
 {
  break;
  return target.connect(url,prop); 
  //这个prop是程序自己弄出来的空属性变量。
 } 
}
return null;

//也就是说找到了合适的连接的话就返回那个连接,否则返回null值就行,
//用driver的acceptsURL方法来判断哪个驱动可以接收这个url
---------------------------------
//也可以用下面的方法来返回,在else中将target置为空
return target==null?null:target.connect(url,prop);

如下所示:

Set drivers;

Iteration it = drivers.iterator();
Driver target = null;
while(it.hasNext()) {
  target = (Driver)it.next();
  if(target.acceptsURL(url)) break;
  else target=null;
}

return target==null?null:target.connect(url, prop);
----------------------------------
获取数据库连接的第三种写法:

public class DemoClass
{
 public static void main(String[] args)
 {
  String url = "jdbc:oracle:thin:hr/hr@localhost:1521:orcl";
  String url2 = "jdbc:oracle:thin:@localhost:1521:orcl";
  String mysqlUrl="jdbc:mysql://localhost:3306/j2ee?user=root&
                      password=root";

  try
  {
  Class.forName("com.mysql.jdbc.Driver");
  Class.forName("oracle.jdbc.OracleDriver");

  Connection conn = DriverManager.getConnection(url);
  Connection conn2 = DriverManager.getConnection(mysqlUrl);

  conn2.close();
  conn.close();
  }
  catch(Exception ex)
  {
  
  }
 }
}

Class.forName的作用:
Class是个public final的类,不可以被继承,因为有了final关键字!
forName方法传入的是一个完整的类名(包括包名),这个方法返回的对象可以关联到这个传入的类。

类都是先从外存加载到内存,然后创建实例。
forName返回的是Class这个类的一个实例,但是这里没有driver的实例,没有driver实例的话,
不可能使用DriverManager来register这个driver

Class.forName是把类加载进来,生成一个Class的实例,然后调用newInstance()来生成关于
驱动的实例。

其实也可以这么写:Class.forName(url).newInstance()。

在类加载时被调用的是静态方法和静态代码块,其实所谓的DriverManager的register
是在类的静态块中写的……保证每次使用这个方法的时候都会注册这个类!

静态代码块:
static
{

}

老师模拟写的一个Driver类,使用alt+shift+s,可以用里面的override来生成driver中的
注意:ctrl+shift+o , 可以自动包括进入包……
而且ctrl+shift+? , 可以把选中的代码变成注释
ctrl + ? , 可以把选中的代码变成单行注释
使用上述两个快捷键时,要把类名选中!!

所有方法。
import java.sql.Driver;
import java.sql.Connection;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.util.Properties;

public class MyDriver implements Driver
{
 static
 { 
  try{
  DriverManager.registerDriver(new MyDriver());
  }
  catch(Exception ex)
  {}
 }
 public boolean acceptsURL(String url) throws SQLException
 {
 //这段话用来判断url是否满足驱动,因为getConnection方法需要调用这个方法!!
  boolean result = false;
  if(url!=null&&url.startsWith("jdbc:mydriver:"))
  {result = true;}
  return result ;
 }
 public int getMajorVersion()
 {
  return 1;
 }
 
 public Connection connect(String url,Properties info) throws SQLException
 {
  return new MyConnection(); //调用下面的MyConnection类的实例
 }
 MyConnection是Connection接口的一个实例。
 
}
----------------------------------------------

public class MyConnection implements Connection
{
 public void close() throws SQLException ex
 {
  System.out.println("this sis my connection");
 }
 ………………其他的方法略
}


这样就可以用Class.forName("MyDriver");来调用了。
然后加上
Connection conn = DriverManager.getConnection("jdbc:mydriver:");
conn.close();

这样就可以得到 this is myconnection了。

1 registerDriver伪代码:创建一个driver实例,并且将之放入一个Set中(Set里面的元素
不可以重复,保证了driver的唯一性)
Set drivers = new HashSet();
drivers.add(driver);

//上面这段话其实在加载了driver的类后就执行了上面的静态块,静态块里面有registerDriver注册。
//其实Class.forName(driver)的目的就是把driver这个类给放到drivers集合中
//以便后面的getConnection来使用!
2 getConnection 伪代码:
Iteration it = drivers.iterator();
Driver targer = null;
while(it.hasNext())
{
 target=(Driver)it.next();
 if(target.acceptsURL(url)) break;
 else target=null;
}
return target==null?null:target.connect(url,prop);

流程:
1 创建一个驱动程序的实例:
2 向DriverManager注册驱动程序,即调用它的registerDriver方法
3 当客户调用getConnection方法获取连接时,DriverManager遍历所有的已经注册的
  驱动程序,并调用驱动程序的acceptsURL,询问驱动程序是否识别这个url,直到找到
  能够识别url的驱动程序。
4 调用能够识别URL的驱动程序的connect方法,返回Connection。
//注意getConnection方法返回的是一个driver的连接!!getConnection方法中调用了
  driver的connect方法
--------------------------------------

驱动程序类型:
共有4类:

一 JDBC-ODBC的桥驱动模式:
   由JDBC连接ODBC来达到间接连接的效果,实际开发中是不可以用的,效率太低了……
   而且由于调用了本地接口,所以跨平台无从谈起……每一次到新的平台中都要重新配置数据源。
   驱动程序:sun.jdbc.odbc.JdbcOdbcDriver
   url是jdbc:odbc:<odbc数据源的名称>

比如数据源的名称是orcl的话,那么
  Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
  Connection conn = DriverManager.getConnection("jdbc:odbc:orcl","hr","hr");
  conn.close();

二 本地接口与java驱动程序相结合的驱动模式
  oracle中的oci就属于这一类驱动程序

三 面向数据库中间件的驱动模式
  驱动程序和oracle的本地加一个中间层,这个中间层调用本地接口,oracle调用这个中间层,
  这样驱动程序不用改变,但是由于多了一层所以效率也比较低。

四 直接连接的驱动模式
  由于java程序越来越普及,所以数据库调用的接口直接提供了面对java的接口,这样驱动程序
  不用调用本地接口了,直接就是java程序。
  oracle的thin驱动程序就属于第四类。

 实际开发中较常用的是第四类和第二类驱动模式……

 oracle的内核一定是汇编语言+C语言

 ----------------------------------
 今天课程结束,作业是模仿老师今天的代码自己重写驱动连接……
 ----------------------------------------------------------
 ----------------------------------
 现在晚上了

 把刚才的东西大概整理了一下,今天讲了三种得到驱动的方式,第三种就是最常用的Class.forName()
 方法,就不再这里浪费地方了,主要说说前两种吧:

首先第一部要在工程文件中引入驱动程序,也就是jar包,oracle和mysql都应该引入才行。
然后,可以在程序的最开始使用import的方式将对应驱动程序的完整类名引入。
mysql是com.mysql.jdbc.Driver;(注意这个类如果和java.sql.Driver同时引入的话
                              会有冲突!!!)
oracle是oracle.jdbc.driver.OracleDriver;
数据库连接必要要有URL字符串!
oracle和mysql的对应的字符串如下:

mysql的:"jdbc:mysql://localhost:3306/test?user=root&password=root" (test是数据库)
oracle的:"jdbc:oracle:thin:hr/hero@localhost:1521:orcl" (orcl是SID名)

注意以上两种连接url都是包含了用户名和密码的,当然也可以不包含用户名和密码!
"jdbc:mysql://localhost:3306/test"
"jdbc:oracle:thin:@localhost:1521:orcl"
尤其注意oracle中的那个thin后面一定不可以丢掉冒号!!
---------------------------------------
 第一种:创建mysql和oracle的对应Driver实例,以及Properties属性,然后使用创建
        出来的实例的connect方法,connect方法里面有两个参数,第一个就是url,
 第二个就是属性文件,如果第一个url中已经有了用户名和密码的信息,那么就不用
 在属性文件中添加了,否则必须按照如下的形式添加属性文件才可以!
 props.put("user","连接数据库的用户名");
 props.put("password","连接数据库密码");

代码如下:
 
oracle的:
-------------------------------------
import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;
import java.util.Properties;

import oracle.jdbc.OracleDriver;

public class DriverTest1 {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  Driver OracleDriver = new OracleDriver();
  Properties props = new Properties();
  //props.put("user","scott");
  //props.put("password","tiger");
  String url="jdbc:oracle:thin:hr/hero@localhost:1521:orcl";
  try {
   Connection conn = OracleDriver.connect(url,props);
   System.out.println("success!");
   conn.close();
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
---------------------------------------
mysql的:

import java.sql.Connection;
import java.sql.*;
import java.sql.SQLException;
import java.util.Properties;
//import com.mysql.jdbc.Driver;

public class DriverTest2 {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  String url="jdbc:mysql://localhost:3306/test?user=root&password=root";
  Properties props = new Properties();
  //props.put("user","root");
  //props.put("password","root");
  //Driver mysqlDriver = new com.mysql.jdbc.Driver();
  try {
   
   Driver driver = new com.mysql.jdbc.Driver();
   System.out.println(driver.acceptsURL(url));
   Connection conn = driver.connect(url,props);
   System.out.println("hfdashfasj");
   conn.close();
   //Connection conn = mysqlDriver.connect(url,props);
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
  
 }

}
-------------------------------------
第二种:
创建driver实例,但是不直接调用connect方法,而是利用DriverManager的
registerDriver方法注册驱动,然后再用DriverManager的getConnection方法
得到连接,不需要属性文件了。这其实是用了驱动程序的管理器……

oracle的:
import java.util.*;
import java.io.*;
import java.sql.*;

import oracle.jdbc.driver.OracleDriver;

public class DriverTest4 {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  Driver driver = new OracleDriver();
  String url = "jdbc:oracle:thin:@localhost:1521:orcl";
  try
  {
   DriverManager.registerDriver(driver);
   Connection conn = DriverManager.getConnection(url,"hr","hero");
   System.out.println("haha");
  }
  catch(Exception ex)
  {
   ex.printStackTrace();
  }
 }

}
--------------------------------------
mysql的:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import com.mysql.jdbc.Driver;

public class DriverTest3 {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  String reg="com.mysql.jdbc.Driver";
  String url="jdbc:mysql://localhost:3306/test?user=root&password=root";
  try {
   Driver driver = new Driver();
   DriverManager.registerDriver(driver);
   Connection conn = DriverManager.getConnection(url);
   System.out.println("success!!");
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

}
---------------------------------
第三种Class.forName()由于太常用了,就不写了。


 

原创粉丝点击