java面試重點(一)
java面試重點(一)
個人學習總結,還望大家多多指教!
目 錄
4、sessionFactory中獲取session的方法--getCurrentSession()和OpenSession()區別:......... 6
6、Hibernate工作原理、六大核心程式設計介面(或物件,此介面非interface):............................................. 8
1、******授權中的with admin option和with grant option區別:
oracle:
with admin option 只能在賦予 system privilege 的時使用
with grant option 只能在賦予 object privilege 的時使用
使用with admin option 被授權使用者可將所獲得的許可權再次授予其它使用者或角色,而且取消授權時不級聯
使用with grant option 被授權使用者可將所獲得的許可權再次授予其它使用者或角色,並且取消許可權是級聯的
mysql:
mysql只有with grant option,對A使用者進行的授權,A可以授予給其他使用者,當收回對A的授權時,A授予給其他使用者的許可權不會級聯收回。
注意:with grant option也可以被授予給其他使用者。
2、日期轉換
package com.bors.test;
import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date;
public class DateParserT {
/** * Date 與 String、long 的相互轉換 * * @author bors * @param args */ public static void main(String[] args) {
Date dt = new Date(); System.out.println(dt); // 格式:Mon Jul 09 02:08:52 CST 2018
// 格式:2018-7-9 String formatDate = null; formatDate = DateFormat.getDateInstance().format(dt); System.out.println(formatDate);
// 格式:2018年7月9日 星期三 formatDate = DateFormat.getDateInstance(DateFormat.FULL).format(dt); System.out.println(formatDate);
// 格式 24小時制:2018-7-9 02:09:39 DateFormat dFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // HH表示24小時制; formatDate = dFormat.format(dt); System.out.println(formatDate);
// 格式12小時制:2018-7-9 02:09:39 DateFormat dFormat12 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); // hh表示12小時制; formatDate = dFormat12.format(dt); System.out.println(formatDate);
// 格式去掉分隔符24小時制:201879020939 DateFormat dFormat3 = new SimpleDateFormat("yyyyMMddHHmmss"); formatDate = dFormat3.format(dt); System.out.println(formatDate);
// 格式轉成long型:1531073683 long lTime = dt.getTime() / 1000; System.out.println(lTime);
// 格式long型轉成Date型,再轉成String: 1464710394 -> ltime2*1000 -> 2016-05-31 23:59:54 long ltime2 = 1531073683; SimpleDateFormat lsdFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date lDate = new Date(ltime2 * 1000); String lStrDate = lsdFormat.format(lDate); System.out.println(lStrDate);
// 格式String型轉成Date型:2018-07-09 02:09:56 -> Mon Jul 09 02:09:56 CST 2018 String strDate = "2018-07-09 02:09:56"; SimpleDateFormat lsdStrFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { Date strD = lsdStrFormat.parse(strDate); System.out.println(strD); } catch (ParseException e) { e.printStackTrace(); } } } |
3、delete from table與truncate table區別?
delete from table:
是屬於DML,資料操作語言,是寫入回滾段的,是需要提交或者回滾的,提交後才能生效。
delete 資料後,主鍵自增還是存在的
truncate table:
是屬於DDL 資料定義語言,是不用提交,不用回滾,執行之後立即生效。是不寫入回滾段的。
主鍵自增還是不存在的
--------------------------------------------
DML(data manipulation language)資料操縱語言:
就是我們最經常用到的 SELECT、UPDATE、INSERT、DELETE。 主要用來對資料庫的資料進行一些操作,寫入回滾段
DDL(data definition language)資料庫定義語言:
在建表的時用到:CREATE、ALTER、DROP等。DDL主要是用在定義或改變表的結構,資料型別,表之間的連結和約束等初始化工作上,不寫入回滾段
DCL(Data Control Language)資料庫控制語言:
是用來設定或更改資料庫使用者或角色許可權的語句,包括(grant,deny,revoke等)語句。這個比較少用到
---------------------
4、sessionFactory中獲取session的方法--getCurrentSession()和OpenSession()區別:
hibernate3.0- 提供了一個方法openSession():Session,用於建立一個session物件
hibernate3.0+ 提供了一個新方法getCurrentSession():Session
用於獲取上下文中的session物件,如果有則重用,不會新建;如果沒有則自動新建。要求上下文中應該有事務。
當事務提交/回滾時自動關閉session,不需要手動關閉
------------------------------------------------------
*****getCurrentSession()和OpenSession()區別:
·採用getCurrentSession()建立的Session會繫結到當前的執行緒中去、而採用OpenSession()不會。
·採用getCurrentSession()建立的Session在commit或rollback後會自動關閉,採用OpenSession()必須手動關閉。
·採用getCurrentSession()需要在Hibernate.cfg.xml配置檔案中加入如下配置:
<property name="current_session_context_class">thread</property>
5、Hibernate:5種查詢方式 OID,ONG,HQL,QBC[JPA],NativeSQL[不建議]
1、ONG:物件導航查詢
2、OID:按id查詢 session.get(UserBean.class,id)/load(UserBean.class,id)
3.HQL:類sql的面向物件查詢方法
Hql語句可以完全參照sql語句編寫,其中列名稱改為屬性名,表名稱改為實體類名稱即可,所有語法基本和sql一致(除了動態sql查詢)
Sql:select * from t_user;
Hql:select u from UserBean u; 簡化寫法: from UserBean;
Sql:select * from t_user where id>1;
Hql:select u from UserBean u where u.id>1;
Sql:select name,id from t_users where id>8;投影計算
Hql:select u.name,u.id from UserBean u where u.id>8; 返回object陣列
select new Map(u.name,u.id) from UserBean u where u.id>8;返回map
Select new UserBean(u.name,u.id) from UserBean u where u.id>8;返回UserBean,但是必須有對應構造器,否則異常;
支援 模糊查 group by/ having /order by /
聚合函式sum count min max avg
4、QBC查詢:使用Criteria物件
5、本地SQL查詢:使用SQLQuery物件
6、Hibernate工作原理、六大核心程式設計介面(或物件,此介面非interface):
1、首先,Configuration讀取Hibernate的配置檔案和對映檔案中的資訊,即載入配置檔案和對映檔案,並通過Hibernate配置檔案生成一個多執行緒的SessionFactory物件;
2、然後,多執行緒SessionFactory物件生成一個執行緒Session物件;Session物件生成Query物件或者Transaction物件;可通過Session物件的get(),load(),save(),update(),delete()和saveOrUpdate( )等方法對PO進行載入、儲存、更新、刪除等操作;
3、在查詢的情況下,可通過Session 物件生成一個Query物件,然後利用Query物件執行查詢操作;如果沒有異常,Transaction物件將提交這些操作結果到資料庫中。
Hibernate六大核心程式設計介面:
1、Configuration類用於讀取並解析xml檔案,是SessionFactory的工廠,屬於即用即丟型物件,生命週期在方法內部
2、SessionFactory介面是Session的工廠,屬於重量級長生命週期物件[持有2級快取]、執行緒安全,一般開發中針對一個數據源只建立一個SessionFactory。最佳的程式設計實踐為單例模式
3、Session介面充當了實體管理的功能[save/update/delete/load/get],屬於輕量級短生命週期物件[持有1級快取]、執行緒不安全,最佳的程式設計實踐為ThreadLocal或者方法體內
Session物件是Connection物件的淺封裝,需要考慮使用try/finally結構保證及時關閉
4、Transaction介面充當事務管理器,封裝了底層的事務實現。屬於輕量級短生命週期物件、執行緒不安全,最佳的程式設計實踐為ThreadLocal或者方法體內。
注意:Session物件<==--繫結--==>Transaction物件
- Criteria介面和Query介面用於實現複雜查詢,屬於輕量級短生命週期物件、執行緒不安全,最佳的程式設計實踐為方法體內
--------------------------------------------------------
7、Hibernate使用load和get載入的區別:
--------------------------------------
1.相同點:load和get都是按id進行查詢一個記錄,呼叫方法一致
2.不同點:
2.1載入方式不同
load預設採用延遲載入的方式,所以load首先在快取中查詢資料,有則返回查詢到的資料,如果沒有則返回一個代理物件,當訪問非主鍵屬性時才真正執行sql查詢(要求獲取的session不能關閉,否則懶初始化異常org.hibernate.LazyInitializationException)。
get預設採用立即載入的方式,get執行時首先在快取中查詢資料,如果有則立即返回,不執行查詢;如果沒有則立即執行資料庫sql查詢操作.
2.2返回結果不同:
load方法在查詢不到資料時會自動丟擲org.hibernate.ObjectNotFoundException異常。
get方法查詢不到資料時會返回null
----------------------------------------
8、*****MyBatis二級快取與hibernate二級快取區別
-----------------------------------------------------------------------
MyBatis一級快取:
-預設存在。sqlSession級別的快取。session內部維繫了一個map。
--不能跨使用者,也不能跨session。
map<KEY,VALUE>:
key:你當前的SQL和引數
value:查詢的結果
在當前session中,每次查詢的時候,都先掃描map中是否有對應的Key,
如果有,直接返回value,如何沒有,才查詢資料庫。
session的銷燬,也會銷燬map。
clearCache();
session.close();
MyBatis二級快取:
必須手工配置,SqlSessionFactory級別的快取,內部也有一個map。
能跨使用者,能夠跨session。
map<KEY,VALUE>:
key:你當前的SQL和引數
value:查詢的結果
在當前session中,每次查詢的時候,都先掃描map中是否有對應的Key,
如果有,直接返回value,如何沒有,才查詢資料庫。
二級快取的配置:
<cache></cache>
什麼時候用二級快取,什麼時候不用二級快取?
不用:
1:關鍵性的金融性資料,是不用二級快取的。
工資表
2:私有,非共享性資料,是不使用二級快取。
Userinfo
用:
3:公共的,共享的,非關鍵性資料,使用二級快取、
資料字典表 民族 國家 省市區 型別
-------------------------------------------------------------------------------------------
****** Hibernate的快取[重點]
快取是位於應用程式和永久性資料儲存源之間用於臨時存放複製資料的記憶體區域,快取可以降低應用程式之間讀寫永久性資料儲存源的次數,從而提高應用程式的執行效能;
hibernate的快取大致可以分為兩級:一級快取【由session進行管理】 二級快取【由SessionFactory進行管理】和查詢快取【基於二級快取】
hibernate在查詢資料時,首先會到快取中查詢,如果找到就直接使用,找不到時才從永久性資料儲存源中檢索,因此,把頻繁使用的資料載入到快取中,可以減少應用程式對永久性資料儲存源的訪問,使應用程式的執行效能得以提升;
一級快取是Session級別的快取,它屬於事務範圍的快取,該級快取由hibernate管理,應用程式無需干預Hibernate的一級快取由Session提供,只存在於Session的生命週期中,當應用程式呼叫Session介面的save(),update(),saveOrupDate(),get(),load()或者Query和Criteria例項的list(),iterate()等方法時,如果Session快取中沒有相應的物件,hibernate就會把物件加入到一級快取中,當session關閉時,該Session所管理的一級快取也會立即被清除;
get/load方法讀寫快取
list方法會寫快取但是不讀快取
iterate方法會讀寫快取
Iterator<CatalogBean> it1 = session.createQuery("from CatalogBean").iterate();
1、傳送查詢,查詢滿足條件的id值;不像list()方法直接獲取的是物件。這裡實際上採用的是延遲載入的方式。
2、當訪問iterate()返回的代理物件時,才傳送按照id的查詢,獲取具體的物件
引發1+N問題:
例如查詢3個不同的物件,則iterate傳送了4條查詢語句,第一條是查詢id,後面則是按照id查詢對應的資料
多數在具體使用中一般不建議使用iterate,但是由於iterate方法可以讀寫快取,如果可以確定資料已經查詢過了,則使用iterate比list效率高
前面還講過一個1+N問題 OGN
from UserBean --當訪問role屬性時hibernate按照預設配置<many-to-one>中的fetch=select傳送對應的select語句載入對應的role屬性
針對load/get的解決方法
fetch改為join
解決方案使用迫切左外連結查詢
form UserBean u left join fetch u.role
Session介面為應用程式提供了兩個管理快取的方法:
evict(obj)方法:用於將某個物件obj從Session的一級快取中清除
clear()方法:用於將一級快取中的所有物件全部清楚
快取引發的問題:批量資料處理
方案1:使用HQL中的delete和update語句,這裡沒有insert
Query query = session.createQuery("update CatalogBean c set c.memo=?0 where c.id>?1");
query.setString(0, "新資料1");
query.setLong(1, 1L);
int len=query.executeUpdate();
session.createQuery("delete CatalogBean c where c.id>:id").setLong("id",1L).executeUpdate();
方法2:繞過hibernate而直接使用JDBC
方法3:使用StatelessSession ss=sessionFactory.openStatelessSession();
----------------------------
二級快取是一個可插拔的快取外掛,它是由SessionFactory負責管理的;
由於SessionFactory物件的生命週期與應用程式的整個過程對應,通常一個應用程式對應一個SessionFactory,因此,二級快取是程序範圍或者叢集範圍的快取;
與一級快取一樣,二級快取也是根據物件的id來載入與快取,當執行某個查詢獲得結果集為實體物件集時,hibernate就會把它們按照物件id載入到二級快取中,在訪問指定的id的物件時,首先從一級快取中查詢,找到就直接使用,找不到則轉到二級快取中查詢(必須配置且啟用二級快取),如果二級快取中找到,則直接使用,否則會查詢資料庫,並將查詢結果根據物件的id放到快取中;
Hibernate的二級快取功能是通過配置二級快取外掛來實現的,常用的二級快取外掛包括EHCache,OSCache,SwarmCache和JBossCache。其中EHCache快取外掛是理想的程序範圍的快取實現
如何配置ehcache快取
1、新增依賴
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>5.3.2.Final</version>
</dependency>
2、建立EHCache的核心配置檔案ehcache.xml
<ehcache>
<diskStore path="java.io.tmpdir"/>設定快取資料檔案的儲存目錄
<defaultCache 預設設定快取的預設資料過期策略
maxElementsInMemory="10000" 設定快取物件的最大數目
eternal="false" 指定是否永不過期,true為不過期,false為過期
timeToIdleSeconds="120" 設定物件處於空閒狀態的最大秒數
timeToLiveSeconds="120" 設定物件處於快取狀態的最大秒數
overflowToDisk="true" 設定記憶體溢位時是否將溢位物件寫入硬碟
/>
<cache name="sampleCache1" 設定具體的命名快取的資料過期策略。每個命名快取代表一個快取區域,命名快取機制允許使用者在每個類以及類的每個集合的粒度上設定資料過期策略
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="true"
/>
</ehcache>
3、在hibernate.cfg.xml配置檔案中,啟用EHCache的配置
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- 設定二級快取外掛EHCache的Provider類 -->
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
4、在實體類的對映中宣告併發訪問策略
xml配置:
<cache usage="read-write"/>
usage屬性取值為read-only時表示只讀型併發訪問策略;
read-write表示讀寫型併發訪問策略;
nonstrict-read-write表示非嚴格讀寫型併發訪問策略;
EHCache外掛不支援transactional(事務型併發訪問策略)
註解配置:
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
---------什麼時候使用二級快取?
經常查詢但很少修改的資料
資料量在可接受的範圍內
不會被第三方修改
非敏感資料
查詢快取: 按照查詢條件儲存查詢結果,需要基於二級快取