⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 day02.txt

📁 JDBC描述详解JDBC描述详解JDBC描述详解JDBC描述详解
💻 TXT
字号:
JDBC_day02   langna  2007-9-7    星期五
wanghg@tarena.com.cn
回顾:   
    con = DriverManager.getConnection("jdbc:oracle:thin:@192.168.0.201:1521:tarena", 
    		                                                                    "xjh0704", "xjh0704");
    另外一种注册方法:
        Properties p = new Properties();
        p.setProperty("user", "xjhsd0704");
        p.setProperty("password", "xjhsd0704");
        Connection con = d.connect("jdbc:oracle:thin:@192.168.0.20:1521:tarena", p);
    另外一种方式:    
    jdbc:oracle:thin:xjh0704/xjh0704@192.168.0.20:1521:tarena
    
    java类型是静态类型,编译器检查类型;字符串只检查类型,不检查内容;
   
    注意:  
    
     同一个statement 得到结果集之后没有去遍历结果集,
                而是做了其他操作(插入或修改)的话,结果集就不能用了,为空了;
     先做插入或修改操作,然后再得到结果集去遍历,不会有什么问题;   
     
 一、设计
    封装:避免重复的代码;
    抽象:将具体的细节、量抽出来,把逻辑,形式留下;
    依赖倒转:原来的设计是写具体的类,依赖倒转就是将具体的抽取出来;
    
    写一个工具类:JdbcUtil ,方法都设成静态方法;
    加载驱动放到初始化代码块里;只加载一次就行;
    
public class JdbcUtil {
   //静态代码块加载驱动;
   static{
        try {
		Class.forName("oracle.jdbc.driver.OracleDriver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
    }
     //得到数据库连接
    public static Connection getConnection(){
        Connection con =null;
        try {
		con = DriverManager.getConnection("jdbc:oracle:thin:@192.168.0.201:1521:tarena",
			                                         "xjh0704", "xjh0704");
		} catch (SQLException e) {
			e.printStackTrace();
		}
        return  con;
    }
    	   
   //释放数据库资源
    public static void close(ResultSet rs,Statement stmt,Connection con){
	   if(rs!=null){
	     try{
		   rs.close();
		 }catch(SQLException e){
		   e.printStackTrace();
		 }
	   }
	   if(stmt!=null){
	     try{
		   stmt.close();
		 }catch(SQLException e){
		   e.printStackTrace();
		 }
	   }
	   if(con!=null){
	     try{
		   con.close();
		 }catch(SQLException e){
		   e.printStackTrace();
		 }
	   }
    }
    //重载一个关闭方法
    public static void close(Object o){
	   try{
	     if(o instanceof ResultSet){
	      ((ResultSet)o).close();
	     }else if(o instanceof Statement){
	      ((Statement)o).close();
	     }else if(o instanceof Connection){
	      ((Connection)o).close();
	     }
	   }catch(SQLException e){
	     e.printStackTrace();
	   }
    } 
}   

二、PreparedStatement概述;预编译的
1、概括:与Statement比较
    
    效率高;
    清晰(类型);
    结构:1、SQL参数化(Statement中SQL是纯字符串的)
              2、SQL预编译
              
    Statement  将 SQL 送到数据库 ---> 编译---> 运行---> 再返回给应用程序 
    有1000条记录的话就送1000次;编译1000次,运行1000次;
    相当于sqlplus ,一条命令执行一次;
    
    Preparement "insert into t_test values(?,?)" //占位符;
                    ---> 发到数据库可以编译但不能运行---> 等参数传过来再运行;
    有1000条记录,编译一次,运行1000次;
   ************************************
    Statement  stmt=null;
    stmt = con.createStatement();
    sql="insert into t_test values(1,'tony')"
    //直接送sql语句;象一个表达式
    stmt.executeUpdate(sql);
    ***********************************
    PreraredStatement  ps=null;//象方法一样
    sql="insert into t_test  values(?,?)");
    
