1.MyBatis中#和$的區別:
1)#和$都可以充當佔位符,
#的底層是通過PreparedStament實現的,$的底層是通過Stament實現的
2)只有傳入數據庫對象時纔會使用到$
2.1按照某個表進行查詢時輸入表名
2.2按照表中的某一列進行排序時,輸入類名
3)在傳入非數據使用庫對象時最好不要使用$
4)#是先編譯sql語句在傳值,傳入的值加上雙引號
$是直接拼接字符串,不會給傳入的值加上雙引號
5)#會防止sql注入,$不會
2.防止sql注入:
sql注入:
查詢時通過修改where後面的條件,將條件該爲真,查詢全表
防止sql注入:
預執行sql語句,提前判斷sql語句的語義和語法是否正確
當我們要查詢的信息比較敏感,對安全要求比較高,通過PreparedStament來進行查詢
3.Spring:
spring是輕量級別的控制反轉和麪向切面的容器框架
IOC:控制反轉:
以前我們都是自己創建對象使用對象,控制反轉就是將對象的創建交給Spring來完成,
我們只需要使用對象即可,實現了鬆散耦合。
IOC的底層實現原理:
IOC容器創建對象和處理對象之間的依賴關係:工廠模式+反射機制
創建對象是Spring容器幫我們來進行創建(控制反轉+依賴注入)
實現是通過java的反射機制來實現的。
創建對象的三種方式:
1)通過靜態工廠獲取對象
2)通過工廠方法模式獲取對象
3)通過Bean的class來進行加載
DI:依賴注入
IOC的一種特殊體現形式,配合接口達到不同層之間的解耦
DI不能單獨存在,必須建立在IOC的基礎上。即要先創建對象才能注入屬性值
DI依賴注入的方式:
1)構造器注入
2)靜態工廠注入
3)實例化工廠注入
4)setter注入
4.1)由於屬性注入具有可選性和靈活性高的特點,是最常用的注入方式
4.2)屬性注入需要爲Bean提供一個默認的構造函數,並且要爲注入的屬性值提供setter方法。
Spring先調用bean默認的構造函數,然後通過反射機制的方法通過setter注入屬性值
通過Property標籤的name屬性的值去找對應的setter方法
AOP:面向切面的編程
對面向對象的完善和補充,即將面向對象中的各個不同的業務模塊所用到的共同的功能提取出來,
通過動態代理模式爲各個業務模塊擴展功能。
一般應用在系統級別的功能配置上,在系統開發中主要是爲了解決系統 層面上的問題(日誌,事務,權限)
AOP的底層實現:採用動態代理模式
1)有接口的情況:創建接口的實現類的代理模式:JDK動態代理
2)沒有接口的情況:子類可以通過super()調用父類的方法
創建子類的代理模式:oglib動態代理
連接點(joinPoint)需要額外增加功能的方法
切入點(pointcut) 所有連接點的集合
代理(proxy):將額外的功能切入切入點.
目標(target):連接點所在的對象
切面(aspect):封裝橫切關注點信息的類,每個關注帶你體現爲一個通知方法.
通知(advice):切面必須完成的各個具體工作
前置通知,後置通知, 後置異常通知, 後置成功通知,
環繞通知:可以更加靈活的在連接點之前,之後添加功能。
<!-- AOP配置 proxy-target-class="false":不使用自動代理-->
<aop:config>
<!-- 切入點的配置 expression:要額外增加功能的方法 返回值 包名 類名 方法名-->
<aop:pointcut id="mypointcut" expression="execution(* com.yangsheng.dao.*.*(..))"/>
<!--環繞增強,通知和切入點 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="mypointcut"/>
</aop:config>
Spring事務管理分爲兩種:
1)編程式事務管理:
通過編程的形式管理事務,靈活性高,很難維護
2)聲明式事務管理:
將事務的管理和業務代碼進行分離,只需要通過註解和配置xml文件管理事務
@Transactional註解:可以作用於接口,接口方法,類以及類方法上
(String建議不要在接口或者接口方法上使用該註解,因爲這隻有在使用接口的代理時纔會生效)
當作用到類上時,該類的所有public 方法將都具有該類型的事務屬性
不要在Dao層使用事務註解,在平時工作中一般使用在service層。
<!-- 事務管理器 DataSourceTransactionManager dataSource:引用上面定義的數據源 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 數據源 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 支持事務註解 -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- 事務通知以及傳播特性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 傳播行爲 -->
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="create*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="select*" propagation="SUPPORTS" read-only="true" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
事務傳播特性:
事務:事務是程序中一系列嚴密的操作,所有操作執行必須成功完成,否則在每個操作所做的更改將會被撤銷,這也是事務的原子性(要麼成功,要麼失敗)
事務的特性:
事務特性分爲四個:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持續性 (Durability)簡稱ACID。
原子性(Atomicity):事務是數據庫邏輯工作單元,事務中包含的操作要麼都執行成功,要麼都執行失敗。
一致性(Consistency):事務執行的結果必須是使數據庫數據從一個一致性狀態變到另外一種一致性狀 態。當事務執行成功後就說數據庫處於一致性狀態。如果在執行過程中發生錯 誤,這些未完成事務對數據庫所做的修改有一部分已寫入物理數據庫,這是數據 庫就處於不一致狀態。
隔離性(Isolation):一個事務的執行過程中不能影響到其他事務的執行,即一個事務內部的操作及使用的 數據對其他事務是隔離的,併發執行各個事務之間無不干擾。
持續性(Durability):即一個事務執一旦提交,它對數據庫數據的改變是永久性的。之後的其它操作不應該 對其執行結果有任何影響。
spring支持7種事務傳播行爲:
required, supports,mandatory,required_new, not_supports,never, nested
required:如果當前沒有事務,就新建一個事務,如果有一個事務,就加入到這個事務中
supports: 支持當前事務,如果當前沒有事務,以非事務方式執行
事務的隔離級別(4種):
1)Read uncommited(讀未提交):
允許一個事務可以看到這個事務未提交的數據
2)Read commited(讀提交):
一個事務提交之後,才能被另外一個事務讀取
3)Repeatable read(讀重複):
一個事務不能讀取該事務未提交的數據
4)Serializable(序列化):
事務被處理爲順序執行
髒讀:一個事務讀取了另外一個事務未提交的數據
不可重複讀:一個事務兩次讀取同一行數據,得到不同的結果
幻讀: 一個事務內讀取了別的事務插入的數據,導致前後結果不一樣
4.SpringMVC和Struts2的區別:
(1) 加載機制(核心)不同:
Struts2的核心是基於Filter的StrutsPrepareAndExecuteFilter
SpringMVC的核心是基於Servlet的DispatcherServlet
(2) SpringMVC的性能比Struts2好
Struts2是基於類級別的攔截,每次來了請求之後都會創建一個Action,然後通過setter,getter方法將request中的數據注入
SpringMVC是基於方法級別的攔截,來了請求之後直接去Controller中找@RequestMapping的URL對應的方法即可
(3) 參數傳遞
Struts2是通過成員屬性來接受參數,參數可以被多個方法所共享。
SpringMVC的方法基本上是獨立的,獨享request,response中的數據。
請求數據通過參數獲取,處理結果通過ModerMap返回給框架,方法之間不共享變量
(4) ajax交互
SpringMVC的ajax交互十分方便,只需要@ResponseBody返回響應文本即可
(5) 攔截機制的實現
SpringMVC通過AOP方式實現,
Struts2有自己的攔截機制,導致Struts2的配置文件比SpringMVC大。
5.Hibernate和Mybatis的區別:
相同點:
1)都是基於ORM(對象關係映射)思想解決Entity和數據庫中的映射關係
2)Hibernate和MyBatis都支持JDBC(數據庫連接池),JTA(事務),API(應用程序編程接口)事務處理
3)Hibernate和MyBatis都是通過SessionFactoryBuilder由xml配置文件生成sessionFactory,
由sessionFactory生成session,由session執行事務和sql語句
不同點:
1)MyBatis是通過mapper.xml維護映射結果,程序員需要手動編寫sql語句,
比起Hibernate自動生成HQL語句更加靈活,SQL調優更加容易。
2)Hibernate 移植性更好,
MyBatis移植性不太好,不同的數據庫需要編寫不同的sql語句。
3)Hibernate在數據量大表多的時候關係操作變得複雜。
4)Hibernate比MyBatis有更好的二級緩存機制。
5)Hibernate自己提供分頁功能,MyBatis需要配置分頁插件
6.Hibernate與MyBatis二級緩存的區別:
1)Hibernate有良好的二級緩存機制,用戶無需關心sql,在查詢時如果出現髒數據系統會報錯
MyBatis用二級緩存要特別小心,髒數據的出現會對系統的正常運行產生影響。
2)Hibernate的二級緩存在sessionFactory中進行詳細的配置,然後在具體的表一映射關係中配置是那種緩存
MyBatis的二級緩存是在具體的表一映射關係中進行詳細的配置,可以根據不同的表,指定不同的緩存機制
7.List Set Map區別?
1) List和Set是存儲單列數據的集合,
Map是存儲鍵值對的雙列數據的集合
2)List是有序的,值可以重複
Set是無序的, 值不可以重複
Map是無序的,鍵不能重複,值可以重複
3) ArrayList:底層結構是數組,查詢快,線程不安全,效率高
LinkedList: 底層結構是鏈表,增刪快, 線程不安全,效率高
Vector: 底層結構是數組,線程安全,查詢慢,增刪慢
ArrayList中的數據是連續的,成塊的,查詢時直接遍歷內存即可。
LinkdedList中鏈表內存是散列的,插入時只需要改變鏈表中兩個節點之間的引用關係,
使它們指向新的節點,即可完成插入。刪除時只需要刪除對應節點的引用即可。
4)HashMap: 存儲順序和遍歷順序不一定一致,鍵和值都可以爲null
HashTable: 和HashMap類似,鍵和值不可以爲null,線程安全
LinkedHashMap:和HashMap類似,鍵和值不可以爲null,線程安全
TreeMap: 按照鍵升序排列
5)HashSet:底層是由HashMap實現,不允許集合中有重複的值,使用該方法必須重寫equals()和HashCode方法
LinkedHashSet:繼承於HashSet,同時又基於LinkedHashMap來進行實現,底層用的是LinkedHashMap
8.Hibernate緩存:
一級緩存:
session級別的緩存,一級緩存不可卸載,只要用到了session,就用到了session的緩存機制
不能手動配置。當執行了get, load, find,query查詢出來的數據默認會在session中保存一分數據。
緩存數據在數據庫中將一些數據拷貝一份放到對應的地方。
清理一級緩存: clean,close
二級緩存:
sessionFactory級別的緩存,可以做到多個session共享此信息
查詢緩存:
Hibernate的二級緩存是根據id來進行查詢的,對條件查詢無用。
Hibernate配置了根據條件查詢的查詢緩存。
適合放在一級緩存中的數據:
1)不允許出現併發(財務數據)
2)與其它應用共享的數據
適合放在二級緩存中的數據:
1)不是很重要的數據,允許出現偶爾併發
2)參考數據
3)不會被併發訪問的數據
9.Spring中爲什麼要先寫接口,在寫實現類?
OOP思想就是面向接口的編程。
面向接口的編程: 無論類的內部怎樣實現,它對外的接口不變,那麼它的使用方式就不會變。
接口的作用:用於多態,可以動態的調用實現類,實現可以方便的更換,替換,只需要改變配置文件即可
10.抽象類和接口的區別:
抽象類:被abstract修飾的類爲抽象類。
對於一個父類,如果它的某個方法在父類中實現出來沒有任何意義,必須根據根據子類的實際需求來實現,
可以將這個類定義爲抽象類。
抽象類和接口是解決單繼承的重要手段。
區別:
1)抽象類可以提供成員方法的實現細節,而接口只能提供public abstract方法
2)抽象類的成員變量是多種類型的,而接口的成員變量是public abstract final 類型
3) 抽象類中可以有靜態方法和靜態代碼塊
接口中不能有靜態方法和靜態代碼塊
4)一個類只能繼承一個抽象類,但是一個類可以實現多個接口。
5)抽象類可以有構造方法,而接口不能有。
6)抽象類中可以包含非抽象的普通方法,接口方法必須是抽象的
7)抽象類中的抽象方法的訪問類型可以是public,protected
接口中的方法只能是public類型的(默認)
11. HTTP 協議
超文本傳輸協議,是用於從www服務器傳輸超文本到本地瀏覽器的傳輸協議
HTTP協議的特點:
客戶端發送的請求都必須服務器迴應響應,而且在請求之後主動釋放資源
HTTP協議響應狀態碼:http狀態碼
400:請求語法有誤(客戶端請求有語法錯誤,不能被服務器所理解)
403:請求資源的訪問被服務器拒絕( 服務器收到請求,但是拒絕提供服務)
404:未找到資源(請求資源不存在,eg:輸入了錯誤的URL)
405:不支持該Request的方法。
500:服務器在執行請求時發生錯誤
503:服務器暫時處於超負荷或者停機維護,現在無法處理請求(服務器當前不能處理客戶端的請求,一段時間後可能恢復 正常)
12.線程和進程
進程:一個正在運行的程序擁有該程序運行的所有資源,包括任務的調度和資源的分配
線程:在進程中負責具體代碼的執行,一個進程至少有一個線程
單線程:在整個程序中只有一個線程,這個線程爲主線程
多線程:整個程序不止一個線程,除了主線程,其它都爲子線程
併發: 多個任務獨立執行,一起執行
同步: 同一時刻只能執行一個任務,該任務執行完成才能執行下一任務。
異步: 一個線程中多個任務同時執行,互不影響。
多進程:操作系統能同時執行多個程序
創建線程的方式:
1)繼承Thread,重寫run()方法
有開闢線程的能力,資源共享方面不是很方便
2)實現runable接口,實現該接口的run()方法
沒有開闢線程的能力,要將創建的對象交給指定線程來執行
創建一個對象,做到資源共享,多個線程可以執行同一任務
線程池:
幫助我們管理線程,我們只需要將需要執行的任務交給線程池。
線程池會根據任務的個數,任務的時長,將不同的任務交給線程池中的線程執行
線程死鎖:
多個線程因爲競爭資源而造成相互等待,
若無外力作用,這些進程都將無法向前運行。
防止線程死鎖:
1)加鎖順序
2)加鎖時限
3)加鎖檢驗
線程鎖:
當多個線程訪問資源時,爲了數據安全,保證當一個線程訪問資源時,其它線程不能訪問,
等上一個線程訪問完成之後才能發訪問。
同步鎖:
synchronized(對象){
//同步代碼塊: 同一個對象鎖下的所有線程,某個時間段內只能有一個線程在執行該代碼塊
}
在同步代碼快內:
wait():當前線程暫停運行,被同一個線程鎖的其它線程喚醒才能繼續運行
wait(時長毫秒):當前線程暫停運行,當超過時長還沒有被喚醒,就不等其它線程喚醒了,接着執行
notify(): 喚醒同一個同步鎖中某一個wait()鎖
notifyAll(): 喚醒同一個同步鎖中所有wait()線程
線程的生命週期:
創建(new)---就緒(start)---運行狀態(等待CPU調用run方法,如果線程在運行時發生阻塞,
進入阻塞狀態,之後又返回就緒狀態,等待CPU的再次調用)---結束狀態(run方法執行完成)
run和start方法的區別:
start:重新開啓了一個線程,不必等待其它線程執行完成。
run:只是調應了一個普通方法,沒有開啓線程,程序還會按照順序執行響應代碼。
13.內部類:
作用場景:更好的完善和補充了java中類的單繼承問題。
形式:
1)成員內部類:定義在外部類中
1.1)該類中不可以定義被static修飾的變量和方法等
1.2)該類的內部可以使用外部類中定義的變量,方法等
使用:外部類.內部類 對象名 = 外部類對象.new 內部類()
2)靜態內部類:定義在外部類中,被static修飾
2.1)在該類中可以定義正常類的所有變量和方法
2.2) 在該類中不能直接使用外部類的成員方法和成員變量
使⽤:外部類.內部類 對象名 = new 外部類.內部類()
3)局部內部類:
定義在方法中的類,和成員內部類類似,只能在定義的方法中使用
不能被static修飾
4)匿名內部類:
有些場景下,接口或者類我們根據當前需求,需要重寫其中的功能。
但是隻是在場景下使用,這時我們可以通過匿名內部類來實現,不需要額外的定義子類。
new 接口名或者類名<>(){
//子類重寫的方法
}
14.MyBatis接口的映射規則:
MyBatis是面向接口的編程,可以將配置文件當成接口的實現類
1)namespace必須寫成接口的完整類名(包名+接口名)
2)sql語句的id必須是對應接口裏的方法名
3)parameterType:必須和方法的參數的類型保持一致
4)resultType: 必須和方法的返回值保持一致
增刪改:parameterType: com.xalo.model.Doctor 沒有resultType
所有更新(增刪改)操作,不用指定返回值類型,默認返回受影響的行數
也可以爲java類起別名,在配置文件中就可以使用別名。 目的:書寫更加簡單
查詢: resultType, parameterType resultMap
resultMap:當實體類跟表中屬性名不一致,在resultMap標籤中做 實體類和表中字段的映射
<resultMap type="java.util.Map" id="stuMap">
<result column="name" property="name"/>
<result column="age" property="age"/>
</resultMap>
column:表中字段名稱 property: 實體類中屬性名
id:當前resultMap映射結果, type: 實體類中屬性名
15.基本數據類型(四類八種):
整數型: byte(1) short(2) int(4) long(8)
浮點型: float(4) double(8)
字符型: char(2)
布爾類型: boolean(1/4字節)
16.left join:
返回包括左表中的所有記錄和右表中連接字段相等的記錄
select * from A left join B on A.id = B.id
right join:
返回包括右表中的所有的記錄和左表中連接字段相等的記錄
select * from A right join B on A.id = B.id
inner join:
等值連接,只返回兩個表中連接字段相等的值
17.SSM配置文件:
SpringMVC_beans.xml:
1.掃描註解包: <context:component-scan/>
2.註解驅動: <mvc:annotation-driven/>
3.靜態資源的配置: <mvc:default-servlet-handler />
4.配置數據效驗器
5.界面解析器
6.文件上傳的配置
7.處理攔截器的配置
spring-mybatis.xml:
1.註解掃描包
2.數據源dataSource
數據庫驅動 數據庫地址 數據庫用戶名 數據庫密碼
3.spring和Mybatis的整合: sqlSessionFactory
3.1:引入數據源
3.2載入Mybatis的主配置文件
4.自動掃描,將Mapper接口生成代理注入到Spring.
4.1:掃描接口所在的包
5.事務管理器
5.1:引入數據源
6.事務通知以及傳播特性
7.AOP配置
7.1切入點的配置:expression要額外增加功能的方法
7.2環繞增強,通知和切入點
myBatis-config.xml:
1.全局設置
1.1:調用log4j框架,打印日誌
1.2:開啓二級緩存
2.爲java類型起別名,在配置文件中就可以使用別名 目的:書寫簡單方便
3.映射文件的導入:
註解的使用:在mybatis的配置文件中註冊這個映射接口(注意是class)
18.獲取input輸入框中的值的方法:
1)利用var方法
var uId = $(#IDQuery).var();
2)通過attr屬性,獲取value的制定的值
var uId = $(#IDQuery).attr("value");
19.如何添加一個輸入框
<label>用戶id</label>
<input id = "IDQuery" type = "uId" disabled="disabled" style = " border:black solid; width: 150px" >
<button id = "selects">查詢</button>
<!--添加點擊事件-->
$("#selects").click(function(){
<!--ajax獲取輸入(input)的值-->
var uId = $(#IDQuery).var();
})
disabled:不可編輯,當設置這個輸入框時,當前輸入框不能輸入內容
用到的標籤<label> <input> <button>
20.JQuery入口函數(腳本)
JQuery: 在html所有便籤(DOM)都加載之後,就會執行
$(document).ready(function(){
})
$(function(){
})
$().ready(function(){
})
21.JQuery選擇器:
<!--1.元素選擇器:用戶點擊按鈕後,所有<p>元素都隱藏-->
$(document).ready(function(){
$("#selects").click(function(){
$("p").hide();
});
});
<!--#id選擇器: 當用戶點擊按鈕後, 有 id = "test" 屬性的元素將被隱藏-->
$(document).ready(function(){
$("#selects").click(function{
$("#test").hide();
});
});
<!--3. .class選擇器: 用戶點擊按鈕後,所有帶有 class = "test"屬性的元素都隱藏-->
$(document).ready(function(){
$("#selects").click((){
$(".test").hide();
});
});
22.設置內容:
var(): 聲明變量
text(): 設置和返回所選元素的文本內容
html(): 設置和返回所選元素的內容(包括HTML標記)
attr(): 設置/改變屬性值,允許同時設置多個屬性。
alert():使用變量,打印出來
val(): 設置或返回表單字段的值
23.前端頁面:
1)將html文件轉換爲jsp文件
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
2)導入jsp標籤庫
<%@ taglib prefix="s" uri="/struts-tags"%>
3)引入css文件
<link rel = “stylesheet” type = “text/css” href = “”/>
4)引入js文件
<script type="text/javascript" src = "js/文件名"></script>
5)執行定義好的方法
<button id="selects" onclick = " ">點擊按鈕</button>
24.String StringBuffer 和StringBuilder的區別:
1)執行速度
StringBuilder > StringBuffer > String
String是字符串常量,StringBuilder和StringBuffer是字符串變量
String一旦創建椒不可以更改的,StringBuilder和StringBuffer是可以更改的。
2)StringBuilder沒有線程鎖,是線程不安全的
StringBuilder和StringBuffer是線程安全的。
String:用於少要字符串的操作。
StringBuffer:多線程下在字符緩衝區進行大量操作的情況
StringBuilder: 單線程下在字符緩衝區進行大量操作的情況
25.Maven
1.Maven生命週期
完整的項目構建過程: clean(清理)--->compile(編譯)--->test(測試)
--->package(打包)---->集成測試--->驗證--->部署
2.defaut 構建項目(最核心)
2.1 compile 編譯項目
2.2 test 測試項目
2.3 package 打包
2.4 install 安裝到本地倉庫中
3.<modelVersion> 指定當前pom版本
<groupId> 組織名 包名 + 類名
<artifactId> 項目名
<packaging> 打包方式
<name> 項目名稱
<url> 項目地址
maven install與maven build的區別
沒有 mvn build這個命令。
只有mvn install 和 mvn package
mvn install 是將你打好的jar包安裝到你的本地庫中,一般沒有設置過是在 用戶目錄下的 .m2\下面
mvn package 只是將你的代碼打包到輸出目錄,一般的是 target下面
maven中更改tomcat默認端口號的方法
方式1:雙擊server下的tomcat服務器,然後在ports下面修改
方式2: 一次性的,下次進行啓動,這樣不需要手動重複輸入
Run As ----Maven build -----Goals(tomcat:run -Dmaven.tomcat.port=8081)
tomcat:run:運行命令
26.如何配置搭建tomcat服務器
1)在官網下載tomcat源代碼,可以直接下載免安裝版,直接解壓到本機的某個路徑下
2)增加環境變量配置
在Path中新增加tomcat所在文件下的bin目錄
3)增加CATALINA_HOME環境變量配置
配置的值是tomcat解壓後的文件目錄
4)打開cmd命令框(window+R)
輸入:catalina startup進行啓動服務器
啓動過程中查看新的窗口打印日誌成功後即可表示啓動完成
5)測試啓動是否正常:
打開瀏覽器輸入地址: http://localhost:8080回車,可以測試啓動是否正常
27.SQL數據庫查詢出一張表中重複的數據
----查詢出name重複的有哪些
select name from score group by name having count(*) > 1;
----查詢每個名字出現大於2次 DESC:降序 ASC:升序
select count(name) as '出現次數',name from score group by namehaving count(name) > 2 order by '出現次數' Desc;