Java程序设计

第八章 数据库编程

Java数据库编程概述

  • JDBC(Java Database Connectivity)是实现Java应用程序与数据库通信的一套规范和编程接口,提供了用于连接\访问\操作关系数据库的统一接口

Java数据库编程概述

  • JDBC四要素
    • DriverManager(处理驱动程序的加载和建立新数据库连接)
    • Connection(处理与特定数据库的连接,创建语句资源)
    • Statement(在指定连接中处理SQL语句,创建结果资源)
    • ResultSet(处理数据库操作结果集)

加载JDBC驱动

  • 数据库驱动类型
    • JDBC-ODBC桥驱动(JDBC-ODBC Bridge)
    • 本地API驱动(native API driver)
    • 网络纯Java驱动(net-protocol fully Java driver)
    • 本地协议纯Java驱动(native-protocol all-Java)

JDBC驱动下载

  • JDBC驱动类名
    • 不同的数据库有不同的驱动程序,不同厂家实现的JDBC接口的类也不同
    • 通常封装在一个或多个包中,采用“包名-类名"的形式
    • 从官网下载对应版本的数据库驱动程序
    • 配置CLASS_PATH参数
DataBase Driver Class
MySQL com.mysql.jdbc.Driver
Oracle oracle.jdbc.driver.OracleDriver
SQL Server com.microsoft.sqlserver.jdbc.SQLServerDriver
PostgreSQL org.postgresql.Driver

注册驱动

  • Java提供了3种加载注册数据库驱动程序的方法
    • DriverManager类的静态方法registerDriver()注册
      • DriverManager.registerDriver(new 驱动程序类名())
      • 
        DriverManager.registerDriver(new com.microsoft.sqlserver.jdbc.SQLServerDrive());
                                            
    • 使用反射机制进行数据库驱动程序的实例化
      • Class类的静态方法forName可从已知包中将需要的类加载到程序中
      • 
        Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDrive");
                                            
      • 若要在一个程序中加载多种数据库驱动,可用多个Class.forName(driver)
      • 数据库加载驱动,必须放在try-catch块中

注册驱动

  • Java提供了3种加载注册数据库驱动的方法
    • 使用System.setProperty()方法注册
    • 
      System.setProperty("jdbc.drivers","DRIVER");
                                      
      • 如System.setProperty("jdbc.drivers","com.mysql.jdbc.Driver");
      • 可用冒号将驱动程序分开,加载多种数据库驱动
      • 
        System.setProperty("jdbc.drivers","Driver1:Driver2");
                                            

注册驱动方法

DriverManager中的常用方法 描述
static void registerDriver(new Driver()) 注册一个数据库驱动
static void deregisterDriver(Driver driver) 从驱动列表中删除给定的数据库驱动
static Driver getDriver(String URL) 获取用URL指定的数据库驱动
static Connection getConnection(String JDBCUrl);static Connection getConnection(String JDBCUrl, Properties info); static Connection getConnection(String JDBCUrl, String username, String password) 获取与数据库的连接,使用1-3个参数:JDBCUrl: 为数据源URL; info: 数据库属性; username: 用户名; password: 密码;

连接数据库

  • JDBC URL 数据源描述
    • 将要连接数据源的有关信息封装在一个String对象中
    • jdbc协议:子协议:子名称
    • jdbc协议,如jdbc
    • 子协议,用于标识数据库的连接机制,如mysql用于MySQL数据库,derby用于Java DB数据库,oracle用于Oracle数据库
    • 子名称,用于标识数据源,提供定位数据源的详细信息,形如//主机名:端口/子名称
      • 如用于SQL Server的URL形如:jdbc: microsoft: sqlserver://服务器名:1433/DatabaseName=数据库名
      • 如用于MySQL的URL形如:jdbc:mysql://服务器名:数据库名