    //1、准备一条sql语句
    ps=con.prepareStatement(sql);
    //2、往ps对象设置参数值;检查类型是否兼容;
    ps.setInt(1,8);
    ps.setString(2,"Tony");
    //3、送到数据库执行
    ps.executeUpdate();
	
2、SQL:同构;sql语句除了参数不同其他都一样;
               异构:除了参数不同,其他地方有不同的就是异构的;
                        比如 insert 和 update;或者表不同也是异构的;
    不管同构的还是异构的都用 PreparedStatement  
    同构的更能发挥它的优势;
    select 一般是异构的,但是执行一次返回一个结果集就行了;
    update/insert 一般都是同构的,用PreparedStatement;
    
    对客户端来说并没有减少工作量,但是对数据库来说减少了工作量;
    
 三、元数据:
1、 ResultSetMetaData
	元数据是用来描述数据的数据,ResultSetMetaData就是来描述结果集的
	列的类型和属性信息,比如可以通过它得到结果集的列数,列名等。
	具体可在API中查阅java.sql.ResultSetMetaData。
	ResultSetMetaData对象可以通过ResultSet对象的getMetaData()来得到。
	
	ResultSetMetaData对象有以下三个方法比较常用:
	getColumnCount():获得实际列数
	getColumnName(int colnum):获得指定列的列名
	getColumnType(int colnum):获得指定列的数据类型(Types里面的类型,存放的是整数)
        getColumnTypeName(); 数据库的类型
        JDBC API :JDBC --- JAVA --- 数据库类型
        类型对照表:String 范围
       //1、获取结果集元数据
       ResultSetMetaData  md=rs.getMetaData();
       //2、从结果集元数据中读取字段个数
         int column=md.getColumnCount();
				
       //3、利用元数据读取字段名和字段值
       for(int i=1;i<=column;i++) {
		System.out.println(md.getColumnName(i)+"\t");
	}
	
2、数据库元数据:
        DatabaseMetaData
        getURL(),获得连接数据库的URL
        getDatabaseProductName() 获得数据库产品的名称
        getDriverVersion() 获得JDBC驱动程序的String形式的版本号
        getUserName() 获得数据库用户名。
        
        ResultSet   getTables(参数)获得数据库中该用户的所有表
        参数:
            catalog : null ,
            schema : 用户名;如"OPENLAB"
            table_name:表名,可以用通配符"%TEST"
            types: 类型;是String[] 格式的;候选类型是:"TABLE"、"VIEW"、"SYSTEM TABLE"
            
       //1获取数据库元数据
	DatabaseMetaData  dbmd=con.getMetaData();
	//2读取特定表信息;获得结果集
	String[] types=new String[1];
	types[0]="TABLE";//必须是大写
	rs=dbmd.getTables(null, "OPENLAB","%", types);
        //3遍历结果集,输出
四、事务Transaction
1、原子操作:不可分割的操作;
    atom: 原子操作,代表不可再分操作;
2、事务:
    事务就是将一组数据库操作变为原子操作;事务是达成原子操作的一个途径;
    事务是针对原子操作的,要求原子操作不可再分,要求原子操作必须同时成功同时失败。
    事务是捆绑的原子操作的边界。
    
    事务由数据库服务器来实现的,我们只是使用它;
    我们写的代码,数据库都将其设为自动提交;插入10条记录就commit 10次;
    
    使用事务的语法:
     1) 关闭自动提交(开始一个用户的事务);
     con.setAutoCommite(false); 打开事务就要关闭自动提交。
     如果不关掉,则是数据库的事务,将每次提交作为一个事务;
     不用事务时要把setAutoCommite(true);
     2)正常的进行若干"相关"的数据库操作;
     3)如果一切正常,用户可以选择提交 con.commit();
        也可以选择回滚 con.rollback();
     4)任何一个操作失败,就回滚;在catch语句块中con.rollback();
        在提交和回滚时旧的事务结束,新的事务开始;
    
    
声明一下:
    从我最近对大家的观察,发现有相当一部分同学上课并没有好好去记笔记;
    这样对记忆还有学习的影响很不好,所以以后我不再给大家发笔记了,
    希望大家自己上课好好听课,好好记笔记。
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -