JDBC 数据库基本操作
一般开发简单的 JDBC 程序的流程如下:
1、加载驱动程序Driver对象
Class.forName("JDBCDriverClass")
创建 Driver 对象,其中 JDBCDriverClass 参数的候选者如下:
数据库 | 驱动类 |
MySQL | com.mysql.jdbc.Driver |
Oracle | oracle.jdbc.driver.OracleDriver |
Access | sun.jdbc.odbc.JdbcOdbcDriver(JDK中已经包含) |
部分驱动类的下载地址:
MySQL JDBC: www.mysql.com/products/connector/
示例:
Class.forName("com.mysql.jdbc.Driver"
2、建立Connection连接对象
Connection connection = DriverManager.getConnection("databaseURL");
创建 Connection 对象,其中 databaseURL 参数的模式如下:
数据库 | URL模式 | 说明 |
MySQL | jdbc:mysql//hostname/dbname | 指定主机名,数据库名 |
Oracle | jdbc:oracle:thin:@hostname:port#oracleDBSID | 指定主机名,数据库监听输入连接请求的端口号,定位数据库的数据库名 |
Access | jdbc:odbcLdataSource | 先在Windows下的ODBC数据管理器创建一各ODBC数据源,在创建Connection对象 |
示例:
//Mysql
Connection connection = DriverManger.getConnection("jdbc:mysql//localhost/bookrama","username","password");
//Oracle
Connection connection = DriverManger.getConnection("jdbc:oracle:thin:@localhost:1521:orcl","username","password");
//Access
Connection connection = DriverManager.getConnection("jdbc:odbc:ExampleMDBDSource");
3、创建Statement对象
Statement statement = connection.createStatement(int ResultSetType,innt ResultSetConcurrency);
- Connection对象是Java程序与数据库的连接通道,Statement对象时通道上的信息交换器;
- 参数 ResultSetType 指定返回结果集的类型,ResultConcurrency 指定结果集的并发类型,connection.createStatement() 不指定参数等同于使用默认参数 connection.createStatement( TYPE_FORWARD_ONLY,CONCUR_READ_ONLY);
ResultSetType 参数候选值 | |
ResultSet.TYPE_FORWARD_ONLY
|
光标只能在结果集中向前移动(默认值)
|
ResultSet.TYPE_SCROLL_INSENSITIVE
|
光标可以向前和向后滚动,结果集对创建结果集后发生的数据库所做的更改不敏感。
|
ResultSet.TYPE_SCROLL_SENSITIVE
|
光标可以向前和向后滚动,结果集对创建结果集之后发生的其他数据库的更改敏感。
|
ResultSetConcurrency 参数候选值 | |
ResultSet.CONCUR_READ_ONLY
|
创建只读结果集(默认值)
|
ResultSet.CONCUR_UPDATABLE
|
创建可更新的结果集
|
4、执行SQL语句,获取结果集
执行查询操作:
ResultSet resultSet = statement.executeQuery("SQLString");
执行更新、删除、添加等操作
statement.executeUpdate("SQLString");
一般update类的操作,不通过ResultSet判断是否执行成功,而是通过捕获其抛出的 SQLException,再进行事务的rollback操作,详情见:http://blog.csdn.net/al_assad/article/details/76091377
5、处理ResultSet结果集
1)获取元数据
可以通过 ResultSetMetaData 对象获取 ResultSet 对象的元数据;
....
//输出返回结果集的字段元数据
ResultSetMetaData rsMetaData= connection.getMetaData();
for(int i=1; i< rsMetaData .getColumnCount() ;i++ )
System.out.printf("%-12s\t", rsMetaData.getColumnName(i));
2)浏览结果集
※ ResultSet 结果集的行列索引下标都是从1开始的;
//假设查询的数据表中的字段依次为isbn,author,title,price,注意结果集字段索引值从1开始;
while(resultSet.next()){
String isbn = resultSet.getString(1);
String author = result.getString(2);
String title = resultSet.getString(3);
float price = resultSet .getFloat(4);
}
//or
String isbn = resultSet.getString("isbn");
String author = result.getString("author");
String title = resultSet.getString("title");
float price = resultSet .getFloat("price");
}
- ResultSet 中关于 移动光标 的API
void beforeFirst()
|
将光标移动到第一行之前
|
void afterLast()
|
将光标移动到最后一行之后
|
boolean first() | 将光标移动到第一行。 |
void last() | 将光标移动到最后一行。 |
boolean absolute(int row) | 将光标移动到指定的行。 |
boolean relative(int row) | 从当前指向的位置,将光标向前或向后移动给定行数。 |
boolean previous() | 将光标移动到上一行。 如果上一行关闭结果集,此方法返回false。 |
boolean next() | 将光标移动到下一行。 如果结果集中没有更多行,则此方法返回false。 |
int getRow() | 返回光标指向的行号。 |
void moveToInsertRow() | 将光标移动到结果集中的特殊行,该行可用于将新行插入数据库。当前光标位置被记住。 |
void moveToCurrentRow() | 如果光标当前位于插入行,则将光标移回当前行; 否则,此方法什么也不 |
- ResultSet 中关于获取 当前行中的列索引
int getInt(String columnName)
|
返回名为columnName的列中当前行中的int值
|
- ResultSet 中关于 更新当前行列索引指向值 的API
void updateString(int columnIndex, String s)
|
将指定列中的String值更改为指定的s值
|
void updateString(String columnName, String s)
|
与前前的方法类似,除了使用列的名称而不是列的索引指定。
|
以上的 updateXXX()方法共有针对 8 种基本数据类型的的更新方法,同时包含 java.sql 包中的其他SQL数据数据类型,如果 updateInteger() 用于更新 Integer 类型的数据;
以上的 updateXXX()方法的修改仅仅会修改 ResultSet当前行中的数据,但不会更改数据库中列的值,如果要同时更新数据库中的行,需要调用以下的方法之一:
void updateRow() | 更新数据库中当前行 |
void deleteRow() | 从数据库中删除当前行 |
void refreshRow() | 刷新结果集中的数据以反映数据库中最近的任何更改。 |
void cancelRowUpdates() | 取消对当前行所做的任何更新。 |
void insertRow() | 在数据库中插入一行。 只有当光标指向插入行时,才能调用此方法。 |
示例:
Class. forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/bookrama","root","root");
Statement statement = connection .createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
ResultSet resultset = statement.excuteQuery("select * from books order by price asc");
//将返回结果集中第4行以后的所有price字段全部执行更新操作
resultset.absolute(3);
while(resultset.next()){
resultset.updateFloat("price",resultset.getFloat("price")+100);
resultSet.updateRow();
}
6、关闭Connection连接对象
connection.close();
获取数据库元数据
除了以上步骤5中,通过ResultSet获取结果集的元素据,也可以在建立Connection对象后,通过 DataBaseMetaData 对象直接获取数据库元数据;
示例:
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql//localhost/demoDatabase","root","123");
DatabaseMeta dbMetaData = connection.getMetaData();
String url = dbMetaData.getURL();
String userName = dbMetaData.getUserName();
String dataProductName = dbMeta.getDataProductName();
String driverName = dbMeta.getDriverName();
......
更多关于 DatabaseMetaData 对象可获取的数据库元数据参数,详见 JDK 技术文档;
完整过程示例
//以下过程,展示插入向数据库插入数据后,输出更新后表的详细
//加载数据库驱动类,建立连接对象、传输对象
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql//localhost/bookRama","root","123");
Statement statement = conncection.createStatement();
//执行Insert操作
statement.executeUpdate("insert into books(isbn,author,title,price) value (201301,someone,Java Programmer,12.3)");
//执行查询操作,输出查询结果
Resulset resultset = statement.executeQuery("select isbn,author,title,price from books");
while(resultset.next()){
String isbn = resultset.getString("isbn");
String author = result.getString("author");
String title = resultSet.getString("title");
float price = resultSet .getFloat("price");
System.out.printf("%-12s\t%-12s\t%-12s\t%-6d\n",isbn,author,title,price);
}
//关闭数据库
connection.close();