이 기사에서 필요한 초기 데이터베이스 파일, 공통 최대 절전 모드 작업에 대한 완전한 샘플 코드 (최대 절전 모드 작업에 필요한 모든 JAR 파일 포함)는 다운로드 및 학습을 위해 제공됩니다 : http://download.csdn.net/detail/daijin888888/9551724
1. 최대 절전 모드 연관 매핑
1) 연관 매핑이란 무엇입니까?
표 사이에 연관성이있는 경우 Hibernate를 사용하면 HBM.XML에서 연관성을 설명한 다음 테이블 중 하나를 작동 할 때이 관계에 따라 다른 관계 테이블에서 자동으로 작동 할 수 있습니다. 그런 다음이 연관 관계의 설정을 연관 매핑이라고합니다.
2) 연관 매핑의 이점은 무엇입니까?
여러 테이블은 한 번의 방문과 관련 될 수 있습니다
-관계 테이블 연관성의 데이터를 팔로우하십시오
-관계 테이블의 새롭고 수정 된 데이터를 연결합니다
-연관성 테이블에서 데이터를 삭제합니다
3) 협회 매핑 구현 단계
- 테이블 간의 관계를 이해하고 관계 분야를 명확히합니다.
-관련 데이터를 캡슐화하기 위해 엔티티 클래스의 협회 속성을 조정하십시오.
-hb.xml 파일을 구성하고 협회 관계를 설정해야합니다.
*2. 일대일 협회
예 : 계정에 여러 서비스 레코드가있는 경우 계정 데이터를 쿼리 할 때 해당 서비스 데이터를 자동으로 쿼리 할 수 있기를 바랍니다.
1) 테이블 관계
일대일 관계 인 관계 필드는 Service.account_id입니다. (즉, 서비스 테이블의 계정 테이블과 관련된 필드 계정 _id가 있어야 하며이 필드는 계정 테이블의 ID에 해당합니다).
2) 관계 속성을 추가하십시오
계정 클래스에서 유형 <service> 유형의 관련 속성 서비스를 추가하십시오.
개인 세트 <서비스> 서비스 = New Hashset <ervice> ();
3) 관계를 설정하십시오
--문법
계정에서 일대일 관계를 설정하십시오 .hbm.xml
<set name = "Association 속성 이름"> <key column = "Association Field Name"/> <일대일 many/> </set>-Implement <set name = "service"> <key column = "ac
4) 샘플 코드
알려진:
-관련 속성 서비스
-관련 필드 account_id
-협회 객체 서비스-> 테이블 이름 서비스
<span style = "font-size : 14px;"> public void testfind () {세션 세션 = hibernateutil.getSession (); 계정 a = (계정) 세션 .LOAD (Account.Class, 1010); System.out.println ( "--- 계정 계정 정보 표시 ----"); System.out.println (a.getid () + "" + a.getRealName () + "" + a.getIdcardNo ()); System.out.println ( "-현재 계정에 따른 비즈니스 계정을 표시 ----"; <service> services = a.getServices (); for (service s : services) {system.out.println (s.getid () + "" + s.getosusername () + "" + s.getunixhost ()); } system.out.println (a.toString ()); } </span>*3. 다국적 협회
예 : 서비스 데이터를 쿼리 한 후 해당 계정 데이터를 자동으로 쿼리 할 수 있기를 바랍니다.
1) 관계
서비스 및 계정은 다중 관계를 가지고 있으며 관계 필드는 Service.account_id입니다.
2) 관련 속성을 추가하십시오
-서비스 엔티티 클래스에서 관련 부동산 계정을 조정하면 해당 유형이 계정입니다.
개인 계정 계정;
그런 다음 AccountID 속성을 제거 할 수 있으며 GetAccount (). getId () 메서드를 통해 Account_ID의 값을 얻을 수 있습니다.
3) 관계를 설정하십시오
에이. 통사론:
-in service.hbm.xml, 협회 관계의 구성을 추가하십시오
-<다중 이름 = "협회 속성 이름"
열 = "관계형 필드 이름"
/>
비. 구현:
<많은 이름 = "계정"
column = "accound_id"
/>
4) 샘플 코드
알려진:
-해당 부동산 계정
-관련 필드 account_id
-Account-> 테이블 이름 계정, 기본 키 ID
<span style = "font-size : 14px;"> public void testfind () {세션 세션 = hibernateutil.getSession (); Service S = (Service) Session.get (Service.Class, 2002); System.out.println ( "---- 비즈니스 계정 정보 표시 ----"); System.out.println (s.getid () + "" + s.getosusername () + "" + s.getunixhost ()); System.out.println ( "--- 표시 관련 계정 정보 표시 ---"); System.out.println (s.getAccount (). getId () + "" + s.getAccount (). getRealName ()); } </span>*4. 관련 작업
1) 관련 쿼리
SQL 문을 사용하여 현재 객체와 관련 속성을 인스턴스화 해야하는 경우 다음 방법을 사용할 수 있습니다.
에이. (권장되지 않음) HBM.XML에서 관련 속성 매핑을 수정하십시오
게으른 속성 :
사실 게으른 하중이 활성화되어 있음을 의미합니다.
거짓은 게으른 하중을 닫는 것을 의미합니다
속성 가져 오기 :
결합은 연결 방법이 기본 객체를 쿼리하는 데 사용됨을 의미합니다. 현재 Lazy = "False"는 유효하지 않습니다.
선택 (기본값) 선택 (기본값)은 SQL 쿼리 관련 데이터를 별도로 전송하는 것을 의미합니다.
비. (권장) HQL을 통과하고 Fetch 구문에 가입하십시오
-계정에서 가입 A.Services a.id =?
의미 : 계정 개체를 쿼리 할 때 서비스 관련 속성 데이터는 테이블 연결을 사용하여 함께 찾을 수 있습니다.
-From Service S 가입 Fetch S.Account where S.Id =?
의미 : 서비스 개체를 쿼리 할 때 계정 관련 속성 데이터는 테이블 연결을 사용하여 함께 찾을 수 있습니다.
-From Service S 가입 Fetch S.Account where s.account.id =?
알아채다:
- 객체와 속성은 HQL로 작성됩니다
-join fetch는 그 후에 절에 없으며 페치는 관련된 속성입니다.
-Query.setInteger 정수 매개 변수 값을 설정하고 첨자는 0에서 시작합니다.
-HQL이 하나의 레코드 만 반환한다는 것이 분명하다면 query.uniqueresult () 메소드를 사용하여 고유 한 레코드를 반환 할 수 있습니다.
기음. 샘플 코드 (위의 일대일 협회 쿼리 코드를 다시 작성)
<span style = "font-size : 14px;"> public void testfind () {세션 세션 = hibernateutil.getSession (); // 계정 a = (계정) session.load (Account.Class, 1010); 문자열 HQL = "계정에서 조인 Fetch A.Services where a.id =?"; query query = session.createquery (HQL); query.setInteger (0, 1010); //?? 0 계정에서 시작합니다 a = (계정) query.uniqueresult (); // 단일 라인 쿼리는 System.out.println ( "--- 표시 계정 정보 ----")을 사용할 수 있습니다. System.out.println (a.getid () + "" + a.getRealName () + "" + a.getIdcardNo ()); System.out.println ( "--- 현재 계정에 대한 비즈니스 계정을 표시합니다 ----"); <service> services = a.getServices (); for (service s : services) {system.out.println (s.getid () + "" + s.getosusername () + "" + s.getunixhost ()); } system.out.println (a.toString ()); } </span> 2) 계단식 첨가 및 계단식 변형
에이. 표에 연관 관계가있는 경우 최대 절전 모드는 연관 쿼리의 기능을 제공 할뿐만 아니라 협회 테이블에서 데이터를 추가, 수정 및 삭제할 수 있습니다. 이 능력을 계단식 작동이라고합니다.
비. 계단식 작업을 구현하는 방법
관련 속성이 설정된 위치에 속성 캐스케이드를 추가해야합니다.
-아니요 : 기본적으로 계단식이 지원되지 않습니다
-Save Update : 계단식 추가 및 업데이트를 지원합니다
-delete : 계단식 삭제를 지원합니다
-모두 : 계단식 추가, 업데이트 및 삭제를 지원합니다
기음. 설명
일반적으로 1 대 마니 테이블 관계가 있습니다. 1의 한쪽은 메인 테이블이고 1의 다른 쪽은 슬레이브 테이블입니다. 주 테이블을 추가, 업데이트 및 삭제할 때 슬레이브 테이블 데이터를 추가, 업데이트 및 삭제해야합니다. 예를 들어, 계정을 삭제할 때 비즈니스 계정의 데이터를 함께 삭제해야합니다.
3) 캐스케이드 삭제
에이. 캐스케이드 삭제를 지원하려면 Cascade = "Delete"또는 Cascade = "All"을 설정하십시오
비. 일반적으로 1의 세트 태그에서 areverifice ververse = "true"를 추가해야합니다.
기음. SESSION.DELETE (OBJ); OBJ는 지속적인 객체 여야하며 새로울 수 없으며로드/검색해야합니다.
디. 배치 삭제 방법 :
계단식 삭제는 n+1 삭제 명령문을 사용하여 메인 테이블과 외국 키 테이블의 관련 데이터를 지우려고합니다.
배치 삭제 인 경우 계단식 삭제는 권장되지 않습니다. HQL을 사용하여 삭제 삭제 명령문을 작성하는 것이 좋습니다 .
ac 서비스 테이블에서 (이 문장은 계단식 작업에서 n 삭제 문을 대체합니다)
id = 어디에서 계정에서 삭제하십시오.
4) 역 속성 (이해) 세부 사항은 여기를 참조하십시오
관계 유지 관리 제어 여부. 즉, 기본적으로 계정과 서비스 개체 간의 관계는 양 당사자가 유지합니다. 이는 계정 또는 서비스 개체에서 계단식 작업을 수행 할 때 관련 필드를 동일한 ID로 설정하려면 업데이트 문을 실행해야합니다. 특정 당사자의 관계 유지 보수 작업을 취소 해야하는 경우 관련 속성 섹션에 inverse = "true"설정을 추가하여 업데이트 문의 실행을 피할 수 있습니다.
True : Hand Over Control, 현재 객체는 두 테이블 간의 관계를 유지할 책임이 없습니다.
False : 컨트롤은 양도되지 않으며, 현재 객체는 두 테이블 간의 관계를 유지해야합니다.
팁 : 한 당사자 (즉, <일대일 매핑 부품)에 대해 (즉, <10 맵핑 부품)을 역 = "true"에 대해서는 종종 = "true"로 설정되므로 한 당사자의 계단식 작업을 할 때 많은 수의 업데이트 업데이트 문을 피할 수 있습니다.
*5. 다수의 협회
예 : admin admin_info 및 역할 role_info는 다량의 관계가 있습니다. 관리자를 쿼리 할 때 해당 역할을 쿼리 할 수 있기를 바랍니다. 데이터베이스를 설계 할 때는 3 개의 테이블을 사용하여 표현해야합니다.
admin_info (관리자)
admin_role (관리자 및 역할 관계)
역할 (역할)
1) 관계 분야
관계 필드는 중간 테이블 admin_role에 있습니다.
admin_id = admin_info.id
role_id = roby_info.id
2) 관련 속성을 부여하여 관리자의 엔티티 클래스에 역할 관련 속성을 부여합니다.
<역할> 역할을 설정하십시오
3) admin.hbm.xml의 협회 매핑 구성을 추가하십시오
-syntax <set name = "Association 속성 이름"테이블 = "중간 테이블 이름"> <key column = "admin의 관련 필드 이름"/> <admin의 관련 필드 이름 "/> </set>-코드 <세트 이름 ="role "테이블 ="admin_role "> <key column ="admin_id "/>
4) 캐스케이드 작업
캐스케이드는 캐스케이드 작업이 지원되고 테이블은 중간 계단사 작업 테이블을 나타내지 않고 다른 쪽에서 작동 함을 의미합니다. 중간 테이블의 유지 보수를 위해 캐스케이드 속성을 작성할 필요가 없습니다.
5) 역전
일반적으로 말하면, 다수의 관계는 반대 = "true"를 작성할 필요가 없습니다. 그 이유는 상대방이 데이터를 삽입 할 때 중간 테이블에 데이터가 없을 수 있으며 현재 당사자는이를 유지해야하기 때문입니다. 따라서 inverse = "true"는 쓸 수 없습니다. 그렇지 않으면 어느 당사자 도이 관계를 유지하지 않으며 데이터에 문제가 있습니다.
6) 샘플 Java 코드
<span style = "font-size;"> // 역할 제거 @Test public void testDeleterole () {세션 세션 = hibernateUtil.getSession (); 트랜잭션 tx = session.begintransaction (); try {admin a = (admin) session.load (admin.class, 1); 역할 R1 = (역할) 세션 .LOAD (역할 .class, 1); a.getRoles (). 제거 (r1); 세션 .update (a); tx.commit (); } catch (HibernateException e) {e.printstacktrace (); tx.rollback (); } 마침내 {session.close (); }} // Append 역할 @test public void testAddrole () {세션 세션 = hibernateUtil.getSession (); 트랜잭션 tx = session.begintransaction (); try {admin a = (admin) session.load (admin.class, 1); 역할 R1 = (역할) 세션 .LOAD (역할 .class, 1); 역할 R2 = (역할) 세션 .LOAD (역할 .class, 43); 역할 R3 = (역할) 세션 .LOAD (역할 .class, 44); a.getRoles (). add (r1); a.getRoles (). add (r2); a.getRoles (). add (r3); 세션 .update (a); tx.commit (); } catch (HibernateException e) {e.printstacktrace (); tx.rollback (); } 마침내 {session.close (); }} @test public void testfind () {세션 세션 = hibernateutil.getSession (); 트랜잭션 tx = session.begintransaction (); try {admin a = (admin) session.load (admin.class, 1); System.out.println ( "----- Show Administrator Information ----"); System.out.println (a.getid () + "" + a.getName () + "" + a.getTelephone ()); System.out.println ( "---- 관리자 역할 정보 표시 ---"); for (역할 역할 : a.getRoles ()) {System.out.println (역할 .getName () + ""); } tx.commit (); } catch (HibernateException e) {e.printstacktrace (); tx.rollback (); } 마침내 {session.close (); }} </span>6. 상속 협회
예 : 검색을 위해 iPhone 입력과 같은 전자 상거래 웹 사이트에서 제품을 검색하십시오. 검색 결과에는 휴대 전화, 휴대 전화 필름, 휴대 전화 케이스, 충전기, 헤드폰 등과 관련된 제품 정보가 포함될 수 있습니다.이 기능은 테이블을 설계 할 때 특별한 일대일 관계로 표현할 수 있습니다. 즉, 모든 제품의 일반적인 속성은 공통 테이블 제품으로 추출됩니다. 특정 제품 테이블 만 특정 제품 테이블에 저장되므로 특정 제품 테이블과 제품 테이블은 일대일 관계가 있습니다. 검색 할 때 제품 테이블 만 검색 할 수 있으며 관련 정보를 검색 할 수 있습니다.
-일반 정보 테이블 제품 (ID, 이름, 가격, DESC)
-책 제품 목록 책 (ID, Authod, Publishing, Words)
-책 테이블을 작동 할 때는 공통 필드를 제품 테이블에 자동으로 유지할 수 있기를 바랍니다.
1) 명확한 관계
책과 제품은 일대일 관계가 있습니다. 이 관계의 목적은 상속 관계와 같은 제품 테이블의 필드를 재사용하는 것입니다.
2) 엔티티 클래스
책은 제품을 확장합니다
3) 관련 관계는 구성 파일에 반영됩니다
-부모 유형은 원래 구성 파일 쓰기 방법과 일치합니다.
-서브 타입에는 특별한 특성이 있습니다
<joined-subclass name = "type name"table = "테이블 이름"확장 = "부모 클래스 이름"> <키 열 = "협회 필드 이름"/> <속성 이름 = ""type = ""column = ""/> ... </join-subclass>
4) 상속 관계에서 두 테이블이 부모 및 자식과 유사한 관계를 갖기 때문에 부모 테이블의 데이터는 아동 테이블에서 참조되어야합니다. 비 참조 사례는 없습니다. 즉, 아동 테이블을 유지하는 동안 부모 테이블을 유지해야합니다. 따라서 이것은 고정 된 상황이므로 캐스케이드 나 역을 쓸 필요가 없습니다.
5) 설명 카테고리 (이해)
<Boined-Subclass> 데이터베이스에는 부모 수업 테이블과 아동 수업 테이블이 있습니다.
<Union-Subclass> 데이터베이스에는 서브 클래스 테이블이 있고 상위 클래스 테이블이 없습니다 (서브 클래스 테이블에는 이미 부모 클래스 테이블 필드, 부모 클래스 테이블이 없지만 부모 클래스 엔티티 객체가 있습니다)
<서브 클래스> 데이터베이스에는 상위 클래스와 아동 클래스가 있으며 테이블을 사용합니다 (디자인은 지저분합니다. 즉, 테이블 분할이 없으며 거의 사용되지 않습니다).
*7. 최대 절전 모드 쿼리
1) *HQL 쿼리 (최대 절전 모드 쿼리 언어)
객체 지향 쿼리 문에 속하며 최대 절전 모드로 매핑 된 POJO를 쿼리하여 데이터베이스를 쿼리하는 것을 실현합니다.
에이. 비 예약 키를 사용하여 조건부 쿼리를 만듭니다
-조건부 매개 변수? query.setString (0, "")을 나타냅니다.
-조건부 매개 변수는 다음과 같이 표시됩니다. x, query.setString ( "x", "");
샘플 코드 :
<span style = "font-size : 14px;"> // 비 예정된 키 @Test 공개 void testfind1 () {string hql = "ac 세션 세션 = hibernateutil.getSession (); query query = session.createquery (HQL); query.setinteger (0, 1011); Query.setString (1, "192.168.0.23"); List <ervice> list = query.list (); for (service s : list) {system.out.println (s.getId () + "" " + s.getosuserName () +" " + s.getUnixHost ()); } session.close (); } // @test 대신 ": evidier"를 사용하여 testfind1과 동일합니다. @test public void testfind2 () {string hql = "service에서 ac 세션 세션 = hibernateutil.getSession (); query query = session.createquery (HQL); Query.setInteger ( "AID", 1011); Query.setString ( "호스트", "192.168.0.23"); List <ervice> list = query.list (); for (service s : list) {system.out.println (s.getId () + "" " + s.getosuserName () +" " + s.getUnixHost ()); } session.close (); } </span> 비. 일부 속성 만 쿼리합니다
-캡슐화 된 기본 반환 수집은 Object []입니다.
-새로운 서비스 (id, unixhost, osusername)는 반환 된 조합으로 서비스 객체를 캡슐화합니다.
알아채다:
서비스에서 응답을 추가 해야하는 생성자;
매개 변수가없는 생성자를 버리지 마십시오.
샘플 코드 :
<span style = "font-size : 14px;"> // 일부 필드 결과를 얻고 객체 []를 사용하여 기본적으로 데이터를 캡슐화하여 @test public void testfind3 () {string hql = "SELECT S.ID, S.UNIXHOST, SERVICE S S.ACCOUNT.id =?"; 세션 세션 = hibernateutil.getSession (); query query = session.createquery (HQL); query.setinteger (0, 1011); 목록 <object []> list = query.list (); for (object [] objs : list) {system.out.println (objs [0] + "" + objs [1] + "" + objs [2] + ""); } session.close (); } // TestFind3에 해당하는 경우 해당 생성자 @Test Public void TestFind4 () {String HQL = "SELLECT S.ACCOUNT.ID =?"; 세션 세션 = hibernateutil.getSession (); query query = session.createquery (HQL); query.setinteger (0, 1011); List <ervice> list = query.list (); for (service s : list) {system.out.println (s.getId () + "" " + s.getosuserName () +" " + s.getUnixHost ()); } session.close (); } </span> 기음. HQL 정의는 구성 파일에 있습니다 (이해하기 만하면)
-쿼리 요소를 통해 구성 파일의 hql을 정의합니다
-쿼리 요소는 수업 뒤에 쓰여집니다
-session.getNamedQuery (HQL Name);
샘플 코드 : <query/> 및 <class/>는 동일한 수준에서 HBM.XML에 배치됩니다.
<span style = "font-size;"> <query name = "findall"> <!-특수 문자를 방지하기 위해 cdata에 일반 텍스트 필드를 포함시킵니다-> <! testfind5 () {세션 세션 = hibernateutil.getSession (); // hbm.xml query query = session.getNamedQuery ( "findAll")에서 <query>에 정의 된 HQL 문을 가져옵니다. List <ervice> list = query.list (); for (service s : list) {system.out.println (s.getId () + "" " + s.getosuserName () +" " + s.getUnixHost ()); } session.close (); } </span> 디. 페이지 매김 쿼리
-쿼리 기록
query.setfirstresult ((Page-1)*pagesize);
query.setmaxresults (pagesize);
-총 페이지 수를 정리하십시오
서비스에서 카운트 (*)를 선택하십시오
샘플 코드 :
<span style = "font-size : 14px;"> // 테스트 페이징 쿼리 @test public void testfind6 () {int page = 2; 문자열 HQL = "ID에 의한 서비스 순서에서"; 세션 세션 = hibernateutil.getSession (); query query = session.createquery (HQL); // query.setfirstresult ((Page -1) * 3)을 설정하기 위해 페이징 매개 변수를 추가하십시오. // 0 query.setMaxResults (3)에서 시작하여 레코드 잡기 시작점을 설정합니다. System.out.println (s.getid () + "" + s.getosusername () + "" + s.getunixhost ()); } session.close (); } // 서비스에서 count (*)를 선택하십시오 @Test public void testfind7 () {String Hql = "SELECT COUNT (*) Service"; 세션 세션 = hibernateutil.getSession (); query query = session.createquery (HQL); 긴 크기 = (long) query.uniqueresult (); System.out.println ( "총 레코드 수 :" + 크기); session.close (); } </span> 이자형. 관련 쿼리 (그냥 기억하십시오)
-서비스 S, 계정 a
여기서 s.account.id = a.id
-From Service S Inner Join S.Account a
-서비스에서 s.account.realName을 선택하십시오
요약 :
HQL과 SQL의 유사성 :
-support select, from, where, group, 주문 별 절
-지원 내부 조인, 왼쪽 조인 및 기타 연결
-support>, <,> =, <=, in, in, in, like 및 기타 조건
-지원 그룹화 통계 함수 count, sum, max, min, avg
HQL과 SQL의 차이점 :
-HQL 문은 사례에 민감합니다. 즉, 사례에 민감합니다. 키워드는 구별 할 수 없습니다.
-HQL은 테이블 이름 및 필드 이름이 아닌 객체 이름 및 속성 이름을 씁니다.
-on on on on on on은 지원되지 않습니다
-선택되지 않은 *
-domain 함수는 날짜 함수 to_date (), 문자 함수 to_char () 등과 같은 지원되지 않습니다.
2) 기준 쿼리 (직관적이지 않고 이해하기 만하면)
최대 절전 모드 API를 사용하여 HQL을 철자하십시오
기준 C = 세션 .CreateCriteria (Service.Class);
샘플 코드 :
<span style = "font-size : 14px;"> // Hibernate의 API를 사용하여 HQL @test public void testfind1 () {세션 세션 = hibernateutil.getSession (); 기준 C = 세션 .CreateCriteria (Service.Class); c.add (제한. 및 (제한. sort // c.setfirstresult (arg0); // pagination // c.setmaxresults (arg0); for (service s : list) {system.out.println (s.getId () + "" " + s.getosuserName () +" " + s.getUnixHost ()); } session.close (); } </span> 3) SQL 쿼리
SQL 쿼리를 실행하려면 JDBC에 전화를 걸도록 직접 도와주세요
sqlquery sqlquery = session.createsqlquery (SQL);
샘플 코드 :
<span style = "font-size : 14px;"> @test public void testfind1 () {string sql = "select * from service"; 세션 세션 = hibernateutil.getSession (); sqlquery sqlquery = session.createsqlquery (SQL); sqlquery.setfirstresult (0); // Pagination sqlquery.setMaxResults (3); // 기본적으로 배열은 레코드 목록을 캡슐화하는 데 사용됩니다. <object []> list = sqlquery.list (); for (object [] objs : list) {system.out.println (objs [0] + "" + objs [2]); } session.close (); } // testfind1 ()과 동일하게 @test public void testfind2 () {string sql = "select * service"; 세션 세션 = hibernateutil.getSession (); sqlquery sqlquery = session.createsqlquery (SQL); sqlquery.setfirstresult (0); // Pagination sqlquery.setMaxResults (3); // 레코드 sqlquery.addentity (service.class)를 캡슐화하는 엔티티 클래스를 지정합니다. // 지정된 서비스 유형 목록으로 레코드를 캡슐화하십시오 <service> list = sqlquery.list (); for (service s : list) {system.out.println (s.getid () + "" + s.getosusername ()); } session.close (); } </span>8. 최대 절전 모드 고급 기능 (이해)
1) 레벨 2 캐시
에이. 레벨 2 캐시 (기본 끄기)
-두 번째 레벨 캐시는 SessionFactory에서 관리하는 SessionFactory 레벨 캐시입니다.
-캐시 된 객체는 또한 엔티티 객체입니다
-다양한 세션간에-성장한 데이터를 공유 할 수 있습니다
-적용 가능한 환경 : 자주 공유되는 객체 데이터; 객체 데이터 변경의 작은 빈도
비. 레벨 2 캐시 사용 단계
-디라 캐시 패키지 ehcache.jar
-임계 캐시 구성 파일 ehcache.xml
-in hibernate.cfg.xml, 보조 캐시를 활성화하고 캐시 드라이버 클래스를 설정하도록 설정했습니다.
<span style = "font-size : 14px;"> <!-레벨 2 캐시 사용-> <property name = "hibernate.cache.use_second_level_cache"> true </property> <!-드라이버 클래스 ehcache.jar-> <속성을 지정하십시오. 이름 = "hibernate.cache.provider_class"> org.hibernate.cache.ehcacheprovider </property> </span>
-관계형 매핑 파일에서 요소를 세트로, pojo의 hbm.xml <cache usage = "readonly"/>
샘플 코드 :
<span style = "font-size : 14px;"> <span style = "font-size;"> @test public void testfind1 () {// 첫 번째 쿼리의 경우 세션 세션 1 = hibernateutil.getSession (); Service S1 = (서비스) 세션 1.get (Service.Class, 2002); System.out.println (s1.getosusername () + "" + s1.getunixhost ()); 세션 1.close (); // 두 번째 쿼리는 Session2를 사용합니다 (보조 캐시를 구성한 후 두 쿼리는 2 차 캐시로 이동하여 데이터를 가져 오기 위해) // hibernateUtil.getSessionFactory (). Evict (service.class); // 쿼리 후에도 두 번 쿼리. 세션 세션 2 = hibernateutil.getSession (); Service S2 = (Service) Session2.get (Service.Class, 2002); System.out.println (s2.getosusername () + "" + s2.getunixhost ()); } </span> </span> 2) 쿼리 캐시
에이. 쿼리 캐시
레벨 1 및 레벨 2 캐시는 단일 객체 만 캐시 할 수 있습니다. 문자열 결과, 배열 결과 또는 목록 컬렉션이 발생하면 쿼리 캐시 스토리지를 사용할 수 있습니다.
-특수 레벨 2 캐시로 간주 될 수 있습니다.
-사용 된 캐시 공간은 두 번째 레벨 캐시입니다
-캐시는 엔티티 객체가 아닌 다른 데이터 유형입니다.
-레벨 2 캐시를 사용하면 기본적으로 꺼져 있으며 사용하기 전에 레벨 2 캐시를 켜야합니다.
비. 단계를 사용하십시오
-레벨 2 캐시를 시작합니다
-hibernate.cfg.xml에서 열린 쿼리 캐시를 설정하십시오
<span style = "font-size : 14px;"> <!-쿼리 캐시를 켜십시오-> <속성 이름 = "hibernate.cache.use_query_cache"> true </property> </span>
쿼리 전에 -query.list (), query.setCachable (true);
기음. 사용 환경
-자주 실행 해야하는 동일한 쿼리 문
-쿼리 결과 컨텐츠 세트 컨텐츠는 주파수를 작게 변경합니다
-결과 세트에 데이터가 너무 많지 않습니다. 팁 : 동일한 SQL의 경우 처음으로 데이터베이스로 이동하여 쿼리를하고 나중에 여러 번 캐시에서 벗어나십시오. SQL+ 결과 세트의 내용이 캐시되기 때문입니다
샘플 코드 :
<span style = "font-size : 14px;"> <span style = "font-size;"> @test public void testfind () {find (); System.out.println ( "-------"); 찾다(); } private void find find () {string hql = "service에서 account.id =?"; 세션 세션 = hibernateutil.getSession (); query query = session.createquery (HQL); query.setinteger (0, 1011); // 쿼리 캐시 활성화 실행 query.setCachable (true); List <ervice> list = query.list (); for (service s : list) {system.out.println (s.getid () + "" + s.getosusername ()); }} </span> </span>9. 동시 처리 잠금
예를 들어:
현재 10306 티켓 구매 메커니즘을 시뮬레이션하십시오. 현재 기차 티켓의 티켓 티켓 (ID, 라인, 금액, 버전)이 있다고 가정하고 여러 사람이 동시에 티켓을 구매하는 시나리오를 시뮬레이션하십시오.
1) 비관적 잠금
-이 프로그램은 모든 방문자가 동시성 문제가 있으므로 비관적이므로 각 데이터가 잠겨 있습니다. 그런 다음 현재 잠금 장치를 잡고있는 방문자가 잠금을 풀면 다음 방문자가 데이터에 액세스 할 수 있습니다. 이 메커니즘을 비관적 잠금 장치라고합니다.
즉, 데이터가 동시성을 갖는 지 여부에 관계없이 무엇이든 관계없이 데이터를 잠그어야합니다.
--특징
낮은 효율과 높은 안전성
--성취하다:
get (class, id, lockmode.upgrade)
업데이트를 위해 EMP에서 *를 선택하십시오
참고 : 여기서 우리는 최대 절전 모드 자체가 발명 한 잠금 메커니즘이 아니라 잠금을위한 데이터베이스와 함께 제공되는 For Update 절을 사용합니다.
2) 낙관적 잠금
-이 프로그램은 모든 방문자가 동시 문제를 겪지 않을 것이라는 낙관적이므로 잠금 장치를 추가하지 않습니다. 대신 데이터가 업데이트되면 데이터 버전이 변경되었는지 여부가 결정됩니다. 변경되면이 기간 동안 동시 발생이 있음을 의미합니다. 따라서 오류 가보고되어 업데이트가 실패했습니다.
-버전 필드의 도움을 받으면 첫 번째 사용자가 업데이트하고 제출할 때 Hibernate는 필드를 1 씩 업데이트하여 후속 사용자가 제출 한 객체 버전 필드가 데이터베이스의 것보다 작습니다. 즉, 버전이 업데이트 중에 변경되는 경우 예외가 발생하고 업데이트가 실패합니다.
-하나의 성공, 다른 사람들은 실패합니다
--특징
높은 효율성, 불량한 사용자 경험
--성취하다
에이. 데이터 버전을 기록하려면 버전 필드를 테이블에 추가해야합니다.
비. 엔티티 클래스에 버전 속성을 추가하십시오.
기음. hbm.xml <버전 이름 = ""type = ""column = "">의 추가 버전 구성.
3) 선택 방법
-동시성이 크면 낙관주의 잠금을 선택해야합니다.
-동시성이 작 으면 비관적 잠금을 선택해야합니다.
위의 내용은 편집자가 소개 한 최대 절전 모드 관련 작업, 쿼리 작업, 고급 기능 및 동시성 처리 메커니즘에 대한 포괄적 인 분석입니다. 나는 그것이 당신에게 도움이되기를 바랍니다. 궁금한 점이 있으면 메시지를 남겨 주시면 편집자가 제 시간에 답장을 드리겠습니다. Wulin.com 웹 사이트를 지원해 주셔서 대단히 감사합니다!