<一> 使用JDBC连接数据库
注意 : preparestatement 可以防止sql 注入
JDBC是由java编程语言编写的类及接口组成,同时它为程序开发人员提供了一组用于实现对数据库访问的JDBC API,并支持SQL语言。利用JDBC可以将JAVA代码连接到oracle、DB2、SQLServer、MYSQL等数据库,从而实现对数据库中的数据操作的目的。
《1》JDBC简介
JDBC全称为:Java Data Base Connectivity (java数据库连接),可以为多种数据库提供填统一的访问。JDBC是sun开发的一套数据库访问编程接口,是一种SQL级的API。它是由java语言编写完成,所以具有很好的跨平台特性,使用JDBC编写的数据库应用程序可以在任何支持java的平台上运行,而不必在不同的平台上编写不同的应用程序。
JDBC的主要功能如下:
(1)建立与数据库或者其他数据源的链接
(2)向数据库发送SQL命令
(3)处理数据库的返回结果
《2》JDBC中常用类和接口
连接到数据库(Connection)、建立操作指令(Statement)、执行查询指令(executeQuery)、获得查询结果(ResultSet)等。
1、驱动程序管理类(DriverManager)
DriverManager类是JDBC的管理类,作用于用户和驱动程序之间。它跟踪在可用的驱动程序,并在数据库和相应驱动程序之间建立连接。另外,DriverManager类也处理诸如驱动程序登陆时间限制及登录和跟踪消息的显示事务。对于简单的应用程序,一般程序员需要在此类中直接使用唯一的方法时DriverManager.getConnection()。该方法将建立与数据库的链接。JDBC允许用户调用DriverManager的方法getDriver()、getDrivers()和registerDriver()及Driver的方法connect().
2、声明类(Statement)
Statement对象用于将SQL语句发送到数据库中。实际上有三种Statement对象,它们都作为在给定链接上执行SQL语句的包容器:Statement、PreparedStatement(它从Statement继承而来)和CallableStatement(它从PreparedStatement继承而来)。它们都专用于发送特定类型的SQL语句:
(1)Statement对象用于执行不带参数的简单的SQL语句;Statement接口提供了执行语句和获取结果的基本方法。
(2)PerparedStatement对象用于执行带或不带IN参数的预编译SQL语句;PeraredStatement接口添加处理IN参数的方法;
(3)CallableStatement对象用于执行对数据库已存储过程的调用;CallableStatement添加处理OUT参数的方法。
Statement提供了许多方法,最常用的方法如下:
(1)execute()方法:运行语句,返回是否有结果集。
(2)executeQuery()方法:运行查询语句,返回ReaultSet对象。
(3)executeUpdata()方法:运行更新操作,返回更新的行数。
(4)addBatch()方法:增加批处理语句。
(5)executeBatch()方法:执行批处理语句。
(6)clearBatch()方法:清除批处理语句。
《3》数据库连接类 (Connection)
Connection对象代表与数据库的链接。连接过程包括所执行的SQL语句和在该连接上所返回的结果。一个应用程序可与单个数据库有一个或多个连接,或者可与很多数据库有连接。打开连接与数据库建立连接的标准方法是调用DriverManager.getConnection()方法。
String url="jdbc:mysql://127.0.0.1:3306/jdbc_test";
String user="root";
String password="123456";
DriverManager.getConnection(url,user,password);
《4》 结果集合类 (ResultSet)
ResultSet包含符合SQL语句中条件的所有行记录,并且它通过一套get方法(这些get方法可以访问当前行中的不同列)提供了对这些行中数据的访问。ResultSet.next()方法用于移动到ResultSet中的下一行,使下一行成为当前行。
《5》JDBC编程步骤
(1)加载驱动程序:Class.forName(driverClass)
加载mysql驱动:Class.forName("com.mysql.jdbc.Driver");
加载oracle驱动:Class.forName("oracle.jdbc.driver.OracleDriver");
(2)获得数据库连接
DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/jdbc_test",user,password);
Connection conn=DriverManager.getConnection(url, user, password)
(3)创建Statement对象:conn.createStatement();
preparestatement conn.prepareStatement(Sql);
(4)向数据库发送SQL命令
(5)处理数据库的返回结果(ResultSet类)
(6) 关闭连接
常见的方法介绍:
(1)preparestatement
方 法 名 称 | 功 能 描 述 |
executeQuery() | 执行前面包含参数的动态SELECT语句,并返回一个永远不能为null的ResultSet实例 |
executeUpdate() | 执行前面包含参数的动态INSERT、UPDATE或DELETE语句,并返回一个int型数值,为同步更新记录的条数 |
setInt(int i, int x) | 为指定参数设置int型值,对应参数的SQL类型为INTEGER |
setLong(int i, long x) | 为指定参数设置long型值,对应参数的SQL类型为BIGINT |
setFloat(int i, float x) | 为指定参数设置float型值,对应参数的SQL类型为FLOAT |
setDouble(int i, double x) | 为指定参数设置double型值,对应参数的SQL类型为DOUBLE |
setString(int i, String x) | 为指定参数设置String型值,对应参数的SQL类型为VARCHAR或LONGVARCHAR |
setBoolean(int i, boolean x) | 为指定参数设置boolean型值,对应参数的SQL类型为BIT |
setDate(int i, Date x) | 为指定参数设置java.sql.Date型值,对应参数的SQL类型为DATE |
setObject(int i, Object x)
| 用来设置各种类型的参数,JDBC规范定义了从Object类型到SQL类型的标准映射关系,在向数据库发送时将被转换为相应的SQL类型 |
(2) ResultSet的方法
方法 | 功能描述 |
getInt() | 以int形式获取此ResultSet对象的当前行中指定列值。如果列值为NULL,则返回值是0 |
getFloat() | 以float形式获取此ResultSet对象的当前行的指定列值。如列值是NULL,则返回值是0 |
getDate() | 以Data形式获取ResultSet对象的当前行的指定列值。如列值是NULL,则返回值是null |
getBoolean() | 以boolean形式获取ResultSet对象的当前行的指定列值。如列值是NULL,则返回null |
getString() | 以String形式获取ResultSet对象的当前行的指定列值。如列值是NULL,则返回null |
getObject() | 以Object形式获取ResultSet对象的当前行的指定列值。如列值是NULL,则返回null |
next() | 将指针向下移一行 |
Statement的方法
方 法 名 称 | 功 能 描 述 |
executeQuery(String sql) | 执行指定的静态SELECT语句,并返回一个永远不能为null的ResultSet实例 |
executeUpdate(String sql) | 执行指定的静态INSERT、UPDATE或DELETE语句,并返回一个int型数值,为同步更新记录的条数 |
clearBatch() | 清除位于Batch中的所有SQL语句。如果驱动程序不支持批量处理将抛出异常 |
addBatch(String sql) | 将指定的SQL命令添加到Batch中。String型入口参数通常为静态的INSERT或UPDATE语句。如果驱动程序不支持批量处理将抛出异常 |
executeBatch() | 执行Batch中的所有SQL语句,如果全部执行成功,则返回由更新计数组成的数组,数组元素的排序与SQL语句的添加顺序对应。数组元素有以下几种情况:①大于或等于零的数:说明SQL语句执行成功,为影响数据库中行数的更新计数;②-2:说明SQL语句执行成功,但未得到受影响的行数③-3:说明SQL语句执行失败,仅当执行失败后继续执行后面的SQL语句时出现。如果驱动程序不支持批量、或者未能成功执行Batch中的SQL语句之一,将抛出异常 |
close() | 立即释放Statement实例占用的数据库和JDBC资源 |
connection的方法:
方 法 名 称 | 功 能 描 述 | ||
createStatement() | 创建并返回一个Statement实例,通常在执行无参的SQL语句时创建该实例 | ||
prepareStatement() | 创建并返回一个PreparedStatement实例,通常在执行包含参数的SQL语句时创建该实例,并对SQL语句进行了预编译处理 | ||
prepareCall() | 创建并返回一个CallableStatement实例,通常在调用数据库存储过程时创建该实例 | ||
setAutoCommit() | 设置当前Connection实例的自动提交模式。默认为true,即自动将更改同步到数据库中; | ||
getAutoCommit() | 查看当前的Connection实例是否处于自动提交模式,如果是则返回true,否则返回false | ||
commit() | 将从上一次提交或回滚以来进行的所有更改同步到数据库,并释放Connection实例当前拥有的所有数据库锁定 | ||
rollback() | 取消当前事务中的所有更改,并释放当前Connection实例拥有的所有数据库锁定。 | ||
close() | 立即释放Connection实例占用的数据库和JDBC资源,即关闭数据库连接 |
实例如下:
数据库:
CREATE DATABASE jdbc_test;
DROP TABLE IF EXISTS USER;
CREATE TABLE USER(
id INT(4) NOT NULL PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(20) NOT NULL,
PASSWORD VARCHAR(20) NOT NULL ,
gender CHAR(2),
phone CHAR(11),
description VARCHAR(50)
);
INSERT INTO USER (username,PASSWORD,gender,phone )VALUES('zhang','zhang123','男','12345678910');
INSERT INTO USER (username,PASSWORD,gender,phone )VALUES('lisi','lisi123','男','13551258273');
package com.rl.login;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import com.mysql.jdbc.PreparedStatement;
public class Login {
public static void main(String[] args) {
String url="jdbc:mysql://localhost:3306/jdbc_test";
String user ="root";
String password="123456";
Connection conn=null;
Statement st=null;
PreparedStatement pst=null;
ResultSet rs=null;
try {
/*1 加载数据库驱动*/
Class.forName("com.mysql.jdbc.Driver");//夹包中的Driver类的全路径
/*建立连接*/
conn=DriverManager.getConnection(url, user, password);
/*创间statement或preparestatement对象*/
/*方式一 用statement*/
st=conn.createStatement();
/*通过数据库的连接操作数据库,实现增删改查(使用Statement类)*/
String sql="select * from user where username='zhang'";
rs=st.executeQuery(sql);
/**/
while(rs.next()){
System.out.println(rs.getString("username")+rs.getString("password"));
}
/*方式二 用preparestatement*/
/*通过数据库的连接操作数据库,实现增删改查(使用Statement类)*/
String s=""+"insert into user(username,password) values(?,123)";
pst=(PreparedStatement) conn.prepareStatement(s);
pst.setString(1, "xiaoshuai1");
pst.execute();
//关闭资源 逆序关闭
if(rs!=null){
rs.close();
}
if(st!=null){
st.close();
}
if(pst!=null){
pst.close();
}
if(conn!=null){
conn.close();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
使用preparestatement实现带参数的增,删,改。查
增加:
String s=""+"insert into user(username,password) values(?,123)";
pst=(PreparedStatement) conn.prepareStatement(s);
pst.setString(1, "xiaoshuai1");
pst.execute();
修改:
String s="update user set username=? ,password=? where id=1 ";
PreparedStatement pst=conn.prepareStatement(s);
pst.setString(1, "zhangsan");
pst.setString(2, "123");
pst.execute();
删除:
String s="delete from user where username=? and password=?";
pst=(PreparedStatement) conn.prepareStatement(s);
pst.setString(1, "zhang");
pst.setString(2, "zhang123");
pst.execute();
查询:
String s="select * from user where username=? and password=?";
pst=(PreparedStatement) conn.prepareStatement(s);
pst.setString(1, "zhang");
pst.setString(2, "zhang123");
pst.execute();
自定义一个JDBC工具类:
package com.test.utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public final class JDBCUtils {
private static String driver="com.mysql.jdbc.Driver";
private static String url="jdbc:mysql://localhost:3306/store28";
private static String user="root";
private static String password="root1234";
private JDBCUtils(){}
static {
/**
* 驱动注册
*/
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError(e);
}
}
/**
* 获取 Connetion
* @return
* @throws SQLException
*/
public static Connection getConnection() throws SQLException{
return DriverManager.getConnection(url, user, password);
}
/**
* 释放资源
* @param conn
* @param st
* @param rs
*/
public static void colseResource(Connection conn,Statement st,ResultSet rs) {
closeResultSet(rs);
closeStatement(st);
closeConnection(conn);
}
/**
* 释放连接 Connection
* @param conn
*/
public static void closeConnection(Connection conn) {
if(conn !=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
//等待垃圾回收
conn = null;
}
/**
* 释放语句执行者 Statement
* @param st
*/
public static void closeStatement(Statement st) {
if(st !=null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
//等待垃圾回收
st = null;
}
/**
* 释放结果集 ResultSet
* @param rs
*/
public static void closeResultSet(ResultSet rs) {
if(rs !=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
//等待垃圾回收
rs = null;
}
}
《4》 事务
事务(Transaction)是作为单个逻辑工作单位执行的一系列操作,这些操作作为一个整体一起向系统提交,要么都执行,要么都不执行。
1、事务的特点
(1)原子性:事务是一个完整的操作
(2)一致性:当食物完成时,数据必须处于一致状态
(3)隔离性:对数据进行修改的所有兵法事务彼此隔离
(4)永久性:事务完成后,它对数据库的修改被永久的保存
2、JDBC对事务管理的支持
(1)我们通过提交Commit()或是回退rollback()来管理事务的操作
(2)事务操作默认是自动提交的
(3)可以通过调用setAutoCommit(false)来禁止自动提交。
3、批处理
批处理规范
JDBC升级到2.0后增强了statement接口,使它能够以批处理的方式执行更新操作(select等语句不能使用)。批处理操作指的是一次可以提交多句更新语句,这些更新语句一起执行。批处理相对逐句提交,使性能大幅度提高。它的具体步骤如下:
String URL="jdbc:mysql://127.0.0.1:3306/jdbc_test";
String USER="root";
String PASSWORD="123456";
//1.加载驱动程序
Class.forName("com.mysql.jdbc.Driver");
//2.获得数据库链接
Connection conn=DriverManager.getConnection(URL, USER, PASSWORD);
//设置事务不自动提交
conn.setAutoCommit(false);
//3.通过数据库的连接操作数据库,实现增删改查(使用Statement类)
Statement st=conn.createStatement();
st.addBatch("insert into user(username,password) values('zhang1','456')");
st.addBatch("insert into user(username,password) values('zhang3','4561')");
st.executeBatch();
conn.commit(); //提交
//关闭资源
st.close();
conn.close();
获得原来JDBC事务的模式:
boolean currentTransactionModle = con.getAutoCommit();
设置成事务模式(关闭自动提交):
con.setAutoCommit(false);
Statement stm = con.createStatement();
三个异构的sql语句:
String sql1 = "delete from user where id = 8";
String sql2 = "update user set name='java' where id = 7";
String sql3 = "insert into user(name,password) values('jdbc','jdbc')";
添加到Statement的批量处理缓冲区中:
stm.addBatch(sql1);
stm.addBatch(sql2);
stm.addBatch(sql3);
执行批量更新:
stm.executeBatch();
提交本次批量更新的事务:
con.commit();
回复原来的事务模式:
con.setAutoCommit(currentTransactionModle);
package com.rl.login;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Pag {
public static void main(String[] args) {
Connection conn = getConnection("root", "123456"); // 获取数据库连接
paging(conn,2,3);//方法名调用数据库连接,且定义显示第几行到第几行
releaseConnection(conn);// 释放数据库连接
}
//分页查询
public static void paging(Connection conn,int startIndex,int total){
try{
String sql="select * from user limit ?,?";
PreparedStatement pstmt=conn.prepareStatement(sql);
pstmt.setInt(1, startIndex);
pstmt.setInt(2, total);
ResultSet rs=pstmt.executeQuery();
while(rs.next()){
System.out.print("usernaem"+rs.getString(2));
System.out.println("password:"+rs.getString(3));
}rs.close();
pstmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
//数据库连接
public static Connection getConnection(String user, String pass) {
Connection conn = null;//声明连接对象
String driver = "com.mysql.jdbc.Driver";// 驱动程序类名
String url = "jdbc:mysql://localhost:3306/jdbc_test?"
+ "useUnicode=true&characterEncoding=UTF8";// 防止乱码
try {
Class.forName(driver);// 注册(加载)驱动程序
conn = DriverManager.getConnection(url, user, pass);// 获取数据库连接
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
// 释放数据库连接
public static void releaseConnection(Connection conn) {
try {
if (conn != null)
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.rl.login;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Pag {
public static void main(String[] args) {
Connection conn = getConnection("root", "123456"); // 获取数据库连接
paging(conn,2,3);//方法名调用数据库连接,且定义显示第几行到第几行
releaseConnection(conn);// 释放数据库连接
}
//分页查询
public static void paging(Connection conn,int startIndex,int total){
try{
String sql="select * from user limit ?,?";
PreparedStatement pstmt=conn.prepareStatement(sql);
pstmt.setInt(1, startIndex);
pstmt.setInt(2, total);
ResultSet rs=pstmt.executeQuery();
while(rs.next()){
System.out.print("usernaem"+rs.getString(2));
System.out.println("password:"+rs.getString(3));
}rs.close();
pstmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
//数据库连接
public static Connection getConnection(String user, String pass) {
Connection conn = null;//声明连接对象
String driver = "com.mysql.jdbc.Driver";// 驱动程序类名
String url = "jdbc:mysql://localhost:3306/jdbc_test?"
+ "useUnicode=true&characterEncoding=UTF8";// 防止乱码
try {
Class.forName(driver);// 注册(加载)驱动程序
conn = DriverManager.getConnection(url, user, pass);// 获取数据库连接
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
// 释放数据库连接
public static void releaseConnection(Connection conn) {
try {
if (conn != null)
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}