MySQL之JDBC 一、JDBC是什麼 Java DatabaseConnectivity (java語言連接資料庫) 二、JDBC的本質 JDBC是SUN公司制定的一套介面(interface)。 介面都有調用者和實現者。 面向介面調用、面向介面寫實現類,這都屬於面向介面編程。 三、為什麼要面向 ...
MySQL之JDBC
一、JDBC是什麼
Java DatabaseConnectivity (java語言連接資料庫)
二、JDBC的本質
JDBC是SUN公司制定的一套介面(interface)。
介面都有調用者和實現者。
面向介面調用、面向介面寫實現類,這都屬於面向介面編程。
三、為什麼要面向介面編程
解耦合:降低程式的耦合度,提高程式的擴展力。解耦合可以理解為淘寶的兩個頁面,你在將商品加入訂單的時候出現錯誤,但是不會影響你在主頁瀏覽商品,就是兩個模塊之間的聯繫不那麼緊密,說明兩個模塊內聚就高。
四、為什麼SUN制定一套JDBC介面
因為每一個資料庫產品都有自己獨特的實現原理
五、JDBC編程六步
1、註冊驅動(告訴Java程式要連接哪個品牌的資料庫)
2、獲取連接(表示JVM的進程和資料庫進程之間的通道打開了,這屬於進程之間的通信,使用完後記得關閉通道)。
3、獲取資料庫操作對象(專門執行sql語句的對象)
4、執行SQL語句(DQL,DML...)
5、處理查詢結果集 (只有當第四步執行的是select語句的時候,才有本步)
6、釋放資源(使用完資源後一定要關閉資源,Java和資料庫之間屬於進程間的通信,開啟之後一定要記得關閉)
六、IDEA編寫JDBC連接MySQL
第一種方法:
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
然後就可以寫代碼啦!
七、jdbc連接mysql程式編寫
7.1 第一種註冊驅動方式
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();
}
}
}
}
}
7.2第二種註冊驅動方式
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();
}
}
}
}
}
7.3將連接資料庫的所有信息配置到配置文件中
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();
}
}
}
7.4處理查詢
工具類封裝
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();
}
}
}
7.5登錄註冊案例
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();
}
}
7.6解決sql註入問題
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();
}
}
7.7JDBC實現模糊查詢
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();
}
}