Java DatabaseConnectivity (java語言連線資料庫)
JDBC是SUN公司制定的一套介面(interface)。
介面都有呼叫者和實現者。
面向介面呼叫、面向介面寫實現類,這都屬於面向介面程式設計。
解耦合:降低程式的耦合度,提高程式的擴充套件力。解耦合可以理解為淘寶的兩個頁面,你在將商品加入訂單的時候出現錯誤,但是不會影響你在主頁瀏覽商品,就是兩個模組之間的聯絡不那麼緊密,說明兩個模組內聚就高。
因為每一個資料庫產品都有自己獨特的實現原理
1、註冊驅動(告訴Java程式要連線哪個品牌的資料庫)
2、獲取連線(表示JVM的程序和資料庫程序之間的通道開啟了,這屬於程序之間的通訊,使用完後記得關閉通道)。
3、獲取資料庫操作物件(專門執行sql語句的物件)
4、執行SQL語句(DQL,DML...)
5、處理查詢結果集 (只有當第四步執行的是select語句的時候,才有本步)
6、釋放資源(使用完資源後一定要關閉資源,Java和資料庫之間屬於程序間的通訊,開啟之後一定要記得關閉)
1.進入mysql官網
2.點選下載downloads
3.點選下載社群版[MySQL Community (GPL) Downloads »]
4.選擇jdbc聯結器Connector/J
5.選擇Archives下載5.1版本的(支援的資料庫版本更多)
兩個都可以下載,自己選一個
6.解壓後拿到一個mysql-connector-java-5.1.49.jar的包
7.在idea建立一個工程,點選file
8.點選Java,選擇你解壓後的jar包,不要選擇帶bin的,是二進位制的意思。點選ok就行。
先檢查jar包位置:在目錄裡新建一個資料夾 libs,把jar包複製進去
然後右鍵選擇新建資料夾libs轉成library
然後就可以寫程式碼啦!
public class JDBCTest1 {
private static Statement stat;
private static Connection conn;
public static void main(String[] args) {
//1.註冊驅動
try {
DriverManager.registerDriver(new Driver());
//2.獲取連線
// DriverManager.getConnection("jdbc:mysql://192.168.137.150:3306?" +
// "useUnicode=true&characterEncoding=utf8&useSSL=false","root","123456");
/*
url: 統一資源定位系統
* http/https: 通過網路請求去存取網路上的資源
* jdbc:mysql: 是驅動提供的請求頭
* 請求的地址: 指定mysql的伺服器地址:192.168.254.150
* 埠號: 3306
* useUnicode=true&characterCharset=utf8
*/
String url ="jdbc:mysql://192.168.137.150:3306/bigdata19?useUnicode=true&characterEncoding=utf8&useSSL=false";
String user = "root";
String password = "123456";
conn = DriverManager.getConnection(url, user, password);
System.out.println("與mysql連線成功"+conn);
//獲取資料庫操作物件
stat = conn.createStatement();
//DQL
//ResultSet executeQuery(String sql)
//執行給定的SQL語句,該語句返回單個 ResultSet物件。
//DML(資料庫操作語言,增刪改)
//int executeUpdate(String sql)
//執行給定的SQL語句,這可能是 INSERT , UPDATE ,或 DELETE語句,或者不返回任何內容,如SQL DDL語句的SQL語句。
// 方法的返回值指的是受影響的行數: Affected rows: 1
int count = stat.executeUpdate("insert into dept(deptno,dname,loc) values(50,'教學部','合肥')");
System.out.println(count==1?"資料儲存成功":"資料儲存失敗");
} catch (SQLException e) {
e.printStackTrace();
}finally {
//釋放資源
if (stat!=null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
public class JDBCTest2 {
public static void main(String[] args) {
//註冊驅動的第二種方式
//註冊驅動底層實際上就是用驅動包中對應的類,而驅動包中的類都是class字尾的編譯好的檔案
// 要想直接使用編譯好的類,使用反射來實現。
// 想一想,反射是如何獲取一個類的class檔案物件呢?3種方式
// 1、getClass
// 2、.class
// 3、Class.forName()
Connection conn = null;
Statement stat = null;
try {
//載入驅動
Class.forName("com.mysql.jdbc.Driver");
//建立與資料庫連線的物件
String url = "jdbc:mysql://192.168.137.150:3306/bigdata19?useUnicode=true&characterEncoding=utf8&useSSL=false";
String user="root";
String password="123456";
conn = DriverManager.getConnection(url, user, password);
//獲取與運算元據庫的物件
stat = conn.createStatement();
//編寫sql語句並執行
//增
String sql="insert into dept(deptno,dname,loc) values(60,'行政部','合肥')";
int count2 = stat.executeUpdate(sql);
System.out.println(count2==1?"資料增加成功":"資料增加失敗");
//改
String sql1 ="update dept set dname='研發部'where deptno=60";
int count3 = stat.executeUpdate(sql1);
System.out.println(count3==1?"資料修改成功":"資料修改失敗");
//刪
String sql2 = "delete from dept where deptno=50";
int count4 = stat.executeUpdate(sql2);
System.out.println(count4==1?"資料刪除成功":"資料刪除失敗");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally{
if (stat!=null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
public class JDBCTest3 {
/*
使用組態檔將連線資料庫的相關引數進行儲存,然後在程式碼中使用
使用jdk自身提供的Properties類來載入組態檔
*/
public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
//使用無參構造方法建立Properties類的物件
Properties prop = new Properties();
//使用字元流讀取組態檔
BufferedReader br = new BufferedReader(new FileReader("F:\\software\\IdeaProjects\\bigdata19_mysql\\resource\\jdbc.properties"));
prop.load(br);
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
String user = prop.getProperty("user");
String password = prop.getProperty("password");
//載入驅動
Class.forName(driver);
//獲取連線物件
Connection conn = DriverManager.getConnection(url, user, password);
//獲取資料庫操作物件
Statement stat = conn.createStatement();
//執行sql語句
int count = stat.executeUpdate("insert into dept(deptno,dname,loc) values(70,'教學部','合肥')");
System.out.println(count==1?"資料插入成功":"資料插入失敗");
//釋放資源
if (stat!=null){
stat.close();
}
if (conn!=null){
conn.close();
}
}
}
工具類封裝
public class MySqlTool {
/*
工具類
1.不能讓外界範例化(構造方法私有化)
2.方法必須是靜態
*/
private static Connection conn;
private MySqlTool(){}
public static Connection init(){
try {
Properties prop = new Properties();
//使用字元流讀取組態檔
BufferedReader br = new BufferedReader(new FileReader("F:\\software\\IdeaProjects\\bigdata19_mysql\\resource\\jdbc.properties"));
prop.load(br);
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
String user = prop.getProperty("user");
String password = prop.getProperty("password");
//載入驅動
Class.forName(driver);
//獲取連線物件
conn = DriverManager.getConnection(url, user, password);
}catch (Exception e){
e.printStackTrace();
}
return conn;
}
}
public class JDBCTest4 {
public static void main(String[] args) throws SQLException {
//通過工具類獲取資料庫連線物件
Connection conn = MySqlTool.init();
//獲取資料庫操作物件
Statement stat = conn.createStatement();
//執行sql語句
ResultSet result = stat.executeQuery("select deptno,dname,loc from dept");
//處理查詢結果集
boolean b = result.next();
//將遊標從當前位置向前移動一行。
//如果遊標移動的位置有值,這裡的返回值是true
// if (b){
// //獲取一行中每一列的數值,第一種方式
// String deptno = result.getString(1);
// String dname = result.getString(2);
// String loc = result.getString(3);
// System.out.println("部門編號:"+deptno+",部門名稱:"+dname+",部門地址:"+loc);
//
// }
//正常情況下,一張結果表的行數我們不確定,但是我們知道,當next的結果是false的時候,表示讀取到末尾
while(result.next()){
//獲取一行中每一列的數值,第一種方式
// String deptno = result.getString(1);
// String dname = result.getString(2);
// String loc = result.getString(3);
// System.out.println("部門編號:"+deptno+",部門名稱:"+dname+",部門地址:"+loc);
//第二種方式,根據列名獲取對應的列值
//注意事項:當查詢sql語句中存在起別名的情況時,通過列名獲取列值的時候,使用名字是別名
String deptno = result.getString("deptno");
String dname = result.getString("dname");
String loc = result.getString("loc");
System.out.println("部門編號:"+deptno+",部門名稱:"+dname+",部門地址:"+loc);
}
//注意事項2:同一個結果resultSet物件,只能遍歷一次
System.out.println("=========================");
//再次遍歷,結果不顯示
while(result.next()){
//獲取一行中每一列的數值,第一種方式
// String deptno = result.getString(1);
// String dname = result.getString(2);
// String loc = result.getString(3);
// System.out.println("部門編號:"+deptno+",部門名稱:"+dname+",部門地址:"+loc);
//第二種方式,根據列名獲取對應的列值
//注意事項:當查詢sql語句中存在起別名的情況時,通過列名獲取列值的時候,使用名字是別名
String deptno = result.getString("deptno");
String dname = result.getString("dname");
String loc = result.getString("loc");
System.out.println("部門編號:"+deptno+",部門名稱:"+dname+",部門地址:"+loc);
}
//釋放資源
if (stat!=null){
stat.close();
}
if (conn!=null){
conn.close();
}
}
}
public class JDBCTest5 {
public static void main(String[] args) throws SQLException {
/*
使用jdbc模擬登入註冊案例
1、註冊賬號:往資料庫插入一條資料
2、登入賬號:查詢資料庫
*/
//1.建表user
//建立鍵盤錄入物件
System.out.println("歡迎來到提瓦特大陸,準備好開始冒險了嗎?");
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入旅行者的名字:");
String username = scanner.next();
System.out.println("請輸入密碼:");
String password = scanner.next();
//建立資料庫驅動
// try {
// DriverManager.registerDriver(new Driver());
// } catch (SQLException e) {
// e.printStackTrace();
// }
//
// Connection conn = DriverManager.getConnection();
//直接採用工具類獲取與資料庫的連線物件
Connection conn = MySqlTool.init();
//獲取資料庫操作物件
Statement stat = conn.createStatement();
//編寫sql語句
String sql= "select username,password from user where username='"+username+"'and password='"+password+"'";
//執行sql語句
ResultSet rs = stat.executeQuery(sql);
//處理查詢結果集
boolean b = rs.next();
if (b){
System.out.println("旅行者"+username+",歡迎來到提瓦特大陸!");
}else{
System.out.println("您還未註冊成為旅行者,是否註冊(Y/N)");
String choice = scanner.next();
if ("Y".equals(choice)){
while (true){
System.out.println("請輸入旅行者的名字:");
String new_username = scanner.next();
System.out.println("請輸入密碼:");
String new_password = scanner.next();
System.out.println("請確認密碼:");
String again_password = scanner.next();
if (again_password.equals(new_password)) {
UUID uuid = UUID.randomUUID();//隨機生成uuid
String new_uuid = uuid + "-" + System.currentTimeMillis();
String sql2 = "insert into user(uid,username,password) values('" + new_uuid + "','" + new_username +"','"+ new_password +"')";
int count = stat.executeUpdate(sql2);
if (count == 1) {
System.out.println("註冊成功");
} else {
System.out.println("註冊失敗");
}
break;
}else {
System.out.println("兩次密碼輸入不一致,請重新輸入:");
}
}
}
}
stat.close();
conn.close();
}
}
public class JDBCTest6 {
public static void main(String[] args) throws SQLException {
/*
我們寫完程式後發現,當我們將密碼輸入成1234' or '1'='1這個樣子的時候,發現登入成功
原因:sql在編譯的時候,會將我們輸入的內容存在關鍵字or,會把or當作sql語法關鍵字進行執行
如何解決呢?
這樣的問題,稱之為sql注入的問題
解決的思路就是在sql編譯完後再傳入資料
獲取資料庫操作物件另外一種方式,預編譯的方式
*/
/*
使用jdbc模擬登入註冊案例
1、註冊賬號:往資料庫插入一條資料
2、登入賬號:查詢資料庫
*/
//1.建表user
//建立鍵盤錄入物件
System.out.println("歡迎來到提瓦特大陸,準備好開始冒險了嗎?");
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入旅行者的名字:");
String username = scanner.nextLine();
System.out.println("請輸入密碼:");
String password = scanner.nextLine();
//建立資料庫驅動
// try {
// DriverManager.registerDriver(new Driver());
// } catch (SQLException e) {
// e.printStackTrace();
// }
//
// Connection conn = DriverManager.getConnection();
//直接採用工具類獲取與資料庫的連線物件
Connection conn = MySqlTool.init();
// //獲取資料庫操作物件
// Statement stat = conn.createStatement();
//
// //編寫sql語句
// String sql= "select username,password from user where username='"+username+"'and password='"+password+"'";
// //執行sql語句
// ResultSet rs = stat.executeQuery(sql);
//這裡的問號相當於一個預留位置,為了後面傳值
String sql = "select username,password from user where username=? and password=?";
//建立預編譯資料庫操作物件
PreparedStatement pps = conn.prepareStatement(sql);
//將sql中的預留位置附上值
//第一個參數列示給第幾個問號傳值,第二個參數列示具體的值,序號從1開始
pps.setString(1,username);
pps.setString(2,password);
//執行sql語句
ResultSet rs = pps.executeQuery();
//處理查詢結果集
boolean b = rs.next();
if (b){
System.out.println("旅行者"+username+",歡迎來到提瓦特大陸!");
}else{
System.out.println("您還未註冊成為旅行者,是否註冊(Y/N)");
String choice = scanner.next();
if ("Y".equals(choice)){
while (true){
System.out.println("請輸入旅行者的名字:");
String new_username = scanner.next();
System.out.println("請輸入密碼:");
String new_password = scanner.next();
System.out.println("請確認密碼:");
String again_password = scanner.next();
if (again_password.equals(new_password)) {
UUID uuid = UUID.randomUUID();//隨機生成uuid
String new_uuid = uuid + "-" + System.currentTimeMillis();
String sql2 = "insert into user(uid,username,password) values('" + new_uuid + "','" + new_username +"','"+ new_password +"')";
int count = pps.executeUpdate(sql2);
if (count == 1) {
System.out.println("註冊成功");
} else {
System.out.println("註冊失敗");
}
break;
}else {
System.out.println("兩次密碼輸入不一致,請重新輸入:");
}
}
}
}
pps.close();
conn.close();
}
}
public class JDBCTest7 {
public static void main(String[] args) throws SQLException {
//獲取資料庫連線物件
Connection conn = MySqlTool.init();
//獲取預編譯資料庫操作物件
String sql="select uid,username,password from user where username like ?";
PreparedStatement pps = conn.prepareStatement(sql);
pps.setString(1,"%bfy%");
//執行sql語句
ResultSet rs = pps.executeQuery();
//處理查詢結果集
while (rs.next()){
String uid=rs.getString(1);
String username=rs.getString(2);
String password=rs.getString(3);
System.out.println(uid+','+username+','+password);
}
pps.close();
conn.close();
}
}