什麼是jdbc:
JDBC(Java DataBase Connectivity)就是Java數據庫連接,說白了就是用Java語言來操作數據庫。原來我們操作數據庫是在控制檯使用SQL語句來操作數據庫,JDBC是用Java語言向數據庫發送SQL語句。
jdbc原理:
早期SUN公司的天才們想編寫一套可以連接天下所有數據庫的API,但是當他們剛剛開始時就發現這是不可完成的任務,因爲各個廠商的數據庫服務器差異太大了。後來SUN開始與數據庫廠商們討論,最終得出的結論是,由SUN提供一套訪問數據庫的規範(就是一組接口),並提供連接數據庫的協議標準,然後各個數據庫廠商會遵循SUN的規範提供一套訪問自己公司的數據庫服務器的API出現。SUN提供的規範命名爲JDBC,而各個廠商提供的,遵循了JDBC規範的,可以訪問自己數據庫的API被稱之爲驅動JDBC是接口,而JDBC驅動纔是接口的實現,沒有驅動無法完成數據庫連接!每個數據庫廠商都有自己的驅動,用來連接自己公司的數據庫。
jdbc核心類:(先混個眼熟吧)
DriverManger Connection Statement ResultSet
DriverManger(驅動管理器)的作用有兩個:
l 註冊驅動:這可以讓JDBC知道要使用的是哪個驅動;
l 獲取Connection:如果可以獲取到Connection,那麼說明已經與數據庫連接上了。
Connection對象表示連接,與數據庫的通訊都是通過這個對象展開的:
l Connection最爲重要的一個方法就是用來獲取Statement對象;
Statement是用來向數據庫發送SQL語句的,這樣數據庫就會執行發送過來的SQL語句:
l void executeUpdate(String sql):執行更新操作(insert、update、delete等);
l ResultSet executeQuery(String sql):執行查詢操作,數據庫在執行查詢後會把查詢結果,查詢結果就是
ResultSet;
ResultSet對象表示查詢結果集,只有在執行查詢操作後纔會有結果集的產生。結果集是一個二維的表格,有行有列。操作結果集要學習移動ResultSet內部的“行光標”,以及獲取當前行上的每一列上的數據:
l boolean next():使“行光標”移動到下一行,並返回移動後的行是否存在;
XXX getXXX(int col):獲取當前行指定列上的值,參數就是列數,列數從1開始,而不是0。怎麼用:
NO.1 導包:數據庫的驅動包:mysql爲例,mysql-connector-java-5.1.13-bin.jar
NO.2 準備四大參數:driverClassName、url、username、password
No.3 註冊驅動類 :Class.froName(driverClassName);搞定
No.4 獲取連接 : DriverManger.getConnection(url,username,password);
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import org.junit.Test;
public class DemoTwo {
@Test
public void fun1() throws ClassNotFoundException, SQLException {
String driverClassName = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/demo";
String user = "root";
String password = "123";
Class.forName(driverClassName);
//得到連接
Connection connection = DriverManager.getConnection(url, user, password);
//創建聲明
Statement statement = connection.createStatement();
// 執行查詢操作
String sqlString = "select * from bm_list";
ResultSet rs = statement.executeQuery(sqlString);//返回結果集。
/*
* rs內部有一個遊標:
* 光標默認位置是第一行的前面
* rs.next()把光標位置向下移動一行。next()方法返回的boolean表示是否有這一行。
* 可利用這個方法對結果集進行遍歷,前提是你需要知道字段名,或者其屬性。
*/
//rs.next();
// Object o = rs.getObject(1);
// System.out.println(o);
// String qq = rs.getString("qq");
// String name = rs.getString("real_name");
/* 這兩種方法都可以對其進行遍歷。
for (int i = 0; rs.next(); i++) {
String qq = rs.getString("qq");
String name = rs.getString("real_name");
System.out.println("姓名:"+name+" qq:"+qq);
}
while (rs.next()) {
String qq = rs.getString("qq");
String name = rs.getString("real_name");
System.out.println("姓名:"+name+" qq:"+qq);
}
*/ 如果列名不知道可以用如下方法獲取。
//獲取結果集列數和行數!
rs.last();//將光標設置到最後一行
int row = rs.getRow();//獲取行數
rs.beforeFirst();//將光標移到初始位置
//獲取結果列的列數。
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount(); //獲取結果集列數
String columnName = rsmd.getColumnName(1); //獲取第一列的名稱
System.out.println("共有"+row+"行數據,並且有"+columnCount+"列,第1列列名是"+columnName);
//獲取所有數據
while (rs.next()) {
for (int i = 1; i <= columnCount; i++) {
//String cName = rsmd.getColumnName(i);//獲得每列的名稱。
Object o = rs.getObject(i);
System.out.print(o + " ");
}
}
/*
* 資源關閉順序:
* 想得到的後關閉!
*/
rs.close();
statement.close();
connection.close();
}
}
如何防止SQL攻擊:
preparedStatement(預編譯聲明)
查詢api可以知道preparedStatement接口是接口Statement的子接口,使用它有以下好處:
l 防止SQL攻擊;
l 提高代碼的可讀性,以可維護性;
l 提高效率。
使用方法及代碼規範化:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import org.junit.Test;
public class MyPreparadStatementTest {
/**
* 使用preparadStatement(預編譯聲明)進行的增刪改查!
*/
@Test
public void insert() {
Connection con = null;
PreparedStatement pStatement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "123");
//使用sql模板,問好對應下面setXXX();的第一個參數,從1開始。。
String sql = "insert into test1 values(?,?,?,?)";
pStatement = con.prepareStatement(sql);
pStatement.setInt(1, 3);
pStatement.setString(2, "吾王");
pStatement.setString(3, "18");
pStatement.setString(4, "898989898");
//調用execute(),可以執行添加、修改、刪除操作。
pStatement.executeUpdate();
} catch (Exception e) {
throw new RuntimeException(e);
}finally{
try {
if(pStatement != null)pStatement.close();
if(con != null)con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Test
public void update() {
Connection con = null;
PreparedStatement pStatement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "123");
String sql = "update test1 set name = ?,qq = ?,age = ? where id = ?";
pStatement = con.prepareStatement(sql);
pStatement.setString(2, "898989898");
pStatement.setString(1, "saber");
pStatement.setString(3, "16");
pStatement.setInt(4, 3);
pStatement.executeUpdate();
} catch (Exception e) {
throw new RuntimeException(e);
}finally{
try {
if(pStatement != null)pStatement.close();
if(con != null)con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Test
public void delete() {
Connection con = null;
PreparedStatement pStatement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "123");
String sql = "delete from test1 where id = ?";
pStatement = con.prepareStatement(sql);
pStatement.setInt(1, 1);
pStatement.executeUpdate();
} catch (Exception e) {
throw new RuntimeException(e);
}finally{
try {
if(pStatement != null)pStatement.close();
if(con != null)con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Test
public void query() {
Connection con = null;
PreparedStatement pStatement = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "123");
String sql = "select * from test1 where name = ? or age = ?";
pStatement = con.prepareStatement(sql);
pStatement.setString(1, "saber");
pStatement.setString(2, "18");
rs = pStatement.executeQuery();
//獲取列。。遍歷結果集
ResultSetMetaData metaData = rs.getMetaData();
int count = metaData.getColumnCount();
while (rs.next()) {
for (int i = 1; i <= count; i++) {
Object object = rs.getObject(i);
System.out.println("查詢結果是:"+object);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}finally{
try {
/*
* 資源關閉順序:
* 先得到的後關閉!
* 一定要關閉資源!
*/
if(rs != null)rs.close();
if(pStatement != null)pStatement.close();
if(con != null)con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}