JDBC课程笔记

JDBC_day01_am

1.










2.解耦合
                   3.驱动分类
  a.JDBC-ODBC桥驱动
    application-->jdbc-->桥-->odbc-->数据库
    1.效率低;
    2.安全性低;
  b.部分Java、部分本地代码驱动;
    application-->jdbc-->java|native(调用操作系统功能的代码)---->数据库
   
 

    速度相对较快,但安全性不好;

   c.纯Java网络服务器驱动(pure java,net Server Driver)
  app-->JDBC--pure Java--中间协议-->netServer--本地协议-->数据库
  效率底;
   d.纯Java本地协议驱动(pure java,native protocol)
   app-->jdbc-->pure Java—本地协议-->数据库
 
   虽然工作量大,但是效率高,更安全;
4.JDBC协议
  java.sql.*;(主要\核心特性包)
  javax.sql.*;(宽展功能包)
5.java.sql.*中的接口和类
Driver   代表驱动程序
DriverManager  辅助工具类-管理驱动程序
Connection    代表DB连接(某种意义上代表DB)
Statement
PreparedStatement     代表DB操作对象(SQL)
CallableStatement
 
ResultSet  代表查询结果
DatabaseMetadata
ResultSetMetadata   元数据对象
Types   定义用于标识一般 SQL 类型(称为 JDBC 类型)的常量的类。


 
 

JDBC_day01_pm
1.JDBC操作步骤
  a.注册/加载驱动 首先导包:classpath环境变量中配置或eclipse中构建工程path
  b.建立连接;写URL(包括:网络协议;主机地址(ip:port);资源名称)
  c.创建执行对象
  d.执行SQL语句
  e.处理结果集
  f.关闭资源

数据库中URL的格式:
    jdbc:mysql://127.0.0.1:3306/test
    
   

     其他的数据库与上面的格式类似
    而oracle的url比较特殊:
          jdbc:oracle:thin:@172.18.9.6:1521:tarena


2.OracleDriver内部实现机制,使用静态块加载Driver给DriverManager

package tang.jdbc;

import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
public class OracleDriver {

    static {
    Driver driver=new oracle.jdbc.driver.OracleDriver();
       try {
DriverManager.registerDriver(driver);
} catch (SQLException e) {
e.printStackTrace();
}
   
    }
}

3.数据库连接实例
package tang.jdbc;

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

public class Lab1 {

/**
* @param args
*/
public static void main(String[] args) {

String driver="oracle.jdbc.driver.OracleDriver";
String url="jdbc:oracle:thin:@172.18.9.6:1521:tarena";
String user="scott";
String password="tiger";
try {
Class.forName(driver);
Connection conn=DriverManager.getConnection(url,user,password);
Statement stmt=conn.createStatement();
ResultSet rs=stmt.executeQuery("select * from userinfo");
while(rs.next()){
System.out.println(rs.getString(1)+"\t"+rs.getString(2));

}
System.out.println("successfully!");
if(null!=rs){
rs.close();
}
if(null!=stmt){
stmt.close();
}
if(null!=conn){
conn.close();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}catch(SQLException e){
e.printStackTrace();
}
}
}
结果:
tang 123456
zhi 123456
qiang 123456
tangzhiqiang tangzhiqiang
yangyi 123456
successfully!
一个可以执行创建数据库的实例(注意执行时的输入信息)
package tang.jdbc;
import java.sql.*;
public class CreateTable {
public static void main(String[] args) {
String url = "jdbc:oracle:thin:@172.18.9.6:1521:tarena";
String user = "scott";
String pwd = "tiger";
Driver driver = new oracle.jdbc.driver.OracleDriver();
Connection conn = null;
Statement stmt = null;
  String sql=null;
if (null == args[0]) {
System.out
.println("执行格式为:java CreateTable 表名   执行命令(如,create\\drop)");
  return;
}
if (null == args[1]) {
System.out
.println("执行格式为:java CreateTable 表名   执行命令(如,create\\drop)");
return;
}
String tablename =args[0];
String command=args[1];
if("create".equals(command)){
sql = "create table " + tablename + "("
+ " ID number(12) primary key,"
+ "    PWD varchar(10) not null)";
}else if("drop".equals(command)){
sql="drop table "+tablename;
}
try {
DriverManager.registerDriver(driver);
conn = DriverManager.getConnection(url, user, pwd);
stmt = conn.createStatement();

int result = stmt.executeUpdate(sql);
System.out.println(result);
} catch (SQLException e) {
e.printStackTrace();

}
}
}











JDBC_day02_am

1.结果集遍历
  a.游标指向的记录叫当前记录,只有当前记录值可读;
  数据库中的行和列的索引都是从“1”开始
  b.游标可移动(rs.next())
  c.默认的 ResultSet 对象不可更新,仅有一个向前移动的光标,游标的最终位置是最后一条记录后面(单向)afterlast,若要使游标可来回移动可使用下面方法(以下代码片段(其中 con 为有效的 Connection 对象)演示了如何生成可滚动且不受其他更新影响的可更新结果集):
 
Statement stmt = con.createStatement(
                                      ResultSet.TYPE_SCROLL_INSENSITIVE,
                                      ResultSet.CONCUR_UPDATABLE);
       ResultSet rs = stmt.executeQuery("SELECT a, b FROM TABLE2");

