java基礎知識點4
(1)檢視:
檢視是一張虛擬的表,本質上是對基表的一條select查詢語句.
然後給這條查詢語句進行命名,即為檢視名稱.
當基表資料發生改變時,檢視資料也發生改變.
檢視的作用:
1.簡化複雜查詢
2.限制資料訪問
檢視語法:
create or replace
create or replace VIEW view_myemp_20 AS select * from myemp where depton = 20;
(2)索引:
索引是基於表中的某一列來進行建立,作用是為了提高查詢效率
單例索引:
create unique
符合索引:
基於多列來建立的索引
例如:基於表中某兩列來建立的索引,進行order by 會使用到
create unique index idx_myemp_deptno_salary on myemp(deptno,salary);
select id,name,deptno,salary from myemp order by deptno ASC,salary DESC;
(3) 觸發器
資料庫中與表相關的一段PL/SQL語句,主要作用是監聽表的DML操作,
當執行了insert/update/delete之後,會自動觸發儲存在觸發器中的PL/SQL語句
create or replace trigger trigger_savenewemp
after insert
on myemp
declare
begin
dbms_output.put_line('成功插入員工');
end;
/
觸發器的使用場景:
1.複雜的安全性檢查
2.資料的確認
3.資料的審計
4.資料的備份和同步
(4)儲存過程:
資料庫系統中一組提前編譯好的PL/SQL語句集,可以將複雜的SQL語句進行封裝,
只需要編譯一次,以後不需要重複編譯.可以經過儲存過程名反覆呼叫,減少工作量
create or replace procedure sayHello
AS
begin
dbms_output_line('helloword');
end;
/
呼叫儲存過程
begin
sayHello();
sayHello();
end;
/
(5)執行緒
程序: 一個正在執行的程式,擁有該程式執行的所有的資源,包括資源的分配和任務的排程
執行緒: 在程序中負責具體程式碼的執行,一個程序至少有一個執行緒
併發: 多個任務獨立執行,一起執行
同步: 同一時刻只能有一個任務執行,當這個任務執行完成之後,才能執行下一個任務
非同步: 一個執行緒中多個任務同時執行,互不影響
執行緒鎖: 當多個任務訪問資源時,為了保證資料的安全,
當一個執行緒訪問資源時,其它執行緒不能訪問,等上一個執行緒訪問完成之後才能訪問.
同步鎖: synchronized 修飾方法
阻塞執行緒的方法:
1) Thread.sleep(3000);
2) synchronized(slock){
slock.wait(3000);
slock.notify();
slock.notifyAll();全部喚醒
}
建立執行緒的方法:
1)繼承Thread,重寫run()方法
有開闢執行緒的能力,資源共享方面不是很方便
2)實現runable介面,實現該介面的run()方法
沒有開闢執行緒的能力,資源共享方面很方便
執行緒池:
幫助我們管理執行緒,我們只需要執行的任務交給執行緒池,
執行緒池會根據任務的大小,任務的時長,會將不同的任務交給執行緒池中的任務執行.
執行緒死鎖:
多個執行緒因競爭資源而造成相互等待.
若無外力的作用,這些執行緒將無法向前推進
防止執行緒死鎖:
1)加鎖順序
2)加鎖時限
3)加鎖檢驗
程序和執行緒的區別:
1)程序時資源分配和排程的一個獨立單元,執行緒是CPU排程的基本單元
2)同一個程序中可以包含多個執行緒
3)程序結束後它擁有的執行緒都將銷燬,而執行緒的結束不會影響同個程序中的其它執行緒的結束
4)執行緒共享整個程序的資源,一個程序至少包含一個執行緒.
(6) Mysql優化
1)in和not in 要慎用,否則會導致全表掃描, 改為 between...and...
2)儘量避免在where後面的子句中使用or, 改為 union all
3)儘量避免在where的子句中進行表示式操作
select id from zhou where num / 2 = 100;
改為: select id from zhou where num = 100 * 2
4)任何時候都不要使用select * from zhou,用具體的欄位代替
5)如果使用到臨時表,在儲存過程的最後務必將臨時表刪除
(7) 泛型:
JDK1.5之後的新特性
作用:
1.在編譯期間規定好我們要使用的型別,將執行時產生的異常提前到編譯器,有利於我們處理異常
2.將類,介面,方法等資料型別引數化,更加靈活,程式碼複用性更高
3.泛型沒有多型的特點
4.泛型不影響真實型別
泛型類:
class 型別<形參1,形參2.....>{ }
實參只能是引用資料型別,而不能是基本資料型別
泛型方法:
修飾符 <形參1,形參2...> 返回值 方法名(引數列表) { }
泛型介面:
interface 介面名<形參1,形參2.....> { }
(8)單例模式:
當全域性物件只需要一個,保證全域性物件的唯一性,達到資源共享
餓漢式:
一開始就建立這個物件,執行緒不安全
優點:多執行緒訪問時效率快
缺點:在不使用例項時佔用記憶體空間
public class Singleton{
private Singleton(){ }
private static Singleton instance = new Singleton();
public static Singleton getInstance(){
return instance;
}
}
懶漢式:
用例項的時候才建立
優點: 在不使用例項時不佔用記憶體空間
缺點: 多執行緒時需要通過同步的手段達到例項的唯一性,效率低
public class Singleton{
private Singleton() { }
private static Singleton instance = null;
public static synchronsized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
return instance;
}
}
(9) Shiro授權流程:
1.呼叫Subject使用者主體介面,委託給Security Manager(安全管理器)
2.Security Manager委託給Authorizer(授權器)
3.Authorizer在授權之前會呼叫Realm(安全資料來源,shiro和資料庫/資料來源之間的橋樑)
4.Authorizer會判斷Realm的許可權/角色是否和傳入的匹配
如果匹配返回true,否則返回false表示授權失敗
(10)Oracle和Mysql的區別:
1.Oracle是大型資料庫,Mysql是小型資料庫。
Oracle市場佔有率達40%,Mysql 20%左右
Oracle價格非常高,Mysql是開源的
2. Oracle支援大併發大訪問量
3. Oracle安裝完成之後需要3G左右,Mysql只需要152M.
使用Oracle佔用特別大的記憶體空間和其它機器效能
4.操作上的區別:
1)Mysql有create table if not exixt 方式建立表
Oracle不支援if not exist和drop table if exists 語句
2)Mysql使用自動增長型別,在建立表時只需要指定表的逐漸即可auto_increment
Oracle不能使用auto_increment.
Oracle的主鍵一般預設是4個位元組,Mysql沒有要求
3)Mysql可以使用雙引號包起字串
Oracle只能用單引號包起字串
4)分頁
Oracle: page:當前頁碼, pageSize:每頁顯示個數
select * from (select rownum rn,zhou.*from zhou)
where rn between (page-1)*pageSize + 1 and page*pageSize
Oracle分頁注意事項:
在使用rownum時,不能對rownum進行大於0的某一數的判斷,
因為rownum必須從0開始遞增
Mysql分頁:
select * from 表明 limit 起始行號,行數。
起始的行號從0開始,如果和order by 連用。order by 在前
---列出總成績並且按照降序排列,只打印三行
select name,sum(score) from score group by name order by sum(score) desc limit 3;
5)字串的模糊查詢
Mysql:
select * from 表名 where 欄位名 like ‘%條件%’
Oracle: 不能使用索引,速度不快
---查詢名字中第二個字母是a的員工的資訊
select id,name from zhou where name like '_a%';
(11)關係型資料庫和非關係型資料庫的區別:
關係型資料庫:表和表,表和欄位,資料和資料庫之間存在著關係
優點:關係型資料庫有事物存在,保證資料的完整性和一致性
缺點: 因為資料和資料之間有關係,底層是運行了大量的運算,會降低效能
對海量資料的增刪改查無能為力,海量資料的維護變得無力
(12)Servlet執行流程
Servlet作用:
處理伺服器端的資源分配,前端傳送過來的請求,並不是直接給伺服器,
而是Servlet來處理請問,根據請求資料找到對應的資源,然後返回給前端。
Servlet執行流程:
1)瀏覽器輸入訪問路徑
2)根據訪問路徑找到已註冊的servlet名稱。
3)根據對映找到對應的servlet名
4)根據servlet名找到我們全限定類名,即我們自己寫的類
5)呼叫init()方法進行初始化
6)呼叫service()方法處理前端傳送過來的請求
前端傳送一次請求該方法被執行一次,所以該方法可以被多次執行
request:接受前端傳送過來的引數,response:負責響應給前端資料
例如:登入操作
6.1)處理前端傳遞過來的資料:req.getParameter(" ")
6.2)生成一個json物件:JSONObject jObject = new JSONObject();
進行非空判斷,呼叫dao層查詢資料庫
6.3)session存值,在jsp頁面顯示它
HttpSession session = req.getSession();
session.setAttribute("manager", manager);
6.4) 建立servlets層繼承自HttpServlet,重寫doGet(),doPost()方法
在doGet()方法裡面寫:
//將資料交給service層來處理
MyService service = new MyService();
String json = service.login(req,resp);
//給前端返回資料
req.setAttribute("json", json);
req.getRequestDispatcher("/login.jsp").forward(req, resp);
6.5)Login.jsp
String json = (String)request.getAttribute("json");
if(json != null){
JSONObject jsonObject = JSONObject.fromObject(json);
int code = jsonObject.getInt("code");
if(code == 0){
//登陸成功
response.sendRedirect(application.getContextPath() + "/index.jsp");
return;
} else{
out.print(jsonObject.get("msg"));
}
}
<script type="text/javascript">
$(document).ready(function(){
//獲取到cookie的name和密碼
var name = $.cookie("name");
var pwd = $.cookie("pwd");
console.log(name);
//把使用者名稱和密碼放到前端的input上 獲取前端的框
$("#name").attr("value",name);
$("#PASSWORD").attr("value",pwd);
});
</script>
7)呼叫destory()方法終止(結束)
當servlet物件被釋放時,會呼叫此方法,一般該方法會做一些掃尾工作
(例如:關閉資料庫,將一些重要的資料儲存起來)
Servlet是由JVM的垃圾回收器進行垃圾回收的
(13)九大內建物件:
request:請求物件;
response:響應物件
out: JSPWriter類例項,負責向前端輸出資料
session: HttpSession類例項,追蹤不同客戶端的會話
application: ServletContext類的例項,可以作用於整個web專案的物件。
獲取轉發物件:getRequestDispatcher("");
獲取當前根目錄:getContextPath();
根目錄:當前專案所需要的資源都在一個目錄下,該目錄為根目錄
pageContext: 可以獲得JSP頁面所有物件,可以存值並指定有效範圍
儲存的資料預設只能在當前的⻚頁⾯面使⽤用: setAttribute(“key1”, “value1”)
儲存的資料在⼀一次會話中使⽤用: setAttribute(“key2”, “value2”, PageContext.SESSION_SCOPE)
page:當前JSP檔案物件,類似java中this關鍵字
config: 獲取xml中的配置內容,
相當於appliacation: config.getServletConfig()
exception:處理異常
獲取異常資訊:
exception.getMessage();
獲取所有發⽣生異常的位置:
StackTraceElement[] elements = exception.getStackTrace();
打印發⽣生異常的地⽅方資訊:
exception.printStackTrace();
(14)重定向和轉發的區別
轉發:
request.getRequestDispatcher(“new.jsp”).forward(request, response);
重定向:
response.sendRedirect( request.getContextPath( ) + "new.jsp")
1)重定向:瀏覽器的行為,發起了兩次請求,兩次響應
轉發:伺服器的行為,發起了一次請求,一次響應
2)重定向可以訪問自己web應用以外的資源,轉發只能轉發給本專案其它資源
3)重定向位址列會顯示第二次請求的地址,傳輸的資訊會丟失。
4)重定向需要給出全路徑,即路徑要包含專案名
轉發只需給出轉發的資源路徑即可
5)重定向底下的程式碼還會執⾏行行, resp.sendRedirect之後,應緊跟⼀一句句return
Manager manager = (Manager)session.getAttribute("manager");
if(manager == null){
System.out.println("未登入");
response.sendRedirect(application.getContextPath()+"/managerLogin.jsp");
}
(15)MyBatis中#和$的區別:
1.#和$都能充當佔位符,
#的底層是通過PreparedStatement實現的
$的底層是通過Statement實現的
2.只有在傳入資料庫物件時,才會用到$
2.1按照某個表進行查詢時,傳入表名;
2.2按照某一列進行排序時,傳入類名
3.傳入非資料庫物件時最好用#不用$
4.#是先編譯sql語句,在傳值給傳入的值都加上雙引號
$是直接拼接字串,不會給傳入的值加上雙引號
5.#會防止sql注入,$不會
(16)防止sql注入的問題:
sql注入:
查詢時通過修改where後面的條件,將條件該為真,查詢全表
防止sql注入:
預執行sql語句,提前判斷該sql語句的語義和語法是否正確
當我們要查詢的資訊比較敏感,對安全性要求高,我們就使用prepareStatement,來進行查詢