连接数据库

  • Connection对象
    • Java应用程序与数据库之间进行数据传递都必须创建一个Connection实例,所有的一系列操作都是由其直接或间接衍生
  • 获取Connection对象方法(1)
    • 可使用DriverManager获取Connection对象
    • 
      Connection conn=DriverManager.getConnection(url,"id","psd");
                                      
      
      String url_ms="jdbc:sqlserver://127.0.8.88:1433:DatabaseName=master";
      String url_mysql="jdbc:mysql://10.0.7.76:3304/myDB";
      String user="aName";
      String psd="123456";
      Connection con=DriverManager.getConnection(url,user,psd);
                                      

连接数据库

  • 获取Connection对象方法(2)
    • 使用数据库连接池获取
      • 为数据库连接建立一个”缓冲池”,预先在缓冲池中放入一定数量的连接,当需要建立数据源连接时,从“缓冲池”中取出一个连接,使用完后再放回去
      • 对普通应用程序,可选用DataSource对象,或DriverManager,但对需要用的连接池或分布式事务的应用程序,必须使用DataSource对象获得Connection

Context ctx=new InitialContext();
DataSource ds=(DataSource)ctx.lookup("jdbc/EmployeeDB");
Connection conn=ds.getConnection("myPassword", "myUserName");
                        

连接数据库

  • 连接过程中的异常处理
    • getConnection()方法在执行过程中可能会抛出SQLException异常,因此需要用try-catch进行处理

try{
    Connection conn=DriverManager.getConnection("jdbc:odbc:sun","zhang","abcde");
}catch(SQLException e){
    //...
}
                        

连接数据库

Conneciton接口常用方法 说明
Statement createStatement() 创建一个Statement实例
Statement createStatement(int resultSetType, int resultSetConcurrency) resultSetType: 实例类型,resultSetConcurrenty: 并发性的结果集
PreparedStatement preparedStatement(String sql) 创建一个PreparedStatement实例
PreparedStatement preparedStatement(String sql, int resultSetType, int resultSetConcurrency) sql:数据库SQL语句,resultSetType:类型

创建SQL工作空间进行数据库操作

创建SQL工作空间,实质是创建Statement实例,利用Connection的createStatement()方法


try{
    Statement stt=conn.createStatement();
}catch(SQLException e){
    //...
}
                        

创建SQL工作空间进行数据库操作

  • 用Statement实例封装SQL语句,如executeQuery,executeUpdate等语句,executeQuery执行的结果返回在ResultSet中
  • 
    try{
        ResultSet resultSet=stt.executeQuery("SELECT * from emp where empno = * FROM 员工表 WHERE 员工年薪 >= 55" );
    }catch(SQLException e){
        //...
    }
    String sqlQuery = "SELECT PRODUCT FROM SUPPLIERTABLE WHERE PRODUCT = 'Bolts'";
                                
    • JDBC在编译时不对将要执行的SQL查询语句执行任何检查,只是将其作为一个String类对象,要到驱动程序执行SQL语句时才知道是否正确
    • 一个Statement实例只能在同一时间打开一个结果集,对第二个结果集的打开隐含着对第一个结果集的关闭
    • 如果对多个结果集同时操作,则必须创建多个Statement实例,在每个Statement实例上执行SQL查询语句

创建SQL工作空间进行数据库操作

Statement接口常用方法 说明
void close() 关闭当前的Statement实例
void cancel() 取消Statement实例中的SQL数据库操作命令
ResultSet executeQuery(String sql) 执行SQL Select语句,将查询结果存放在一个ResultSet对象中
void executeUpdate(String sql) 执行SQL更新语句(update,delete,insert),返回整数表示所影响的数据库表行数
boolean execute(String sql) 执行(返回多相结果集)SQL语句,即前两个方法合并
int[] executeBatch() 在Statement对象中建立批执行SQL语句表
void addBatch(String sql) 向批执行表中添加SQL语句
void clearBatch() 清除在Statement对象中建立的批执行SQL语句
ResultSet getResultSet() 返回当前结果集
boolean getMoreResults() 移动到Statement实例的下一个结果集(用于返回多个结果的SQL语句)

处理结果集

  • Statement实例执行与数据库交互的结果由结果集进行封装
  • 结果集由游标进行管理
    • 游标,指向结果集中的行,初始时指向第1行
    • rs.last(), rs.first(), rs.previous(), rs.next()
    • rs.getRow(), rs.absolute()
    • rs.isFirst(), rs.isLast()