   d.游标的最初位置beforefirst
  
2.将具有相同或重复性的代码进行封装
 
package tang.jdbc;
import java.sql.*;
public class JdbcUtil {
// 静态加载驱动,只需要加载一次就可以
static {
      /* 直接使用此段代码也可加载驱动,oracle.jdbc.driver.OracleDriver类中的static自动加载
Driver driver = new oracle.jdbc.driver.OracleDriver();*/
try {
// load Driver
String driver = "oracle.jdbc.driver.OracleDriver";
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
/*
* 直接在命令行中使用java -D jdbc.drivers=oracle.jdbc.driver.OracleDriver
* 直接加载环境变量中的驱动
*/
}
public static Connection getConnection() {
Connection conn = null;
try {
String url = "jdbc:oracle:thin:@172.18.9.6:1521:tarena";
String user = "scott";
String password = "tiger";
conn = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
  //注意"有连接"的关闭顺序
public static void close(ResultSet rs, Statement stmt, Connection con) {
if (null != rs) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (null != stmt) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (null != con) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
   public static int toInt(String str){
   return Integer.parseInt(str);
   }
}

3.DriverManager的工作原理(若内存中有多个驱动,它如何进行选择)





























JDBC_day02_pm
1.PreparedStatement(预编译后的SQL执行类型)
批量处理SQL
   



         sql=”insert into sd091202 values(?,?)”;
         sp=con.prepareStatement(sql);
         sp.setInt(1,10);
         sp.setString(2,”xiaohegn”);
         sp.executeUpdate();
        
老师建议:面试笔试时使用PreparedStatement,显得有经验
PreparedStatement的小实例:
package tang.jdbc;
import java.sql.*;
public class PreparedStatementTest {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement ps=null;
conn=JdbcUtil.getConnection();//此处的JdbcUtil是上面的封装类
   try {
    conn.setAutoCommit(false);
ps=conn.prepareStatement("insert into sd091202 values(?,?)");
ps.setInt(1, 2);
ps.setString(2, "bbbb");
conn.commit();
int result= ps.executeUpdate();
System.out.println(result);
} catch (SQLException e) {
e.printStackTrace();
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
JdbcUtil.close(null, ps, conn);
}
}


JDBC_day03_am

1.DatabaseMetaData通过Connection获取对象,从而获取数据库的相关信息;
ResultSetMetaData通过ResultSet获取对象,从而获取表的有关信息(如列名,列数目等)
2.事务处理(Transaction)
  原子操作:一组相关操作,要么全成功,要么全失败!

JDBC_day03_pm

1.事务处理
   a.在执行操作之前调用Connection的setAutoCommit(false)方法;
   b.在事务处理成功且完成后再手动提交事务,此时调用Connection的commit()方法;
   c.若事务处理失败(如出现异常)则调用Connection的rollback()方法,执行会滚操作,撤销上一次commit()的状态;数据库将保存在其他地方的原数据进行恢复(rollback 操作是将 rollback segment/undo segment 的数据返回)

2.对所读数据正确度的影响因素
   a.事务中的dirty read(脏读。何为脏数据:未保存或未提交的数据):一个事务处理到了未保存或未提交的数据;
   b.事务中unrepactable read(不可重复读):第一更新丢失
   c.事务中的phantom read(幻读):读到的数据量不一致;
如何处理上诉的影响因素:
  设置事务隔离: getTrasactionIsolation
                  Connection.setTransactionIsolation(Connection的静态变量)
               
3.增强的结果集
  设置结果集游标是否可滚动和可更新等,默认的游标只能单向移动且不可更新;
  单向只读(默认);双向只读;双向可更新(在生成结果集之前声明,即在创建Statement时设置)如,
Statement stmt = con.createStatement(
                                      ResultSet.TYPE_SCROLL_INSENSITIVE,
                                      ResultSet.CONCUR_UPDATABLE);
       ResultSet rs = stmt.executeQuery("SELECT a, b FROM TABLE2");


4.JNDI使用的类javax.naming.*;
  获取数据源:Context ctx=new InitialContext();
               ctx.lookup(name);














JDBC_day04_am
1.使用PreparedStatement进行批处理过程,如出路1万条,用循环控制:
for(int i=1;i<=10000;i++){
ps.set(1,x);
ps.set(2,y);
.....................
ps.set(n,z);
ps.addBatch();
  if(i%100==0){
    ps.executeBatch();
  }
}

下面为一个具体的实例:
package tang.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class PreparedStatementTest {

/**
* @param args
*/
public static void main(String[] args) {

Connection conn=null;
PreparedStatement ps=null;
conn=JdbcUtil.getConnection();
try {
ps=conn.prepareStatement("insert into aaa values (?,?)");
long start=System.currentTimeMillis();
        //位置1
for(int i=1;i<=10000;i++){
ps.setInt(1, i);
ps.setString(2, "tang");
ps.executeUpdate();
//System.out.println(i);
}
     //位置2
// for(int i=1;i<=10000;i++){
// System.out.println(i);
// ps.setInt(1, i);
// ps.setString(2, "zhi");
// ps.addBatch();
// if(i%100==0){
// ps.executeBatch();
// }
// }

long end=System.currentTimeMillis();
System.out.println("执行的时间为: "+(end-start)+" 毫秒");
} catch (SQLException e) {
e.printStackTrace();
}

}

}
结果:
位置1:执行的时间为: 85555 毫秒
位置2:执行的时间为: 2210 毫秒
2.连接池(提高连接的效率):池--》可重复使用的资源(资源的特点:有用且稀缺)
特点:用完收回(重复);实现建好;
3.Blob-->Binary Large Object(常用的类型,二进制文件的使用稍多,如:mp3,jpg,zip,exe等)
Clob-->Character Large Object(纯文本[字符串],如text,而pdf等不可存)
主要讲解java.sql.Blob接口:

使用PreparedStatement的setBinaryStream可以将二进制存入数据库;
从数据库中取:使用ResultSet可以获得Blob类性的对象;

Blob数据存入数据库:
package tang.jdbc;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Blob_Save_to_DB_Test {

/**
* 将文件保存进数据库
*/
public static void main(String[] args) {

Connection conn=null;
  PreparedStatement ps=null;
 
  conn=JdbcUtil.getConnection();
  try {
ps=conn.prepareStatement("insert into table_blob values(?,?)");
File file=new File("/home/soft01/oracle.jar");
InputStream is;
  is = new FileInputStream(file);
ps.setInt(1, 2);
  ps.setBinaryStream(2, is,is.available());

ps.executeUpdate();
System.out.println("success!");
} catch (SQLException e) {
e.printStackTrace();
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
  JdbcUtil.close(null, ps, conn);
}

}
将blob类型取出数据库并保存
package tang.jdbc;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class Blob_Get_from_DB_Test {

/**
* 将文件取出数据库
*/
public static void main(String[] args) {

Connection conn=null;
  PreparedStatement ps=null;
    ResultSet rs=null;
    Blob blob=null;
    FileOutputStream fos=null;
  conn=JdbcUtil.getConnection();
    try {
ps=conn.prepareStatement("select file_content from table_blob where id=?");
ps.setInt(1, 1);
rs=ps.executeQuery();
if(rs.next()){
blob=rs.getBlob(1);
}
InputStream is=blob.getBinaryStream();
try {
fos=new FileOutputStream("/home/soft01/jdbcproject/day03/src/tang/jdbc/desk.gif");
byte b[]=new byte[1024];
try {
while(is.read(b)!=-1){
fos.write(b);
}
fos.close();
is.close();
System.out.println("success");
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}

} catch (SQLException e) {
e.printStackTrace();
}
 
 
  JdbcUtil.close(rs, ps, conn);


}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值