머리말
MyBatis는 "데이터베이스 구조는 제어할 수 없다"는 아이디어를 기반으로 합니다. 즉, 데이터베이스가 제3정규형(BCNF)을 따르기를 바라지만 실제로는 우리의 바람에 어긋나고, 그러면 결과 집합 매핑은 MyBatis가 제공하는 이상과 현실의 변환 수단이며, resultMap은 결과 집합 매핑의 구성 레이블입니다.
ResultMap 태그에 대해 자세히 알아보기 전에 SQL 쿼리 결과 집합에서 JavaBean 또는 POJO 엔터티까지의 프로세스를 이해해야 합니다.
SQL 쿼리 결과에서 도메인 모델 엔터티로
JDBC 쿼리를 통해 ResultSet 개체 가져오기
ResultSet 개체를 트래버스하고 필드 이름이나 필드 별칭을 사용하여 데이터의 각 행을 HashMap 인스턴스에 임시 저장합니다. 결과 세트를 키로, 필드 값을 값으로 설정
ResultMap 태그의 유형 속성에 따라 반영을 통해 도메인 모델을 인스턴스화
에 따라 HashMap의 키-값 쌍을 채웁니다. ResultMap 태그의 type 속성과 id, result 등의 태그 정보를 도메인 모델 인스턴스로 이동하여 반환합니다.
1. 속성 설명
id 속성, resultMap의 식별 꼬리표.
type 속성, 반환 값의 정규화된 클래스 이름 또는 유형 별칭입니다.
autoMapping 속성, 값 범위 true(기본값) | false, 자동 매핑 기능 시작 여부를 설정합니다. 자동 매핑 기능은 필드 이름과 동일한 속성 이름을 소문자로 자동으로 찾아 호출하는 것입니다. 세터 방식. false로 설정한 후 해당 setter 메소드를 호출하기 전에 resultMap
에서 매핑 관계를 명확하게 표시해야 합니다.
2 기본 기능: SQL 쿼리 결과 필드와 엔터티 속성 간의 매핑 관계 설정
예제 1: setter를 통해 도메인 모델 구성
public class EStudent{ private long id; private String name; private int age; // getter,setter方法 /** * 必须提供一个无参数的构造函数 */ public EStudent(){} }
<select id="getStudent" resultMap="getStudentRM"> SELECT ID, Name, Age FROM TStudent </select> <resultMap id="getStudentRM" type="EStudnet"> <id property="id" column="ID"/> <result property="studentName" column="Name"/> <result property="studentAge" column="Age"/> </resultMap>
하위 요소 설명:
id 요소, 기본 키 필드 설정 도메인 모델 속성
result 요소와의 매핑 관계, 일반 필드와 도메인 모델 속성
id 간의 매핑 관계를 설정하는 데 사용, 결과 설명 속성 구성 세부 정보:
Property | Description |
---|---|
property | JavaBean에 매핑해야 하는 속성 이름입니다. |
column | 데이터 테이블의 열 이름 또는 레이블 별칭입니다. |
javaType | 전체 클래스 이름 또는 유형 별칭입니다. JavaBean과 일치하면 MyBatis는 일반적으로 자체적으로 이를 감지합니다. 그런 다음 HashMap에 매핑하는 경우 javaType의 목적을 지정해야 합니다. |
jdbcType | 데이터 테이블에서 지원하는 유형 목록입니다. 이 속성은 삽입, 업데이트 또는 삭제 중에 Null을 허용하는 열에만 유용합니다. JDBC에서는 이를 요구하지만 MyBatis에서는 그렇지 않습니다. JDBC에 대해 직접 코딩하고 null을 허용하는 열이 있는 경우 이를 지정하는 것이 좋습니다. |
typeHandler | 이 속성을 사용하여 유형 핸들러를 재정의합니다. 이 값은 완전한 클래스 이름이거나 유형 별칭일 수 있습니다. |
示例2:通过构造函数构造领域模型
<select id="getStudent" resultMap="getStudentRM"> SELECT ID, Name, Age FROM TStudent</select><resultMap id="getStudentRM" type="EStudnet"> <constructor> <idArg column="ID" javaType="_long"/> <arg column="Name" javaType="String"/> <arg column="Age" javaType="_int"/> </constructor></resultMap>
子元素说明:
constructor元素 ,指定使用指定参数列表的构造函数来实例化领域模型。注意:其子元素顺序必须与参数列表顺序对应
idArg子元素 ,标记该入参为主键
arg子元素 ,标记该入参为普通字段(主键使用该子元素设置也是可以的)
3、一对一关系、一对多关系查询
注意:在采用嵌套结果的方式查询一对一、一对多关系时,必须要通过resultMap下的id或result标签来显式设置属性/字段映射关系,否则在查询多条记录时会仅仅返回最后一条记录的情况。
联合元素用来处理“一对一”的关系。需要指定映射的Java实体类的属性,属性的javaType(通常MyBatis 自己会识别)。对应的数据库表的列名称。如果想覆写的话返回结果的值,需要指定typeHandler。
不同情况需要告诉MyBatis 如何加载一个联合。MyBatis 可以用两种方式加载:
select: 执行一个其它映射的SQL 语句返回一个Java实体类型。较灵活;
resultsMap: 使用一个嵌套的结果映射来处理通过join查询结果集,映射成Java实体类型。
例如,一个班级对应一个班主任。
首先定义好班级中的班主任 private TeacherEntity teacherEntity;
使用select实现联合
例:班级实体类中有班主任的属性,通过联合在得到一个班级实体时,同时映射出班主任实体。
这样可以直接复用在TeacherMapper.xml文件中定义好的查询teacher根据其ID的select语句。而且不需要修改写好的SQL语句,只需要直接修改resultMap即可。
ClassMapper.xml文件部分内容:
<resultMap type="ClassEntity" id="classResultMap"> <id property="classID" column="CLASS_ID" /> <result property="className" column="CLASS_NAME" /> <result property="classYear" column="CLASS_YEAR" /> <association property="teacherEntity" column="TEACHER_ID" select="getTeacher"/> </resultMap> <select id="getClassByID" parameterType="String" resultMap="classResultMap"> SELECT * FROM CLASS_TBL CT WHERE CT.CLASS_ID = #{classID}; </select>
TeacherMapper.xml文件部分内容:
<resultMap type="TeacherEntity" id="teacherResultMap"> <id property="teacherID" column="TEACHER_ID" /> <result property="teacherName" column="TEACHER_NAME" /> <result property="teacherSex" column="TEACHER_SEX" /> <result property="teacherBirthday" column="TEACHER_BIRTHDAY"/> <result property="workDate" column="WORK_DATE"/> <result property="professional" column="PROFESSIONAL"/> </resultMap> <select id="getTeacher" parameterType="String" resultMap="teacherResultMap"> SELECT * FROM TEACHER_TBL TT WHERE TT.TEACHER_ID = #{teacherID} </select>
使用resultMap实现联合
与上面同样的功能,查询班级,同时查询器班主任。需在association中添加resultMap(在teacher的xml文件中定义好的),新写sql(查询班级表left join教师表),不需要teacher的select。
修改ClassMapper.xml文件部分内容:
<resultMap type="ClassEntity" id="classResultMap"> <id property="classID" column="CLASS_ID" /> <result property="className" column="CLASS_NAME" /> <result property="classYear" column="CLASS_YEAR" /> <association property="teacherEntity" column="TEACHER_ID" resultMap="teacherResultMap"/> </resultMap> <select id="getClassAndTeacher" parameterType="String" resultMap="classResultMap"> SELECT * FROM CLASS_TBL CT LEFT JOIN TEACHER_TBL TT ON CT.TEACHER_ID = TT.TEACHER_ID WHERE CT.CLASS_ID = #{classID}; </select>
其中的teacherResultMap请见上面TeacherMapper.xml文件部分内容中。
聚集元素用来处理“一对多”的关系。需要指定映射的Java实体类的属性,属性的javaType(一般为ArrayList);列表中对象的类型ofType(Java实体类);对应的数据库表的列名称;
不同情况需要告诉MyBatis 如何加载一个聚集。MyBatis 可以用两种方式加载:
1. select: 执行一个其它映射的SQL 语句返回一个Java实体类型。较灵活;
2. resultsMap: 使用一个嵌套的结果映射来处理通过join查询结果集,映射成Java实体类型。
例如,一个班级有多个学生。
首先定义班级中的学生列表属性:private List<StudentEntity> studentList;
使用select实现聚集
用法和联合很类似,区别在于,这是一对多,所以一般映射过来的都是列表。所以这里需要定义javaType为ArrayList,还需要定义列表中对象的类型ofType,以及必须设置的select的语句名称(需要注意的是,这里的查询student的select语句条件必须是外键classID)。
ClassMapper.xml文件部分内容:
<resultMap type="ClassEntity" id="classResultMap"> <id property="classID" column="CLASS_ID" /> <result property="className" column="CLASS_NAME" /> <result property="classYear" column="CLASS_YEAR" /> <association property="teacherEntity" column="TEACHER_ID" select="getTeacher"/> <collection property="studentList" column="CLASS_ID" javaType="ArrayList" ofType="StudentEntity" select="getStudentByClassID"/> </resultMap> <select id="getClassByID" parameterType="String" resultMap="classResultMap"> SELECT * FROM CLASS_TBL CT WHERE CT.CLASS_ID = #{classID}; </select>
StudentMapper.xml文件部分内容:
<!-- java属性,数据库表字段之间的映射定义 --> <resultMap type="StudentEntity" id="studentResultMap"> <id property="studentID" column="STUDENT_ID" /> <result property="studentName" column="STUDENT_NAME" /> <result property="studentSex" column="STUDENT_SEX" /> <result property="studentBirthday" column="STUDENT_BIRTHDAY" /> </resultMap> <!-- 查询学生list,根据班级id --> <select id="getStudentByClassID" parameterType="String" resultMap="studentResultMap"> <include refid="selectStudentAll" /> WHERE ST.CLASS_ID = #{classID} </select>
使用resultMap实现聚集
使用resultMap,就需要重写一个sql,left join学生表。
<resultMap type="ClassEntity" id="classResultMap"> <id property="classID" column="CLASS_ID" /> <result property="className" column="CLASS_NAME" /> <result property="classYear" column="CLASS_YEAR" /> <association property="teacherEntity" column="TEACHER_ID" resultMap="teacherResultMap"/> <collection property="studentList" column="CLASS_ID" javaType="ArrayList" ofType="StudentEntity" resultMap="studentResultMap"/> </resultMap> <select id="getClassAndTeacherStudent" parameterType="String" resultMap="classResultMap"> SELECT * FROM CLASS_TBL CT LEFT JOIN STUDENT_TBL ST ON CT.CLASS_ID = ST.CLASS_ID LEFT JOIN TEACHER_TBL TT ON CT.TEACHER_ID = TT.TEACHER_ID WHERE CT.CLASS_ID = #{classID}; </select>
其中的teacherResultMap请见上面TeacherMapper.xml文件部分内容中。studentResultMap请见上面StudentMapper.xml文件部分内容中。
4. 动态映射关系
通过 discriminator子元素 (鉴别器)可以实现动态映射关系信息的设置。具体示例如下:
public class EStudent{ private long id; private String name; private String juniorHighSchool; private String seniorHighSchool; private int during; // 在本校就读时间 // getter,setter方法 /** * 必须提供一个无参数的构造函数 */ public EStudent(){} }
情景:查询学生信息的seniorHighSchool信息,若就读时间during字段值为4、5、6时,则以juniorHighSchool字段作所为seniorHighSchool信息。
<select id="getStundent" resultMap="rm"> SELECT ID, Name, JuniorHighSchool, SeniorHighSchool, during FROM TStudent</select><resultMap id="rm" type="EStudent"> // 若不加这句,则当将juniorHighSchool赋予给seniorHighSchool属性时,juniorHighSchool属性将为null <result column="juniorHighSchool" property="juniorHighSchool"/> <discriminator column="during" javaType="_int"> // 形式1:通过resultType设置动态映射信息 <case value="4" resultType="EStudent"> <result column="juniorHighSchool" property="seniorHighSchool"/> </case> // 形式2: 通过resultMap设置动态映射信息 <case value="5" resultMap="dynamicRM"/> <case value="6" resultMap="dynamicRM"/> </discriminator></resultMap><resultMap id="dynamicRM" type="EStudent"> <result column="juniorHighSchool" property="seniorHighSchool"/></resultMap>
注意:上面关于 discriminator子元素 的 case元素 的 resultType属性 和 resultMap元素 的 type属性 ,均不是直指返回的领域模型类型,而是指定根据判断条件后得到映射关系,可通过 id子元素 和 result子元素 重写映射关系。
5. id元素,result元素,idArg元素,arg元素,discriminator元素的共同属性
javaType属性 :Java类的全限定名,或别名
jdbcType属性 :JDBC类型, JDBC类型为CUD操作时列可能为空时进行处理
typeHandler属性 :指定类型处理器的全限定类名或类型别名
column属性 :指定SQL查询结果的字段名或字段别名。将用于JDBC的 resultSet.getString(columnName)
이 기사에서는 mybatis 속성에 대한 자세한 설명을 설명합니다. 더 많은 관련 내용을 보려면 PHP 중국어 웹사이트를 참고하세요.
관련 권장 사항:
위 내용은 mybatis 속성에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!