mybatis 프레임 워크 실행 프로세스 :
1. myBatis 구성 파일, sqlmapconfig.xml 구성 (이름은 고정되지 않음)
2. 구성 파일을 통해 MyBatis 실행 환경을로드하고 SQLSESSIONFACTORY SESSION FACTORY를 만듭니다.
sqlsessionfactory는 실제로 사용될 때 싱글 톤 방식으로 사용됩니다.
3. sqlsessionfactory를 통해 sqlsession을 만듭니다
sqlsession은 사용자 지향 인터페이스 (운영 데이터베이스 방법 제공)입니다. 구현 오브젝트는 스레드 inscure입니다. SQLSession의 응용 프로그램 시나리오는 메소드 본문 내에있는 것이 좋습니다.
4. 데이터를 조작하려면 sqlsession 메소드를 호출하십시오.
거래를 커밋 해야하는 경우 SQLSESSION의 Commit () 메소드를 실행해야합니다.
5. 리소스를 릴리스하고 SQLSESSION을 닫습니다
맵퍼 에이전트 개발 방법 (권장)
프로그래머 만 Mapper 인터페이스를 작성하면됩니다 (즉, DAO 인터페이스).
Mapper.xml (매핑 파일) 및 mapper.java를 작성할 때 프로그래머는 개발 사양을 따라야합니다.
1. Mapper.xml의 네임 스페이스는 Mapper.java 클래스의 전체 경로입니다.
2. mappper.xml의 문의 ID는 mappper.java의 메소드 이름과 동일합니다.
3. mapper.xml에서 문의 매개 변수 유형은 입력 매개 변수의 유형과 mapper.java 메소드의 입력 매개 변수 유형을 지정합니다.
4. Mapper.xml의 명령문의 결과 유형은 출력 유형과 Mapper.java 메소드의 리턴 값 유형을 지정합니다.
이 기사의 내용 :
주문 제품 데이터 모델을 분석하십시오.
고급 매핑 : (배우기)
일대일 쿼리, 일대일 및 다수의 쿼리를 구현하십시오.
지연 로딩
쿼리 캐시
레벨 1 캐시
레벨 2 캐시 (MyBatis 레벨 2 캐시의 사용 시나리오 이해)
Mybatis 및 Spirng 통합 (마스터)
리버스 엔지니어링 (사용할 수 있음)
제품 데이터 모델을 주문하십시오
데이터 모델 분석 아이디어
1. 각 테이블에 기록 된 데이터 컨텐츠
모듈별로 각 테이블에 기록 된 컨텐츠에 익숙한 것은 학습 시스템 요구 사항 (기능) 과정과 같습니다.
2. 각 테이블에 대한 중요한 필드 설정
비어 있지 않은 필드, 외국 키 필드
3. 데이터베이스 레벨 테이블 간의 관계
외국의 주요 관계
4. 테이블 간의 비즈니스 관계
테이블 간의 비즈니스 관계를 분석 할 때는 특정 비즈니스 중요성에 따라 테이블을 분석해야합니다.
데이터 모델 분석
사용자 테이블 사용자 :
구매 한 제품의 사용자 정보를 기록하십시오
주문 테이블 : 주문
사용자가 작성한 주문을 기록합니다 (항목 구매 주문)
주문 세부 사항 : OrderDetail :
주문의 자세한 정보, 즉 구매 정보를 기록하십시오.
제품 목록 : 항목
기록 된 제품 정보
테이블 간의 비즈니스 관계 :
테이블 간의 비즈니스 관계를 분석 할 때는 특정 비즈니스 중요성에 따라 테이블을 분석해야합니다.
먼저 데이터 수준 간의 관계가있는 테이블 간의 비즈니스 관계를 분석하십시오.
USRE 및 주문 :
사용자 —-> 주문 : 사용자는 여러 주문을 1-10으로 생성 할 수 있습니다.
ORDERS -> 사용자 : 주문은 하나의 사용자 만 생성합니다.
주문 및 주문화 :
Orders> OrderDetail : 주문에 여러 주문 세부 사항이 포함될 수 있습니다. 한 주문은 여러 항목을 구매할 수 있고 각 항목의 구매 정보는 OrderDetail, 1-Many 관계에 기록됩니다.
OrderDetail> 주문 : 주문 세부 사항은 한 순서로만 포함될 수 있습니다.
OrderDetail 및 itemsm :
OrderDetail-> itemsms : 하나의 주문 세부 사항은 하나의 제품 정보에만 해당합니다.
항목> 주문화 테일 : 제품은 여러 주문 세부 사항에 포함될 수 있습니다.
그런 다음 데이터베이스 수준과 관련이없는 테이블간에 비즈니스 관계가 있는지 여부를 분석하십시오.
주문 및 항목 :
주문과 항목의 관계는 OrderDetail 테이블을 통해 설정할 수 있습니다.
사용자 및 항목 : 다른 테이블을 통해 다수의 관계를 구성합니다.
일대일 쿼리
요구 사항 : 주문 정보 쿼리 및 주문 생성을위한 쿼리 사용자 정보를 연결합니다.
결과 유형을 사용하여 쿼리하십시오
SQL 문의 사용에 대한 고려
쿼리의 기본 테이블 : 주문 테이블을 결정하십시오
쿼리 : 사용자 테이블의 연관성 테이블을 결정하십시오
협회 쿼리는 내부 링크 또는 외부 링크를 사용합니까?
Orders 테이블에는 외국 키 (user_id)가 있으므로 외국 키 연관을 통해 사용자 테이블을 쿼리하면 하나의 레코드 만 찾을 수 있으며 내부 링크를 사용할 수 있습니다.
주문을 선택하십시오.*, user.username, user.sex, user.address, user where orders.user_id = user.id
pojo 만들기 (OrdersCustom.java)
위의 SQL 쿼리의 결과를 pojo에 매핑하는데, 여기에는 모든 쿼리 열 이름이 포함되어야합니다.
원래의 Orders.java는 모든 필드를 매핑 할 수 없으며 새로 생성 된 Pojo가 필요합니다.
많은 쿼리 필드가 포함 된 PO 클래스를 상속하는 PO 클래스를 만듭니다.
OrdersMapperCustom.xml
OrdersMapperCustom.java
테스트 수업을 작성하십시오
OrdersMapperCustom.java 파일을 마우스 오른쪽 버튼으로 클릭하십시오. 새> Other> Junit 테스트 케이스> 테스트 기능 선택
OrdersMapperCustomTest.java에 다음 코드를 작성하십시오.
public class ordersmappercustomtest {private sqlsessionfactory sqlsessionfactory; //이 메소드는 @beforepublic void setup ()를 실행하는 것입니다 {// sqlsessionfactory // myBatis 구성 파일 string resource = "sqlmapconfig.xml"; resources.getResourCeasStream (Resource); // 세션 공장 생성 및 MyBatis 구성 파일 정보 SQLSESSIONFACTORY = NEW SQLSESSIONFACTORYBUILDER (). 빌드 (inputStream);}@testPuboid testFindordersUser () 예외 {sqlsessionsestionestions (sqlsestionsionsession); 프록시 객체 OrdersMapperCustom OrdersMapperCustom = SQLSESSION.GETMAPPER (OrdersMapperCustom.class); // Call Mapper 메소드 목록 <ordersCustom> list = OrdersMapperCustom.findordersUser (); System.out.println (list); sqlsession.close ();};Query에 resultMap을 사용하십시오
SQL 문 : SQL은 동일한 결과 유형에서 구현되었습니다
결과 맵 매핑 사용에 대한 아이디어
query result의 주문 정보를 주문 객체에 맵핑하고 Orders Class의 사용자 속성을 추가 한 다음 관련 쿼리 사용자 정보를 Orders Object의 사용자 속성에 매핑합니다.
Orders 클래스에 사용자 속성을 추가하십시오
OrdersMapperCustom.xml
결과 맵을 정의하십시오
TYEP : 전체 쿼리의 결과를 특정 클래스에 매핑하는 수단 예를 들어 : CN.ITCast.mybatis.po.orders
ID : 주문 정보의 고유 식별자 인 데이터베이스 테이블의 쿼리 열의 고유 식별자를 나타냅니다. 고유 식별자를 형성하는 여러 열이있는 경우 여러 ID를 구성하십시오.
열 : 데이터베이스 테이블의 주문 정보에 대한 고유 식별 열
속성 : 주문 정보의 고유 식별 열에 의해 어떤 속성이 주문에 매핑됩니까?
협회 : 개별 객체 쿼리를위한 정보를 매핑하는 데 사용됩니다
속성 : 관련 쿼리의 사용자 정보를 매핑하기위한 주문의 속성
Javatype : 사용자에게 매핑 된 속성
<!-관련 사용자의 결과 맵은 전체 쿼리의 결과를 cn.itcast.mybatis.po.orders-> <resultmap type = "cn.itcast.mybatis.po.orders"id = "ordersuseResultMap"> <! <! <!-id : 고유 한 식별자에 대한 quight excentifer에서 구성합니다. 고유 한 식별자를 형성하기위한 여러 열이있는 경우 여러 IdColumn을 구성하십시오. 주문 정보의 고유 식별 열 : 주문 정보의 고유 한 식별자 열의 고유 한 식별자 열에 따라 맵핑되는 속성-> <id 열 = "id"속성 = "id" /> <결과 열 = "user_id"property = "userId" /> <result column = "number" /> <result colment = "productime =" "freateTime =" "reculation" "number" "number" column = "note"propertion = note/> <!-매핑 된 관련 사용자 정보를 구성-> <!-협회 : 관련 쿼리 단일 객체 속성을 매핑하는 데 사용되는 정보 : 관련 쿼리의 사용자 정보를-> <anspociTed property = "user"javatype = "cn.itcast.mybatis.po.user에 매핑하기 위해 어떤 속성을 매핑하는지. javatype : 사용자에게 매핑 된 속성 -> <id 열 = "user_id"property = "id"/> <result column = "username"property = "username"/<result column = "sex"property = "sex"/> <result column = "propert"= "address"/> <</협회> </resultmap>
진술 정의
OrdersMapperCustom.java
테스트 코드
@TestPublic void testFindorsSuserResultMap ()는 예외를 {sqlsession sqlsession = sqlsessionfactory.opensession (); // 프록시 객체 작성 mapperCustom OrdersMapperCustom = sqlsession.getMapper (OrdersMapperCustom.class); // call mapper list = sqlsession. OrdersMapperCustom.findordersUserResultMap (); System.out.println (list); sqlsession.close ();}resulttype 및 resultmap은 일대일 쿼리 요약을 구현합니다
resultType : resultType를 사용하여 구현하는 것은 비교적 간단합니다. 쿼리 열 이름이 pojo에 포함되지 않은 경우 매핑을 완료하려면 열 이름의 해당 속성을 추가해야합니다.
쿼리 결과에 대한 특별한 요구 사항이없는 경우 resulttype를 사용하는 것이 좋습니다.
ResultMap : resultMap은 별도로 정의해야하며 이는 약간 번거로움입니다. 쿼리 결과에 대한 특별한 요구 사항이있는 경우 resultMap을 사용하면 관련 쿼리 매핑 pojo의 속성을 완성 할 수 있습니다.
ResultMap은 게으른 하중을 구현할 수 있으며 결과 유형은 게으른 하중을 구현할 수 없습니다.
일대일 쿼리
요구 사항 : 주문 및 주문 세부 정보 정보.
SQL 문
기본 쿼리 테이블 : 주문 테이블을 결정하십시오
관련 쿼리 테이블 : 주문 세부 사항 테이블을 결정하십시오
일대일 쿼리를 기반으로 주문 세부 사항 목록 협회를 추가하십시오.
selectorders.*, user.username, user.sex, user.address, orderdetail.id orderdetail_id, orderdetem.items_id, orderdetail.items_num, orderdeteam.orders_idfromorders, userdetwhere orders.user_id = user.id 및 orderdetail.ords = Orders
분석 : resultType를 사용하여 위의 쿼리 결과를 pojo에 매핑하고 주문 정보는 복제입니다.
요구 사항 : 주문 매핑에 대해서는 중복 레코드가 발생할 수 없습니다.
Orders.java 클래스에 <stepledetail> orderdetails 속성 목록을 추가하십시오.
마지막으로, 주문 정보는 주문에 매핑되며 주문에 해당하는 주문 세부 사항은 OrderDetails 속성에 주문됩니다.
매핑에 기록 된 주문 수는 두 가지입니다 (주문 정보는 반복되지 않음)
각 주문의 OrderDetails 속성은 주문에 해당하는 주문 세부 사항을 저장합니다.
Orders.java에 목록 주문 세부 사항 속성을 추가하십시오
OrdersMapperCustom.xml
결과 맵 정의
사용 주문 정보 및 사용자 정보의 매핑을 구성하지 않고 상속을 사용합니다.
수집 : 협회 쿼리의 수집 객체에 매핑 할 여러 레코드 쿼리
속성 : 협회 쿼리를 여러 레코드에 cn.itcast.mybatis.po.orders에 매핑하십시오.
oftype : 목록 수집 속성에서 pojo에 맵핑되는 유형을 지정합니다.
<!-주문 및 주문 세부 사항에 대한 결과 맵은 확장을 사용하여 상속되며, 주문 정보 및 사용자 정보의 매핑을 구성 할 필요가 없습니다 .-> <resultmap type = "cn.itcast.mybatis.po.orders"id = "ordersandorderDoderDorderDorderDoderDetailResultMap"extends = "orderSeResultMap"-<! <! <! <! <! <! <! <! 상속, 주문 정보 및 사용자 정보의 매핑을 구성 할 필요는 없습니다 .-> <!-주문 세부 정보 주문 협회 쿼리에는 여러 세부 사항이 있습니다. 컬렉션 컬렉션을 사용하여 컬렉션 컬렉션에 여러 레코드를 맵핑하여 컬렉션 객체 속성에 대한지도 쿼리 : cn.itcast.mybatis.po.orders의 속성에 대한 여러 레코드에 대한지도 쿼리 : collection 속성을 나열하기 위해 pojo 맵 유형을 지정하십시오-> <collection properties = "OrderDetails"oftype = "cn.itcast.po.po.fordetail"> id 고유 한 속성. 순서 세부 사항을 cn.itcast.mybatis.po.orderDetail-> <id column = "orderdetail_id"property = "id"/> <result column = "items_id"property = "inciptid"/<result column = "items_num"property = "itemsnum"/> <result column = "orders_id"property = "ordersid"</result ""</rected "/</result" "</result"
OrdersMapperCustom.java
테스트 코드 :
@TestPublic void testFindorsandOrderDetailResultMap ()는 예외를 {sqlsession sqlsession = sqlsessionfactory.opensession (); // proxy ObjectMapperCustom 작성 mapperCustom = sqlsession.getMapper (OrdersMapperCustom.getMapper); // congper Methogs List = class maperCUSTOM.GETTMAPPER (ordersMapperCustom.class); OrdersMapperCustom.FindOrdersandOrderDetailResultMap (); System.out.println (list); sqlsession.close ();}요약
MyBatis는 ResultMap의 컬렉션을 사용하여 관련 쿼리의 여러 레코드를 목록 수집 속성에 매핑합니다.
resulttype를 사용한 구현 :
주문 세부 사항을 주문 대표로 매핑하는 경우 직접 처리하고 이중 루프를 사용하여 트래버지를 제거하고 중복 레코드를 제거하며 주문 세부 사항을 주문 테일로 배치해야합니다.
다수의 쿼리
요구 사항 : 사용자 및 사용자 구매 정보 쿼리.
SQL 문
쿼리 메인 테이블은 사용자 테이블입니다
협회 표 : 사용자와 제품은 직접 관련이 없으므로 주문 및 주문 세부 사항과 관련이 있으므로 협회 테이블 : 주문, 주문 테일, 항목
Orders.*, user.username, user.sex, user.address, orderdetail.id orderdetail_id, orderdetail.items_id, orderdetail.items_num, orderdetail.orders_id, items.name items_name, items.detail items_detail, items_pricefromorders, Order, Where, where, where, where user.id 및 orderdetail.orders_id = orders.id 및 orderdetail.items_id = items.id
매핑 아이디어
사용자 정보를 사용자에게 매핑합니다.
사용자가 작성한 주문을 OrdersList에 매핑하려면 사용자 클래스에서 주문 목록 속성 목록을 추가하십시오.
주문 세부 사항 추가 목록 속성 목록 <StredDetail> OrderDetials Orders OrderDetials를지도합니다.
주문 세부 사항에 해당하는 항목을 맵핑하려면 항목 속성을 주문하십시오.
OrdersMapperCustom.xml
결과 맵 정의
<!-사용자 및 구매 제품-> <resultmap type = "cn.itcast.mybatis.po.user"id = "userAnditemSresultMap"> <! <!-사용자 정보-> <id councme = "user_id"property = "id"/<result column = "usern"propert = "username ="result column = "sex" "sex" "sex" "sex" "sect" 속성 = "주소"/> <!-주문 정보 사용자는 여러 주문에 해당하고 수집 매핑-> <Collection Property = "OrdersList"oftype = "cn.itcast.mybatis.po.orders"> <id "속성 ="id "/<result councm ="user_id "propert ="user column = "number" "number" "number" "id column ="id column = "id" "id" 속성 = "createTime"/> <result column = "note"propertion = "note"/> <!-주문 세부 사항 하나의 주문 세부 사항은 여러 세부 사항을 포함합니다-> <Collection Propertion = "OrderDetails"oftype = "cn.itcast.myBatis.po.orderDetail"> <id councme = "orderdetail_id"propert = "id"/> <result column = "inited _ expertion" "airedS" 속성 = "itemsnum"/> <result column = "orders_id"property = "OrdersId"/> <!-제품 정보 주문 세부 사항은 제품에 해당합니다-> <anicke property = "items"javatype = "cn.itcast.mybatis.po.items"> <id councm = "initem _id"propert = "id <result column ="inited councm " 속성 = "세부 사항"/> <결과 열 = "items_price"property = "price"/> </assion> </collection> </collection> </resultmap>
OrdersMapperCustom.java
테스트 코드 :
@testpublic void testfinduseranditemsresultmap ()는 예외를 {sqlsession sqlsession = sqlsessionfactory.opensession (); // proxy 객체 mapperCustom OrdersMapperCustom = sqlsession.getMapper (OrdersMapperCustom.class); // call mapper list <ustmappercustom ordersmapperCustom = sqlsectom.class를 만들어냅니다. OrdersMapperCustom.finduserAnditemsresultMap (); System.out.println (list); sqlsession.close ();} 다수의 쿼리 요약
사용자가 구매 한 제품 정보의 자세한 목록은 확인됩니다 (사용자 이름, 사용자 주소, 제품 이름, 구매 시간, 구매량)
위의 요구 사항에 따라 결과 유형을 사용하여 쿼리 레코드를 확장 된 pojo에 매핑하는데, 이는 세부 목록의 기능을 구현하기가 매우 간단합니다.
일대일은 다음과 같이 다수의 특별한 경우입니다.
사용자가 구매 한 제품 정보를 쿼리 할 때 사용자와 제품 간의 관계는 다수의 관계입니다.
요구 사항 1 :
쿼리 필드 : 사용자 계정, 사용자 이름, 사용자 성별, 제품 이름, 제품 가격 (가장 일반적)
엔터프라이즈 개발의 일반적인 세부 목록, 사용자가 구매 한 세부 제품 목록,
결과 유형을 사용하여 위의 쿼리 열을 POJO 출력에 매핑하십시오.
요구 사항 2 :
쿼리 필드 : 사용자 계정, 사용자 이름, 구매 품목 수량, 제품 세부 정보 (세부 정보 표시 마우스)
ResultMap을 사용하여 사용자의 구매 한 제품 세부 정보 목록을 사용자 개체에 매핑하십시오.
요약 :
resultmap 사용은 쿼리 결과 매핑에 대한 특별한 요구 사항이있는 기능과 예를 들어 특수 요구 사항을 여러 목록을 포함한 목록에 매핑하는 것과 같은 기능입니다.
resultType 및 resultMap의 요약
결과 유형 :
효과:
SQL 열 이름 Pojo 속성 이름 일관성에 따라 쿼리 결과를 pojo로 매핑하십시오.
기회:
사용자가 제품 세부 정보를 구매하고 페이지의 모든 관련 쿼리 정보를 표시 할 때와 같은 자세한 레코드의 일반적인 표시는 결과 유형을 직접 사용하여 각 레코드를 매핑 할 수 있습니다.
Pojo로 쏘고 프론트 엔드 페이지에서 목록 (목록의 Pojo)을 가로 지르십시오.
결과 맵 :
협회와 컬렉션을 사용하여 일대일 및 일대일 고급 매핑을 완료하십시오 (결과에 대한 특별한 매핑 요구 사항이 있습니다).
협회:
효과:
관련 쿼리 정보를 POJO 객체에 매핑하십시오.
기회:
관련 정보 쿼리를 용이하게하려면 연관성을 사용하여 관련 주문 정보를 사용자 객체의 POJO 속성에 매핑 할 수 있습니다. 주문 쿼리 및 관련 사용자 정보.
resulttype를 사용하면 쿼리 결과를 pojo 객체의 pojo 속성에 매핑 할 수 없습니다. 결과 세트 쿼리를 가로 지르는 요구에 따라 resulttype 또는 resultmap을 사용할지 여부를 선택하십시오.
수집:
효과:
관련 쿼리 정보를 목록 수집에 매핑하십시오.
기회:
Traversal Association 정보 쿼리를 용이하게하려면 Collection을 사용하여 다음과 같은 다음과 같이 연관 정보를 목록에 매핑 할 수 있습니다. 사용자 권한 범위 모듈 및 모듈 아래의 메뉴 쿼리를 사용하여 모듈 목록을 맵핑하여 모듈 객체의 메뉴 목록 속성을 매핑 할 수 있습니다. 이것의 목적은 또한 쿼리 결과 세트를 쿼리하는 트래버스 쿼리를 용이하게하는 것입니다.
resulttype를 사용하는 경우 쿼리 결과를 목록 컬렉션에 매핑 할 수 없습니다.
지연 로딩
ResultMap은 고급 매핑을 구현할 수 있습니다 (협회 및 컬렉션을 사용하여 일대일 및 일대일 매핑을 구현). 연관과 수집에는 게으른 하중 기능이 있습니다.
필요:
주문이 쿼리되고 사용자 정보가 연관된 경우 요구 사항을 충족하기 위해 주문 정보를 먼저 쿼리하면 사용자 정보를 쿼리해야 할 때 사용자 정보를 쿼리합니다. 수요에 대한 사용자 정보 쿼리는로드가 지연됩니다.
지연로드 : 단일 테이블의 첫 번째 쿼리, 필요할 때 관련 테이블의 첫 번째 쿼리는 데이터베이스 성능을 크게 향상시키는 것이 여러 테이블을 쿼리하는 것보다 빠르기 때문에 데이터베이스 성능을 크게 향상시킵니다.
연관성을 사용하여 게으른 하중을 구현하십시오
요구 사항 : 쿼리 주문 및 쿼리 사용자 정보를 연결합니다
ordresmappercustom.xml
두 개의 매퍼 방법에 해당하는 명령문을 정의해야합니다.
1. 주문 정보 만 쿼리합니다
* 주문에서 *를 선택하십시오
협회를 사용하여로드 지연 (실행) 쿼리 순서 문의 다음 만족도 (협회 쿼리 사용자 정보)
2. 관련 쿼리 사용자 정보
user_id는 위의 순서 정보 쿼리에서 user_id를 따라 사용자 정보를 쿼리하는 데 사용됩니다.
usermapper.xml에서 finduserbyid를 사용하십시오
위의 첫 번째는 FindorderSuserlazyloading을 실행하고 사용자를 쿼리해야 할 때 FindUserById를 실행하고 지연된로드 및 실행은 resultMAP의 정의를 통해 구성됩니다.
지연 로딩 결과 맵
연관에서 선택을 사용하여 게으른로드로 실행될 명령문의 ID를 지정하십시오.
<!-Lazy Loaded resultMap-> <resultmap type = "cn.itcast.mybatis.po.orders"id = "ordersUserLazyLoadingResultMap"> <!-순서 정보의 맵핑-> <id 열 = "id"property = "id"/> <result column = "property" "/> 열 = "CreateTime"Property = "CreateTime"/> <result column = "propertion ="note "/> <!-순서 정보의 맵핑 구성-> <id councle ="id "propertion ="user_id "property ="userId "/<result column ="number "property ="number "/> <result column ="createTime "/> <result loadem ="note "note"note ".
선택 : 게으른로드를 위해 실행될 명령문의 ID를 지정하십시오 (user_id를 기반으로 사용자 정보를 쿼리하는 명령문)
usermapper.xml에서 findUserById를 사용하여 사용자 ID (user_id) 사용자 정보를 기반으로 쿼리를 완료합니다. FindUserById 가이 맵퍼에 있지 않은 경우 네임 스페이스를 추가해야합니다.
열 : 사용자 정보 쿼리와 관련된 순서 정보의 열은 user_id입니다.
협회 쿼리 용 SQL은 다음과 같이 이해됩니다.
Orders.*, (Orders.user_id = user.id) 사용자 이름, (Orders.user_id = user.id) sexfrom Orders-> <association 속성 = "user"javatype = "cn.itcast.mybatis.po.user"select.mopper.suremporpor.suremporper.finperforporporporporporporporpord " column = "user_id"> <!-사용자 정보의 게으른로드를 구현-> </협회> </resultmap>
OrderesMapperCustom.java
테스트 아이디어 :
1. 위의 Mapper 메소드 (Findordersuserlazyloading)를 실행하고 CN.itcast.mybatis.mapper.ordersmapperCustom에서 findordersuserlazyloading을 호출하여 쿼리 주문 정보 (단일 테이블) 만 호출하십시오.
2. 프로그램에서 이전 단계에서 쿼리 된 목록을 통과하십시오. 주문에서 getUser 메소드를 호출하면 게으른 적재를 시작합니다.
3. 지연로드, usermapper.xml의 finduserByid 메소드를 호출하여 사용자 정보를 얻습니다.
게으른 부하 구성
MyBatis는 기본적으로 게으른로드를 활성화하지 않으며 SQLMAPCONFIG.XML로 구성해야합니다.
MyBatis Core 구성 파일에서 구성 :
설정 항목 설명 허용 값 기본값
LazyloadingEnabled 전 세계적으로 게으른 하중을 설정했습니다. 'false'로 설정되면 관련된 모든 것이 초기화되고로드됩니다. 참 또는 거짓
공격적으로 설정하면 'true'로 설정되면 게으른 로딩 물체는 모든 게으른 특성에 의해로드 될 수 있습니다. 그렇지 않으면 각 속성은 필요에 따라로드됩니다. 참 또는 거짓
sqlmapconfig.xml에서 구성 :
테스트 코드
지연된 하중에 대해 생각합니다
Mybatis가 제공 한 연관성과 컬렉션을 사용하지 않고 게으른 하중을 달성하는 방법은 무엇입니까?
구현 방법은 다음과 같습니다.
두 가지 매퍼 방법 정의 :
1. 주문 목록을 쿼리하십시오
2. 사용자 ID를 기반으로 한 사용자 정보 쿼리
구현 아이디어 :
먼저 첫 번째 Mapper 메소드를 확인하고 주문 정보 목록을 가져옵니다.
프로그램 (서비스)에서 사용자 정보를 쿼리하기 위해 필요에 따라 두 번째 매퍼 메소드를 호출하십시오.
간단히 말해서 게으른로드 방법을 사용하여 간단한 SQL (바람직하게는 단일 테이블, 쿼리를 연결할 수도 있음)을 쿼리 한 다음 필요에 따라 관련 쿼리의 다른 정보를로드하십시오.
쿼리 캐시
Mybatis는 데이터 압력을 줄이고 데이터베이스 성능을 향상시키기 위해 쿼리 캐시를 제공합니다.
Mybaits는 1 단계 캐시 및 2 단계 캐시를 제공합니다.
레벨 1 캐시는 SQLSESSION 레벨 캐시입니다. 데이터베이스를 작동 할 때는 SQLSESSION 객체를 구성해야하며 캐시 된 데이터를 저장할 객체에 데이터 구조 (HASHMAP)가 있습니다. 다른 SQLSESSION 간의 캐시 된 데이터 영역 (해시 맵)은 서로 영향을 미치지 않습니다.
보조 캐시는 매퍼 레벨 캐시입니다. 여러 sqlsessions는 동일한 맵퍼의 SQL 문을 작동합니다. 여러 sqlsessions는 보조 캐시를 공유 할 수 있습니다. 보조 캐시는 교차 SQLSESSION입니다.
캐시를 사용하는 이유는 무엇입니까?
캐시에 데이터가있는 경우 데이터베이스에서 데이터를 가져올 필요가 없으므로 시스템 성능이 크게 향상됩니다.
레벨 1 캐시
1 차 캐싱 작업 원리
사용자 ID 1을 사용하여 사용자 정보에 대한 쿼리를 처음 시작했을 때 먼저 캐시에 ID 1이있는 사용자 정보가있는 사용자 정보가 있는지 확인하십시오. 그렇지 않은 경우 데이터베이스의 사용자 정보를 쿼리하십시오.
사용자 정보를 얻고 1 단계 캐시에 사용자 정보를 저장하십시오.
sqlsession이 커밋 작업을 수행하면 (삽입, 업데이트 및 삭제) SQLSession의 첫 번째 수준 캐시를 지 웁니다. 이것의 목적은 캐시 저장을 최신 정보로 만들고 더러운 읽기를 피하는 것입니다.
사용자 ID 1을 사용하여 사용자 정보에 대한 쿼리를 두 번째로 시작한 경우 먼저 캐시에 ID 1이있는 사용자 정보가있는 사용자 정보가 있는지 확인하십시오. 캐시에 하나가 있으면 캐시에서 직접 사용자 정보를 얻습니다.
레벨 1 캐시 테스트
MyBatis는 기본적으로 1 단계 캐싱을 지원하며 구성 파일에서 구성 할 필요가 없습니다.
위의 레벨 1 캐시 원리 단계를 따라 테스트하십시오.
//ordersmappercusntomtest.java@testpublic void testcache1 ()은 예외를 {sqlsession sqlsession = sqlsessionfactory.opensession (); // proxy 객체 usermapper usermapper = sqlsession.getMapper.getMapper.getMapper.getMapper (usermpper.class)를 사용합니다. ID 1은 query user user1 = usermapper.finduserByid (1); System.out.println (user1); // sqlsession이 커밋 작업 (삽입, 업데이트 및 삭제)을 수행하는 경우 SQLSession의 첫 번째 레벨 캐시를 지 웁니다. 이것의 목적은 캐시 저장을 최신 정보로 만들고 더러운 읽기를 피하는 것입니다. // User1의 정보 User1.setUserName 업데이트 ( "Test User22"); usermapper.updateuser (user1); // 캐시 SQLSESSION.COMMIT ()를 지우기 위해 커밋 작업을 실행하고 두 번째 요청을 시작하고 ID 1 user2 = usermapper.finduserByid (1); System.out.println (user2); sqlsession.close ();레벨 1 캐시 애플리케이션
공식적인 개발은 mybatis와 Spring을 통합하는 것이며, 거래는 서비스 중입니다.
서비스 방법에는 많은 Mapper 메소드 호출이 포함됩니다.
서비스 {// 실행을 시작할 때 트랜잭션을 시작하고 SQLSESSION 객체를 만듭니다. // FindUserById (1)를 처음으로 Mapper 메소드를 호출하십시오. 셀러스 서비이드 (1)를 두 번째로 Mapper 메소드로, 첫 번째 수준 CACHE에서 데이터를 가져 오는 메소드, SQLSESSION이 닫힙니다.동일한 사용자 정보를 쿼리하기 위해 두 개의 서비스 호출을 실행하면 세션 메소드가 종료되므로 SQLSESSION이 닫히고 첫 번째 수준 캐시가 지워집니다.
레벨 2 캐시
원칙
먼저, Mybatis의 두 번째 레벨 캐시를 활성화하십시오.
SQLSESSION1 QUERYS 사용자 ID가있는 사용자 정보 1. 사용자 정보 쿼리시 쿼리 데이터는 보조 캐시에 저장됩니다.
SQLSESSION3이 동일한 맵에서 SQL을 실행하는 경우 커밋 제출물을 실행하고 Mapper 아래의 보조 캐시 영역에서 데이터를 지 웁니다.
sqlsession2는 사용자 ID 1을 사용하여 사용자 정보를 쿼리하고 캐시에 데이터가 있는지 여부를 찾습니다. 존재하면 데이터가 캐시에서 직접 검색됩니다.
보조 캐시와 1 차 캐시의 차이는 더 큽니다. 보조 캐시의 범위가 더 큽니다. 여러 sqlsessions는 usermapper의 보조 캐시 영역을 공유 할 수 있습니다.
usermapper에는 보조 캐시 영역 (네임 스페이스로 세분화)이 있으며 다른 Mapppers는 자체 보조 캐시 영역 (네임 스페이스로 세분)을 가지고 있습니다.
각 네임 스페이스 매퍼에는 두 번째 캐시 영역이 있습니다. 두 매퍼의 네임 스페이스가 동일하면 데이터가 SQL에 의해 실행될 때 두 개의 매퍼는 동일한 두 번째 캐시 영역을 갖습니다.
레벨 2 캐시를 켜십시오
Mybaits의 두 번째 수준 캐시는 Mapper 범위 수준입니다. sqlmapconfig.xml에서 두 번째 레벨 캐시의 기본 스위치를 설정하는 것 외에도 특정 mapper.xml에서 두 번째 레벨 캐시도 활성화되어야합니다.
코어 구성 파일 SQLMAPCONFIG.XML에 추가되었습니다
<설정 이름 = "Cacheenabled"value = "true"/>
설명 허용 값 기본값
이 구성 파일의 모든 캐시에 대해 전 세계적으로 CACHEENIDANIVE ON/OFF 설정. 참 또는 거짓
usermapper.xml에서 보조 캐시를 켜면 usermapper.xml에서 SQL 실행이 캐시 영역 (Hashmap)에 저장됩니다.
직렬화 인터페이스를 구현하려면 pojo 클래스에 전화하십시오
캐시 된 데이터를 추출하기 위해, 2 차 캐시 된 데이터 저장 미디어는 다양하고 메모리가 다르기 때문에 사막화 작업이 수행됩니다.
레벨 2 캐시 테스트
@TestPublic void testCache2 ()는 예외를 {sqlsession sqlsession1 = sqlsessionfactory.opensession (); sqlsession sqlsession2 = sqlsessionfactory.opensession (); sqlsession sqlsession3 = sqlsession.opensession (); // create 객체에 대해 우선자 명소를 제작합니다. sqlsession1.getMapper (usermpaper.class); // 첫 번째 요청을 시작하고 ID 1 user user1 = usermapper1.finduserByid (1); System.out.println (user1); commit() operation UserMapper userMapper3 = sqlSession3.getMapper(UserMapper.class);User user = userMapper3.findUserById(1);user.setUsername("Zhang Mingming");userMapper3.updateUser(user);//Execute the submission and clear the secondary cache under UserMapper sqlsession3.commit (); sqlsession3.close (); usermapper usermapper2 = sqlsession2.getmapper (usermapper.class); // id user2 = usermapper2.finduserbyid (1); system.out.println (user2); sqlsession2.close ();USECACHE 구성
명령문에서 usecache = false를 설정하면 현재 선택 문의 보조 캐시가 비활성화 될 수 있습니다. 즉, 각 쿼리는 쿼리에 SQL을 발행합니다. 기본값은 사실입니다. 즉, SQL은 보조 캐시를 사용합니다.
<select id = "findorderListresultMap"resultMap = "OrdersUserMap"usecache = "false">
요약 : 각 쿼리마다 최신 데이터 SQL이 필요합니다. Usecache = false로 설정하고 보조 캐시를 비활성화하십시오.
캐시를 새로 고치십시오
캐시를 지우십시오
동일한 맵퍼 네임 스페이스에서 다른 인서트, 업데이트 또는 작업 데이터가 있으면 캐시를 새로 고치고 캐시를 새로 고치지 않으면 더러운 판독 값이 발생합니다.
명령문 구성에서 FlushCache = "True"속성을 설정하십시오. 기본적으로는 사실입니다. 즉, 캐시가 새로 고쳐 졌음을 의미합니다. False로 변경되면 새로 고침되지 않습니다. 캐시를 사용하는 경우 데이터베이스 테이블에서 쿼리 데이터를 수동으로 수정하면 더러운 읽기가 발생합니다.
<insert id = "InsertUser"ParameterType = "cn.itcast.mybatis.po.user"FlushCache = "true">
요약 : 일반적으로 커밋 작업을 실행 한 후 캐시를 새로 고침해야합니다. FlushCache = true는 캐시를 새로 고치는 것을 의미하며 데이터베이스의 더러운 읽기를 피할 수 있습니다.
mybatis 통합 ehcache
Ehcache는 분산 된 캐싱 프레임 워크입니다.
분산 캐시
我们系统为了提高系统并发,性能、一般对系统进行分布式部署(集群部署方式)
不使用分布缓存,缓存的数据在各各服务单独存储,不方便系统开发。所以要使用分布式缓存对缓存数据进行集中管理。
mybatis无法实现分布式缓存,需要和其它分布式缓存框架进行整合。
整合ehcache方法(掌握)
mybatis提供了一个cache接口,如果要实现自己的缓存逻辑,实现cache接口开发即可。
mybatis和ehcache整合,mybatis和ehcache整合包中提供了一个cache接口的实现类。
mybatis默认实现cache类是:
加入ehcache包
整合ehcache
配置mapper中cache中的type为ehcache对cache接口的实现类型。
加入ehcache的配置文件(在classpath下配置ehcache.xml)
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"><diskStore path="F:/develop/ehcache" /><defaultCache maxElementsInMemory="1000" maxElementsOnDisk="10000000"eternal="false" overflowToDisk="false" timeToIdleSeconds="120"timeToLiveSeconds="120" diskExpiryThreadIntervalSeconds="120"memoryStoreEvictionPolicy="LRU"></defaultCache></ehcache>
属性说明:
diskStore:指定数据在磁盘中的存储位置。
defaultCache:当借助CacheManager.add(“demoCache”)创建Cache时,EhCache便会采用<defalutCache/>指定的的管理策略
以下属性是必须的:
maxElementsInMemory - 在内存中缓存的element的最大数目
maxElementsOnDisk - 在磁盘上缓存的element的最大数目,若是0表示无穷大
eternal - 设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断
overflowToDisk - 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上
以下属性是可选的:
timeToIdleSeconds - 当缓存在EhCache中的数据前后两次访问的时间超过timeToIdleSeconds的属性取值时,这些数据便会删除,默认值是0,也就是可闲置时间无穷大
timeToLiveSeconds - 缓存element的有效生命期,默认是0.,也就是element存活时间无穷大
diskSpoolBufferSizeMB 这个参数设置DiskStore(磁盘缓存)的缓存区大小.默认是30MB.每个Cache都应该有自己的一个缓冲区.
diskPersistent - 在VM重启的时候是否启用磁盘保存EhCache中的数据,默认是false。
diskExpiryThreadIntervalSeconds - 磁盘缓存的清理线程运行间隔,默认是120秒。每个120s,相应的线程会进行一次EhCache中数据的清理工作
memoryStoreEvictionPolicy - 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出)
二级应用场景
对于访问多的查询请求且用户对查询结果实时性要求不高,此时可采用mybatis二级缓存技术降低数据库访问量,提高访问速度,业务场景比如:耗时较高的统计分析sql、电话账单查询sql等。
实现方法如下:通过设置刷新间隔时间,由mybatis每隔一段时间自动清空缓存,根据数据变化频率设置缓存刷新间隔flushInterval,比如设置为30分钟、60分钟、24小时等,根据需求而定。
二级缓存局限性
mybatis二级缓存对细粒度的数据级别的缓存实现不好,比如如下需求:对商品信息进行缓存,由于商品信息查询访问量大,但是要求用户每次都能查询最新的商品信息,此时如果使用mybatis的二级缓存就无法实现当一个商品变化时只刷新该商品的缓存信息而不刷新其它商品的信息,因为mybaits的二级缓存区域以mapper为单位划分,当一个商品信息变化会将所有商品信息的缓存数据全部清空。解决此类问题需要在业务层根据需求对数据有针对性缓存。