处理结果集

  • 游标的getXxx()方法
    • SQL结果集中,每一列是一个数据类型,getXxx()方法用于进行列数据类型的转换
SQL类型 Java数据类型 getXxx()方法 SQL类型 Java数据类型 getXxx()方法
CHAR/VARCHAR String String getString() LONGVARCHAR String InputStream getAsciiStream()/getUnicodeStream()
NUMERIC/DECIMAL java.Math.BigDecimal java.math.BigDecimal getBigDecimal() BIT Boolean boolean getBoolean()
TINYINT Integer byte getByte() SMALLINT Integer short getShort()
INTEGER Integer int getInt() BIGINT long long getLong()
REAL float float getFloat() FLOAT/DOUBLE double double getDouble()
BINARY/VARBINARY byte[] byte[] getBytes() LONGVARBINARY byte[] InputStream getBinaryStream()
DATE java.sql.Date java.sql.Date getDate() TIME java.sql.Time java.sql.Time getTime()
TIMESTAMP java.sql.Timestamp java.sql.Timestamp getTimestamp()

处理结果集

  • 对数据库操作结束后,应当按照先建立(打开)后关闭的顺序依次关闭ResultSet, Statement(PreparedStatement)和Connection引用指向的对象
  • 假设这些对象分别是rsltSet, stt和conn,则应执行的顺序为
  • 
    rsltSet.close();//关闭查询结果集
    stt.close();//关闭语句连接
    conn.close();//关闭数据库连接
                                

JDBC数据库查询实例

JDBCDemo.java

PreparedStatement接口

  • PreparedStatement接口适用于建立动态SQL工作空间,其实例执行的SQL语句被预编译并保存到PreparedStatement实例中,用于操作不确定的内容
  • 如 String sql="INSERT INTO user(name, age, gender)"+"VALUES(?,?,?)"
  • 其中每个用“?"表示的字段可用setXxx()方法设定,其中Xxx为类型,如String, int等
  • 当数据库执行预编译时,SQL语句被预编译并存储在PreparedStatement对象中,此后可多次使用这个对象高效执行该语句

PreparedStatement接口

  • 一组封装SQL语句的方法
封装SQL语句的主要方法 说明
void addBatch(String sql) 向批执行表中添加SQL语句,在statement语句中增加用于数据库操作的SQL批处理语句
void clearParameters() 清除PreparedStatement中的设置参数
boolean execute() 执行SQL查询语句,可以是任何类型的SQL语句
ResultSet executeQuery() 执行SQL查询语句
int executeUpdate() 执行设置的预处理SQL语句,如insert, update, delete等,返回更新的列数
ResultSet.MetaData getMetaData() 进行数据库查询,获取数据库元数据

PreparedStatement接口

  • 一组setXxx()方法,第一个参数index表示占位符的位置,索引值从1开始
设置数据方法 设置数据方法
void setArray(int index, Array x) void setAsciiStream(int index, InputStream stream, int length)
void setBigDecimal(int index, BigDecimal x) void setBinaryStream(int index, InputStream stream, int length)
void setCharacterStream(int index, InputStream stream, int length) void setBoolean(int index, boolean x)
void setByte(int index, byte x) void setBytes(int index, byte[] b)
void setDate(int index, Date x) void setFloat(int index, float x)
void setInt(int index, int x) void setLong(int index, long x)
void setRef(int index, int ref) void setShort(int index, short x)
void setString(int index, String x) void setTime(int index, Time x)

PreparedStatement接口

  • PreparedStatement对象操作SQL语句步骤
    • 创建PreparedStatement对象,同时给预编译SQL语句
    • 
      PreparedStatement preStat=conn.prepareStatement("SELECT * FROM dbTableName");
                                      
    • 设置实际参数
    • 
      preStat.setString(1,"b001");
                                      
    • 执行SQL语句
    • 
      ResultSet rst=preStat.executeQuery();
                                      
    • 关闭PreparedStatement对象
    • 
      preStat.close();
                                      

PreparedStatementDemo.java