一.Java基礎語法
1.Jdk環境搭建
- (1)JDK是Java開發環境集【Java Development Kit】
①JAVA_HOME:填寫Jdk的安裝目錄
②Path:在變量值最後輸入%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
③CLASSPATH :.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar
檢驗是否配置成功 :運行cmd 輸入 java -version (java 和 -version 之間有空格) - (2)Jre是Java運行環境【Java runtime environment】
- (3)Ivm是Java虛擬機【Java Virtual Machine】
★ 三者關係如下:JDK > JRE > JVM2.
2.入門案例
public class Demo {
public static void main(String[] args) {
System.out.println("Hello-World!");
}
}
3.Java數據類型
(1)基礎數據類型(四類八種)不能爲null
- 整型 : 【byte short int long 】
- 浮點類型 【單精度 float】 【雙精度 double】
- 布爾類型 【boolean true和false(默認)】
- 字符類型 【char】
基本數據類型之間的比較:
基本數據類型 大小 最小值 最大值 包裝數據類型
byte 1 個字節(1*8 位) -2^7 2^7 - 1 Byte
short 2 個字節(2*8 位) -2^15 2^15-1 Short
int 4 個字節(4*8 位) -2^31 2^31-1 Integer
long 8 個字節(8*8 位) -2^63 2^63 - 1 Long
boolean - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Boolean
char 2 個字節(2*8 位) 0 2^16 - 1 Character
float 4 個字節(4*8 位) 1.4E - 45 3.4028235E38 Float
double 8 個字節(8*8 位) 4.9E – 324 1.7976931348623157E308 Double
(2)引用數據類型可以=null
-
類 (Class)
預定義的類:官方定義好的類,拿來就可以使用,無需再次創建
自定義的類:官方沒有定義的類,只能夠自己創建 -
接口 (Interface)
預定義的接口:官方定義好的接口,拿來就可以使用,無需再次創建
自定義的接口:官方沒有定義的類,只能夠自己創建 -
數組 (Array)
-
枚舉 (Enumeration)
4.關鍵字
- (1)用於數據類型
int 、 byte 、 short 、 long 、 char 、 boolean 、 float 、 double 、 true 、 false 、 new 、 void 、 instanceof
- (2)用於語句
break 、 continue 、 switch 、 case 、 default 、 catch 、 do 、 while 、 else 、 if 、 for return 、 try 、 finally 、 throw 、 this 、 super
- (3)用於修飾
private 、 public 、 static 、 protected 、 final 、 abstract 、 native 、 synchronized
- (4)用於方法、類、接口、包和異常
class 、 extends 、 implements 、 interface 、 package 、 import 、 throws
5.標識符
- 標識符由字母、數字、下劃線“_” 組成,數字不能開頭。
- 不能把【 關鍵字】 和 【保留字】 作爲標識符。
- 標識符沒有長度限制。
- 標識符對大小寫敏感。
命名規範:
- 類/接口:首字母大寫,多個單詞首字母都大寫 eg:ClassName
- 包: 倒域名 全部小寫字母 以實心點(.)分開 eg:javabs.entity
- 方法/函數名稱:一個單詞小寫,多個單詞從第二個開始首字母大寫(第一個依舊小寫,有括號)eg:getSum()
- 變量(臨時存儲數據的作用):一個單詞小寫,多個單詞從第二個開始首字母大寫(第一個依舊小寫,最後沒有括號)eg:getElementById
- 常量:全部大寫,多個單詞以下劃線分割eg:MY_CLORE
6.註釋
單行註釋
- // 被註釋的內容
- 快捷鍵:ctrl+/ 或 ctrl+shift+C
多行註釋
- /* 被註釋的內容 */
- 快捷鍵:ctrl+shift+/
文檔註釋
- /** 被註釋的文檔 */
- 快捷鍵:Alt+shift+J
7.變量和常量
變量
成員變量/全局變量:定義在類中,不在方法、語句、代碼塊中
public class Demo{
int age;
}
局部變量:定義在方法中或語句中、代碼塊中
public calss Dmeo{
public static void main(string []arge){
int age;
System.out,println(age);
}
}
成員變量和局部變量的區別?
- 成員變量有默認初始化值
int的初始化值爲0
boolean的初始化值爲false - 局部變量沒有初始化值,在使用之前必須得進行賦值操作
常量
- 不變的量
- 得使用final去修飾變量
8.運算符
- 算術運算符【+ - * / %】
- 比較運算符【< > >= <= == !=】
- 邏輯運算符【或\ 與& 非! 短路與&& 短路或】
– \ 或:一true則true 都false則false 第一個判斷條件不管成立與否,後面的條件條件都會進行執行
– 短路或:一true則true 都false則false 第一個條件成立,後面的條件不再執行返回true
– &與 :都true則true 一false則false 第一個判斷條件不管成立與否,後面的條件條件都會進行執行
– 短路與:都true則true 一false則false 第一個條件不成立,後面的條件不再執行,返回false - 三元/三目元運算符條件表達式 ? 滿足:不滿足
例如
public class Demo {
public static void main(String[] args) {
boolean a = 20 > 15 ? true: false;
System.out.println(a);
}
}
- 移位運算符
- 賦值運算符
在Java中,單等於號表示賦值,等於號右邊的值賦值給等於號左邊的,雙等於表示等於
9.語句
選擇結構語句
- if
單支語句 if ( ) { }
雙支語句 if ( ) { }else if ( ){ }else if ( ){ }
多支語句if ( ) { }else { }
- switch
switch(①){ case xxx : break; default{} }
①的意思是:條件 該條件的類型可以是 整數 在JDK1.7版本後,可以使用字符串作爲類型
public class Demo {
public static void main(String[] args) {
System.out.println("請輸入分數:");
Scanner sc = new Scanner(System.in);
int score = sc.nextInt();
switch (score/10){
case 10:
case 9:
System.out.println("A");
break;
case 8:
System.out.println("B");
break;
case 7:
case 6:
System.out.println("C");
break;
}
System.out.println("分數爲:" + score);
}
}
循環結構語句
-
while循環
先判斷後循環 -
for循環
i++ 先運算後賦值
++i 先複製後運算
public class Demo {
public static void main(String[] args) {
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
- do while循環
先循環後判斷
10.方法
描述對象具備的功能,就是方法
-
格式:
權限修飾符 返回值類型 方法名稱(參數1 的類型 參數1 ,參數2的類型 參數2 ){
執行語句;
return; 結果值
} -
權限修飾符
public 公共的
private 私有的
default 默認的
protected 受保護的 -
返回值類型
如果有類型,請參照數據類型結構圖
如果沒有類型,使用void -
方法名稱
命名在符合命名規範的前提下 見面知意即可 eg:getSum() 求和 -
返回值
如果有返回值類型,使用return關鍵字
@Test
public viod getSum(int x,int y){
int z = x + y;
return z;
}
如果沒有返回值類型,省略return關鍵字
@Test
public void print99(){
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(i * j);
}
System.out,println();
}
}
-
重載 overload
方式一:方法名稱相同,參數個數不同
方式二:方法名稱相同,返回值類型不同 -
Junit單元測試的方法 使用細節
1.在方法名稱上 存在 @Test—— 別忘記導包
2.測試方法的權限修飾符 必須是 public
3.測試方法的返回值類型 必須是 void
4.測試方法的方法名稱 隨便起名
5.測試方法的方法參數 必須爲空 -
數組
數組是一個容器,也是一個數據存儲結構
一維數組
二維數組
數組的使用
1.存入數組
(1)前提:有剩餘的長度
(2)直接對剩餘的長度進行分別賦值操作
2.從數組中取出元素
(1)單個取出,制定數組中的索引值位置
(2)循環操作
3.如何排序
(1)Arrays.sort(arr);
@Test
public void print(int [] arr){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ", ");
}
System.out.println();
}
@Test
public void bubbleSort(){
int arr [] = {2,55,69,78,41,58};
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1; j++) {
if (arr[j] > arr[j + 1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
print(arr);
}
(1)如何找出最值
public class Demo{
public static void main(String[] args) {
int arr [] = {12,56,99,82,36,555};
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] > max){
max = arr[i];
}
}
System.out.println(max);
}
}
二 面向對象
概述
- Java語言是一種面向對象的程序設計語言,而面向對象思想是一種程序設計思想。我們在面向對象思想的指引下,
使用Java語言去設計、開發計算機程序。 這裏的對象泛指現實中一切事物,每種事物都具備自己的屬性和行爲。面
向對象思想就是在計算機程序設計過程中,參照現實中事物,將事物的屬性特徵、行爲特徵抽象出來,描述成計算 機事件的設計思想。
它區別於面向過程思想,強調的是通過調用對象的行爲來實現功能,而不是自己一步一步的去 操作實現。 - 面向過程:強調步驟。
- 面向對象:強調對象
- 類:是一組相關屬性和行爲的集合
- 屬性:該事物的狀態信息
- 行爲:該事物能夠做什麼
類與對象的關係
- 類是對一類事物的描述,是抽象的
- 對象是一類事物的實例,是具體的
- 類是對象的模板,對象是類的實體
三種特性
封裝
- 原則:將屬性隱藏起來,若需要訪問某個屬性,提供公共方法對其訪問
- 步驟:使用private關鍵字來修飾成員變量 ; 對需要訪問的成員變量,提供對應的一對一的get××× 和set×××方法
- 封裝操作private的含義
private是一個權限修飾符,代表最小權限
可以修飾成員變量和成員方法
被private修飾後的成員變量和成員方法,只在本類中才能訪問 - 封裝優化this方法
使用 this 修飾方法中的變量,解決成員變量被隱藏的問題
繼承
- 類的繼承描述的是類與類之間的關係
繼承關係–通過已有的類,創建出新類的機制 - 已有的類我們叫父類【超類】 創建出來的新類我們叫子類
- 通過extends關鍵字完成一個繼承關係
具體格式:
訪問修飾符 class 子類類名 extends 父類類名{
} - java中只支持單繼承【一個類只能由一個父類】
- 充當父類的java類絕對不能用final關鍵字修飾【被final關鍵字修飾的類是沒有子類的】
多態
- 前提是繼承
- 格式:
父類 對象名稱 = new 子類名稱(); //父類與子類有繼承關係
接口名稱 對象名稱 = new 實現類名稱();
class Dog extends Animal{
//狗 是 狗
Dog d = new Dog();
//狗 是 動物
Animal d = new Dog();
}
抽象
- 將沒有方法主體的方法稱爲抽象方法
- 權限修飾符
public
protected
private
default - 抽象方法必須在抽象類中
- 抽象類可以沒有抽象方法
- 抽象方法不能new 不是子類不能new
- 如果子類繼承了父類,就必須繼承抽象方法,必須重寫方法體
- 抽象類不能new的原因:
因爲有抽象方法,沒有構造方法
接口
抽象類 接 口
構造方法 有 沒有
成員變量 有普通成員變量 沒有
普通方法 可以包含非抽象的 不可包含
訪問類型 可以是public protected 只能是public(默public abstract)
靜態方法 可以 不可以
靜態成員變量 訪問類型可以任意 接口中定義的變量只能是public static final類型
- 一個類可以實現多個接口
- 一個類只可以繼承一個類(單繼承)
- 一個類只可以繼承一個類,並且實現多個接口
- 一個接口可以繼承另一個接口
- 一個接口可以繼承多個接口
- 一個接口不能繼承類
- 一個接口不可以實現另一個接口
關鍵字
this 當前的
super 父類的
static 靜態化的
-
優點
1.可以使用【類名 方法名稱】進行調用,不必再創建對象
2.優於構造函數先執行------> 任何一個類都會有一個默認的無參數的構造方法
構造方法/函數的作用:爲了使類可實例化【就是爲了可以new】
3.靜態成員被所有對象所共享(靜態數據達到成爲共享數據)
4.隨着類的加載而加載(也就是說類運行了,靜態成員也就跟隨運行了) -
缺點
1.訪問出現侷限性 只能訪問靜態
2.靜態成員的生命週期過長
3.不可以與this | super關鍵字同用
(1)因爲this代表使當前類對象,而靜態存在時,有可能沒有對象
(2)因爲super代表的是父親對象,而靜態存在時,有可能沒有對象,而且靜態優先於對象存在
4.靜態方法只能訪問靜態成員,非靜態方法既可以訪問靜態又可以訪問非靜態
final 最終化的
構造方法
- 作用:是爲了給對象進行初始化而存在的
沒有構造方法就不能new - 當你沒有寫構造方法,jvm會自動給你加上一個無參數的構造方法
成員變量or局部變量
public class Car{
String color; //成員變量
public void driver(){
int speed = 80; //局部變量
System.out.println("時速:" + speed);
}
}
- 在類中的位置不同 ★
成員變量:類中,方法外
局部變量:方法中或者方法聲明上(形式參數) - 作用範圍不一樣 ★
成員變量:類中
局部變量:方法中 - 初始化值的不同 ★
成員變量:有默認值【int爲0 boolean爲false】
局部變量:沒有默認值 必須先定義,賦值,最後使用 - 在內存中的位置不同 瞭解
成員變量:堆內存
局部變量:棧內存 - 生命週期不同 瞭解
成員變量:隨着對象的創建而存在,隨着對象的消失而消失
局部變量:隨着方法的調用而存在,隨着方法的調用完畢而消失
補: - 如果private私有化了,就一定能夠得提供公有方法 Getter and Setter方法 string是類
- equals看的是漢字是否一樣
- == 看的是兩方漢字的地址值是否一樣
三.集合
單列集合 collection / 表示爲泛型
-
List【線程不安全性】
-
派生類
ArrayList 查詢塊、增刪慢
LinkedList 查詢慢、增刪塊
Vector 查詢慢、增刪更慢 【線程安全性】 -
特點
使用線性存儲
可以重複添加
存入與取出順序一致 -
Set【線程不安全性】
-
派生類
HashSet
TreeSet -
特點
使用哈希表存儲
不可以重複添加
存入與取出順序不一致 -
爲什麼不可以重複添加數據?
- 加入Set裏面的元素必須定義equals()方法以確保對象的唯一性
- set插入數據時,先比較hashCode
1.如果hashCode相同纔會比較equals,equals相同,則兩個對象相同,不能插入,equals不同,可以插入;
2.如果hashCode不同,就直接插入了,兩個對象hashCode不相等,他們equals一定是false
-
接口:繼承了Iterable,迭代器
-
foreach
雙列集合 Map /表示爲泛型 key value鍵值對
泛型:限定類型,泛型中的不可以使用基礎數據類型,只能使用引用數據類型
-
HashMap 【線程不安全性】
- 迭代器iterator使用
三種迭代器方法- keyset()
先獲取鍵
通過鍵獲取值
打印值 能打印鍵 - entryset()
可以獲取鍵
也可以獲取值
都可以打印 - values()
直接獲取值
打印值 不能打印鍵
- keyset()
- 迭代器iterator使用
-
都需要使用迭代器
Iterator it = Set.iterator();
while (it.hasNext()){
it.next();
}
-
TreeMap 【線程不安全性】
-
HashTable【線程安全性】
properties 既是io流 也是集合 -
list與Map不能轉換
-
set與Map可以轉換 共同點有【都是線程不安全性 都是接口 都間接的繼承了Iterable這個接口】
-
在雙列集合接口中,並沒有繼承Iterable,意味着Map集合中沒有迭代器
工具類 Collections
Collections是專門用於對Collection集合進行操作的工具類,它提供了一些便捷的方法,如排序,查找,求最值等等
四. 異常
Error錯誤
-
CPU中央處理器
-
單核處理器(並行)
-
多核處理器(併發線程)
-
如果是單核處理器,就不是同時在執行
運行速度非常快,快到以爲是同時
-
多核處理器真的可以同時在執行,處理器多了可以分開執行
-
Exception異常
系統定義好的/官方的預定義
- 編譯時異常
- 寫代碼過程中,寫完未執行時,報錯
- 運行時異常
- 已寫完後,已經開始運行時,報錯
自定義異常
- 導致原因
算數異常
數組異常
圖片異常
圖標異常
音頻異常
io異常 - 解決方案
1.捕捉異常
try{
catch{
finally{
}
2.聲明式異常
在方法名稱的括號後加上一個 throws - eg:
ClassNotFoundException 找不到類異常
NoClassDefoundError 沒有定義類的異常
ArrayIndexOutOfBoundsException 數組角標超出範圍的異常
NullPointerException 空指針異常
★ RuntimeException 運行時異常
五.多線程
進程和線程定義和關係:
- 進程(表面):正在進行中的程序(任務管理器 ctrl+_alt+del)
- 線程(內在):是存在進程中的一個執行單元(沒有箱子,但是有組件)
- 進程和線程的關係:每一個進程中至少存在一個線程,也可擁有多個線程
多線程
- 並行:針對於多個線程,在同一時間內發生 (重在指一段時間內)
- 併發:針對於多個線程,在同一時刻發生 (指的是同時)
線程調度 【Java的繼承機制:僅單繼承,不可以多繼承】
- 分時調度
- 按方式調度
設置線程:Run()方法
開啓線程:Start()方法
實現多線程的三種方法
-
繼承java.lang.Thread類【extend Thread】
-
實現java.lang.Runnable接口(重寫Run方法)【implements Runnable】
-
實現Callable接口(接口中一定不允許存放變量,不能夠存放常量)
-
Thread和Runnable的區別(實現接口比繼承類的優勢)
①可以避免單繼承的侷限性【若一個類繼承 Thread的話,則不適合資源共享;但若實現 Runnable 接口的話,就很容易實現資源共享】②適合多個相同的程序代碼的線程去處理同一個資源
③增強程序的擴展性,降低耦合性(避免牽一髮而動全身)【代碼可以被多個線程共享,代碼和數據獨立】
④線程池只能放入實現 Runnable 或 Callable 類的線程,不能直接放入繼承 Thread 的類
線程的狀態可以分爲5種:
- 新建new:
當一個線程新建出來,例如 Thread thread = new Thread() 此時,線程狀態就是new。 - 可運行Runnable:
當新建的線程調用start方法,線程狀態就變爲runnable,此時線程隨時等待CPU調度執行,但未執行。 - 正在運行running:
CPU開始調度執行此線程,需要注意的是,線程running狀態只能從runnable轉換過來。 - 阻塞blocked:
當處於正在運行的線程因爲一些情況放棄爭奪CPU資源,此時就進入了阻塞狀態,如果線程需要再次運行必須先轉變成runnable狀態。 - 死亡dead:
線程運行完成或出現異常,線程S生命週期結束。
線程安全、線程同步、線程互斥、線程通信
- 線程安全:
是指多線程執行同一份代碼每次執行結果都和單線程一樣。 - 線程同步:
對臨界區的共享數據,A線程去操作數據,並且需要另一線程B的操作才能繼續完成,這種線程之間協作的就是線程同步。 - 線程互斥:
對臨界區的共享數據,兩個線程都有修改情況,如果沒有加鎖或cas等的操作會造成數據混亂異常,這種就是線程互斥。 - 線程通信:
可以認爲是線程同步的擴展,因爲wait/notify必須獲取了對象鎖才能使用,通過wait/notify這種方式實現兩個線程的等待喚醒。
線程同步的7種方式
- synchronized同步方法。如果是普通方法會鎖住這個對象,如果是靜態方法鎖住的是整個類。
- synchronized同步代碼塊。
- volatile修飾變量。
- 重入鎖ReenreantLock。實現了Lock接口,可重入,但效率低。
- ThreadLocal線程級別的變量共享。
- 阻塞隊列LinkedBlockingQueue。主要通過synchronized的put、take實現。
- 原子變量。
線程狀態轉換
- 進程的基本狀態
- 新建狀態:創建一個線程對象
- 就緒狀態:等待系統分配處理器
- 運行狀態:佔有處理器正在運行
- 等待狀態(阻塞狀態):等待某個事件的完成
- 進程狀態變化
- 新建態 -------> 就緒態 【進程創建】
- 運行態 -------> 等待態 【等待某個事件發生】
- 等待態 -------> 就緒態 【等待事件完成】
- 就緒態 -------> 運行態 【進程調度】
- 運行態 -------> 就緒態 【時間片完成】
六.IO流
IO流大致分類
以Stream結尾的爲字節流,以Writer或者Reader結尾的爲字符流
所有的輸入流都是抽象類IuputStream或者是抽象類Reader的子類,所有的輸出流都是抽象OutputStream或者是抽象類Writer的子類。字符流能實現的功能字節流都能實現,但字節流能實現的功能字符流不一定能實現。如:圖片,視頻等二進制文件,只能使用字節流讀寫。
字節流
- 輸入流 InputStream
- 字節流 FileInputStream
- 字節緩衝流 BufferedInputStream
- 輸出流 OutputStream
- 字節流 FileOutputStream
- 緩衝字節流 BufferedOutputStream
字符流
- 字符流 Reader
- 字符流 FileReader
- 緩衝字符流 BufferedReader
- 轉換流 InputStreamReader
- 字符流 Writter
- 字符流 FileWriter
- 緩衝字符流 BufferedWriter
- 轉換流 OutputStreamWriter
public static void main(String[] args) throws Exception {
InputStream in = new FileInputStream("C:\\Users\\學生29\\Desktop\\a.jpg"); //該資源的位置
OutputStream out = new FileOutputStream("E:\\a.jpg"); //到哪裏去 文件名稱
long begintime = System.currentTimeMillis();
int len = 0; //局部變量 沒有默認的初始化值
byte[] b = new byte[1024 * 10]; //b表示緩衝區
while ((len = in.read(b)) != -1){ //read(b)輸入方法
out.write(b,0,len); //write(b,0,len)輸出方法
}
long endtime = System.currentTimeMillis();
long time = endtime - begintime;
System.out.println("消耗的時間爲:" + time);
out.close(); //關閉流 【先開後關,後開先關】
in.close();
}
RandomAccessFile
- 這個類的實例支持對隨機存放文件的讀和寫
- 隨機訪問
- 操作文件
- 既可以讀又可以寫
- 內部維護了用於存儲數據的byte數組
- 提供了對數組操作的文件指針
- 文件指針可以通過getFilePointer方法獲取,並通過seek方法設置
- InputStream有個方法read()可用於讀取內容
int len = 0;
while((len = in.read()) != -1){
out.write(len);
}
- 在指定位置
- 創建一個文件
- 讀取txt的內容
- 將讀取的內容輸出道新文件
int b = in.read();
if(b == -1){
break;
}
字節流和字符流的區別
字節流不是漢字的內容,而是字母、數字等,字符流則是漢字,(簡體和繁體);
字節流按字節讀寫,而字符流按字符讀寫;
字節流是以stream結尾,而字符流是以reader和writer結尾;
字節流採用ASCII編碼,而字符流採用Unicode編碼;
字節流默認不使用緩衝區,字符流使用緩衝區。
七.Jdbc
創建過程
/**
* 前提:
* 想使用jdbc連接:導入一個jar包
* |-----------mysql-connector-java-5.1.47------------|
* 1.註冊驅動
* 2.通過驅動管理(DrviverManage)獲取連接class.forName(url user password)
* 3.通過連接(connection)對象創建statement(陳述 聲明)對象
* 4.通過statement對象執行SQL語句 execute執行
* 5.操作結果集對象ResultSet
* 6.釋放資源
*/
- 增刪改一個套路【比較繁瑣】
//全局變量
private static String url = "jdbc:mysql://localhost:3306/bookmanage";
private static String driverClassName = "com.mysql.jdbc.Driver";
private static String username = "root";
private static String password = "root";
@Test
public void addJdbc(){
try {
Class.forName(driverClassName);
Connection con = DriverManager.getConnection(url, username, password);
Statement statement = con.createStatement();
statement.execute("insert into dept(id,name,location) values (100,'學術部','深圳')");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void delJdbc(){
try {
Class.forName(driverClassName);
Connection con = DriverManager.getConnection(url, username, password);
Statement statement = con.createStatement();
String sql;
sql="delete from dept where id=100";
statement.execute(sql);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void editJdbc(){
try {
Class.forName(driverClassName);
Connection con = DriverManager.getConnection(url, username, password);
Statement statement = con.createStatement();
statement.execute("update dept set location='上海' where id = 33");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
- 查詢
@Test
public void listJdbc(){
try {
Class.forName(driverClassName);
Connection con = DriverManager.getConnection(url, username, password);
Statement statement = con.createStatement();
String sql;
sql="select * from dept";
ResultSet rs = statement.executeQuery(sql);
int id = 0;
String name = "";
String location = "";
while (rs.next()){ //處理結果集
id = rs.getInt("id");
name = rs.getString("name");
location = rs.getString("location");
System.out.println(id + " " + name + " " + location);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
或者
public void add2() throws Exception{
Class.forName(driverClassName);
Connection con = DriverManager.getConnection(url, username, password);
PreparedStatement ps = con.prepareStatement("insert into lib(id,name,price,date) values(?,?,?,?)");
ps.setInt(1,111);
ps.setString(2,"蜜汁燉魷魚");
ps.setDouble(3,36.9);
String date = "1999-8-8 19:52:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); //轉換
Date d = sdf.parse(date);
long time = d.getTime();
ps.setDate(4,new java.sql.Date(time));
int rows = ps.executeUpdate();
if (rows > 0){
System.out.println("success");
}else{
System.out.println("error");
}
- 簡單化
public class JdbcUtil2 {
public static void main(String[] args) {
// update("insert into category (id,name) values (221,'公關部')");
// update("delete from category where i d=?");
// update("update category set name='社會' where id=77");
query("select * from category");
}
public static Connection load(){
String driverClassName = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql:///bookmanage";
String username = "root";
String password = "root";
try {
Class.forName(driverClassName);
Connection connection = DriverManager.getConnection(url, username, password);
return connection;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 增刪改 用update
*/
public static void update(String sql){
Connection con = load();
try {
Statement sta = con.createStatement();
boolean execute = sta.execute(sql);
if (!execute){
System.out.println("執行成功");
}else {
System.out.println("執行失敗");
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 查詢 用query
*/
public static void query(String sql){
Connection con = load();
try {
PreparedStatement ps = con.prepareStatement(sql);
ResultSet resultSet = ps.executeQuery();
while (resultSet.next()){
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println(id + " " + name);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
- 疑問
/** * Statement 是編譯對象 是執行sql語句的 * |-----PreparedStatement 是預編譯對象 是執行sql語句的 *爲什麼不採用Statement? * 答:因爲有可能會發生 SQL安全問題! SQL注入 * 因此 子類PreparedStatement 解決上面的可會出現的問題,沒有 SQL安全問題。所以採用它 * executeUpdate(): 增刪改 使用 Update方法 --- > 對應到 QueryRunner 類中的update() * executeQuery(): 查 使用 Query方法 --- > 對應到 QueryRunner 類中的query() */