JDBC技术
java.sql包中的主要类和接口:
DriverManager(类);
Connection(接口);
Statement(接口);
PreparedStatement(接口);
ResultSet(接口)
一、DriverManager类
该类是JDBC的管理层,作用于用户和驱动程序之间。它跟踪可用的驱动程序,并在数据库和相应驱动程序之间建立连接。在使用此类之前,必须先加载数据库驱动程序,加载方式:Class.forName(JDBC数据库驱动);
加载前应把下载的驱动程序(mysql-connector-java-5.1.39-bin.jar)拷贝到\jdk\jre\lib\ext或\tomcat5.x\common\lib文件夹中。
Class.forName(JDBC数据库驱动)中JDBC驱动程序的写法:
MySQL数据库驱动:com.mysql.jdbc.Driver
SQLServer2005数据库驱动:com.microsoft.sqlserver.jdbc.SQLServerDriver
Orcale数据库驱动:oracle.jdbc.driver.OracleDriver
二、Connection接口
数据库驱动程序加载之后,可以调用DriverManager.getConnection()方法得到数据库的连接
ConnectionManager类的静态方法getConnection()方法返回一个数据库连接,与数据库建立连接后,可以对数据库进行增、删、改、查等操作。当操作结束后,调用相应的关闭方法(close),释放对应的资源。
在DriverManager类中定义了三个重载的getConnection()方法:
static Connection getConnection(String url);
static Connection getConnection(String url, Properties info);
static Connection getConnection(String url, String user,String password);
其中参数:
url :建立数据库连接的字符串,不同的数据库其连接字符串不一样。常用数据库的连接字符串:
MySQL:jdbc:mysql://主机名:3306/数据库名
SQLServer:jdbc:sqlserver://主机名:1433;databaseName=数据库名
Orcale:jdbc:orcale:thin:@主机名:1521:数据库名
info :作为连接参数的任意字符串标记/值对的列表;通常至少应该包括 “user” 和 “password” 属性
user: 数据库用户,连接是为该用户建立的
password :用户的密码
三、Statement接口
该接口对象用于将普通的SQL语句发送到数据库中。建立了到数据库的连接后,就可以创建Statement对象。Statement接口可以通过调用Connection接口的CreateStatement()方法创建。例如:
Connection connection=DriverManager.getConnection(url, “user”, “password”);
Statement stmt=connection.createStatement();
Statement接口提供了4种执行SQL语句的方法:executeQuery()、executeUpdate()、executeBatch()、和execute()。使用哪一种由SQL语句所返回的结果决定,常用的是前两个方法。
-
executeUpdate()方法用于更新数据,如执行Insert、Update和Delete及SQL DDL(数据定义)语句,这些语句不返回记录集,而是返回一个整数,表示受影响的行数。其方法原型:int executeUpdate(String sql),其中sql为SQL命令字符串。
-
executeQuery()方法用于执行select语句,返回一个结果集,其类型为ResultSet。ResultSet是一个数据库游标,通过它可访问数据库中的记录,其原型:
-
ResultSet executeQuery(String sql),sql为SQL命令字符串。
四、PreparedStatement接口
该接口基础自Statement接口,具有Statement的所有方法,同时又增加了自己的方法。PreparedStatement接口对象包含已编译的SQL语句,其执行速度要快于Statement对象。PreparedStatement接口对象中的SQL语句可包含一个或多个IN参数,也可用“?”作为占位符。
**注意:**在创建PreparedStatement对象时,需要 SQL命令字符串作为preparedStatement()方法的参数,在调用PreparedStatement对象的executeQuery()或executeUpdate()方法执行查询时,不再需要参数。
使用PreparedStatement对象的SQL命令字符串中使用“?”占位符时,在执行executeQuery()或executeUpdate()方法之前,要用setXXX(n, p)方法为占位符赋值。如setString()方法可为字符串型数据赋值。方法中的参数n表示要赋值的参数在SQL命令字符串中出现的位置,n从1开始;p为参数设置的值。
五、ResultSet接口
ResultSet接口用于获取执行SQL语句/数据库存储过程返回的结果,它的实例对象包含符合SQL语句中条件的所有记录的集合,并且它可以通过一套getXXX()方法提供对这个集合的访问。next()方法用于移动数据库游标到记录集中的下一行,使下一行成为当前行,可通过此游标访问记录集中的记录。
ResultSet接口对象的游标最初位于结果集的第一行的前面,当执行一次next()方法之后才会将指针指向第一条记录。每调用一次next()方法数据库游标向下移动一行,直到记录集最后一行。在ResultSet或Statement对象关闭之前,数据库游标一直有效。
在数据库游标移动过程中,可通过getXXX()方法获取结果集中的数据,其中XXX与结果集中所存放的数据类型有关。getXXX()方法将基本数据类型转换成指定Java类型,然后返回合适的值。
数据库的操作示例
在Java中提倡面向接口编程,通过接口定义类的方法原型,在具体类中实现接口,这样给编程带来很大的灵活性。
设计包::
utils 用于存放工具类
dao 用于存放接口
impl 存放接口的实现类
test 用于存放测试类
通过JDBC驱动与MySQL数据库中的books数据库建立连接
ConnectionManager工具类:
package utils;
import java.sql.*;
public class ConnectionManager {
//数定义据库驱动字符串
private static final String DRIVER_CLASS = "com.mysql.jdbk.Driver";
//定义数据库连接字符串
private static final String DATABASE_URL = "jdbc:mysql://localhost:3306/books?";
//定义数据库用户名
private static final String DATABASE_USER = "root";
//定义数据库密码
private static final String DATAVASE_PASSWORD = "123456789";
/**
* 用来获取一个Connection(数据库连接对象)
* @return 数据库连接对象
*/
public static Connection getConnection(){
Connection con = null;
try{
Class.forName(DRIVER_CLASS);
con = DriverManager.getConnection(DATABASE_URL,DATABASE_USER,DATAVASE_PASSWORD);
}catch (Exception e){
e.printStackTrace();
}
return con;
}
public static void closeConnection(Connection con){
try{
//如果con对象不为空,并且他没有被关闭,则关闭它
if(con != null && (!con.isClosed())){
con.close();
}
}catch (SQLException e){
e.printStackTrace();
}
}
/**
* 关闭结果集对象
* @param rs 结果集
*/
public static void closeResultSet(ResultSet rs){
try{
if(rs != null){
rs.close();
}
}catch (SQLException e){
e.printStackTrace();
}
}
/**
* 关闭执行sql语句的对象
* @param ps
*/
public static void closePreparedStatement(PreparedStatement ps){
try{
if(ps != null){
ps.close();
}
}catch (SQLException e){
e.printStackTrace();
}
}
/**
* 关闭另外一种执行sql语句的对象
* @param st
*/
public static void closeStatement(Statement st){
try{
if(st != null){
st.close();
}
}catch (SQLException e){
e.printStackTrace();
}
}
}
定义account表的数据操作接口:
package dao;
import java.sql.*;
/**
* books数据库 account表 账户表里面有balance(double 余额) id(int 编号) cardNo(varchar 卡号)三个属性
*/
public interface AccountDao {
/**
* 添加id和卡号
* @param id 编号
* @param cardNo 卡号
* @return 返回修改成功的条数
*/
public int insert(int id,String cardNo);
/**
* 根据卡号修改余额
* @param cardNo 卡号
* @param balance 余额
* @return 返回受到影响的记录条数
*/
public int update(String cardNo,double balance);
/**
* 根据id来删除记录
* @param id 用户id
* @return 删除的记录条数
*/
public int delete(int id);
/**
* 根据id查询账户数据
* @param id 账户id
* @return 返回查询结果集合
*/
public ResultSet select(int id);
}
定义account表的数据操作类,要求实现AccountDao接口
package impl;
import dao.AccountDao;
import utils.ConnectionManager;
import java.sql.*;
public class AccountDaoImpl implements AccountDao {
private Connection con;//数据库连接对象
private PreparedStatement ps;//用于执行sql的对象
@Override
public int insert(int id, String cardNo) {
int result = 0;//记录修改的数量
con = ConnectionManager.getConnection();//利用工具类获取connection连接对象
try{
String sql = "insert into account(id,cardNo) values(?,?)";
ps = con.prepareStatement(sql);
ps.setInt(1,id);
ps.setString(2,cardNo);
result = ps.executeUpdate();//执行sql语句,获取结果
}catch (SQLException e){
e.printStackTrace();
}
return result;
}
@Override
public int update(String cardNo, double balance) {
int result = 0;
con = ConnectionManager.getConnection();
try{
String sql = "update account set balance=? where cardNo=?";
ps = con.prepareStatement(sql);
ps.setDouble(1,balance);
ps.setString(2,cardNo);
result = ps.executeUpdate();
}catch (SQLException e){
e.printStackTrace();
}
return result;
}
@Override
public int delete(int id) {
int result = 0;
con = ConnectionManager.getConnection();
try{
String sql = "delete from account where id=? ";
ps = con.prepareStatement(sql);
ps.setInt(1,id);
result = ps.executeUpdate();
}catch (SQLException e){
e.printStackTrace();
}
return result;
}
@Override
public ResultSet select(int id) {
ResultSet rs = null;//保存结果集的对象
con=ConnectionManager.getConnection();
try {
String sql = "select * from account where id=?";
ps = con.prepareStatement(sql);
ps.setInt(1,id);
rs=ps.executeQuery();
}catch (SQLException e){
e.printStackTrace();
}
return rs;
}
}
编写测试类TestAccount,对TestAccountDaoImpl类中的方法进行测试,看是否能输出正确的结果
package test;
import dao.AccountDao;
import impl.AccountDaoImpl;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TextAccount {
public static void main(String[] args) {
AccountDao dao = new AccountDaoImpl();
int n =0;//用于保存操作结果
n = dao.insert(2,"002");
if(n > 0){
System.out.println("插入成功!");
}else {
System.out.println("插入失败!");
}
n = dao.update("001",20000);
if(n > 0){
System.out.println("修改成功!");
}else {
System.out.println("修改失败!");
}
n = dao.delete(2);
if(n > 0){
System.out.println("删除成功!");
}else {
System.out.println("删除失败!");
}
ResultSet rs = dao.select(1);
try {
while (rs.next()){
int id = rs.getInt("id");
double balance = rs.getDouble("balance");
String cardNo = rs.getString("cardNo");
System.out.println("编号:"+id+" 余额:"+balance+" 卡号:"+cardNo);
}
}catch (SQLException e){
e.printStackTrace();
}
}
}