1.自动映射-根据字段名和属性名
2.如果字段取了别名,会根据别名自动映射属性名
3.在setting中通过设置使用驼峰命名映射,前提是在配置文件中配有<setting name="mapUnderscoreToCamelCase" value="true"/>。具体可以上网搜4.通过配置resultMap的形式进行映射
情况一(映射结果封装到Map中):
接口:
public interface EmpMapper {
//将映射结果封装到Map中,只能是HashMap。key通过@MapKey来指定,比如
//将Emp对象中的empno属性的值作为key。这样就可以通过key来找到对应的value
@MapKey("empno")
public Map<Integer,Emp> findEmpsByReturnMap(String lastName);
}
对应的mapper文件:
这里的resultType是emp,一般是完全限定名,由于做了别名的设置,可以直接写成emp
<mapper namespace="com.anseon.mapper.EmpMapper">
<select id="findEmpsByReturnMap" resultType="emp" >
select * from emp where last_name like #{lastName}
</select>
</mapper>
test:
public void test1(){
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Map<String, Object> map = mapper.findEmpByReturnMap(7369);
System.out.println(map);
}
情况二(关联映射):
这里的关联映射是1对1或者多对1的情况,以pojo为标准:
pojo:
public class Emp {
private Integer empno;
private String lastName;
private String job;
private double salary;
private Dept dept;
public class Dept {
private Integer deptno;
private String name;
private String loc;
当然一定要有set get 以及构造函数,这里省略了。
对应的mapper文件:
<resultMap type="emp" id="empMap"> <id column="empno" property="empno"/> <result column="ename" property="lastName"/> <result column="job" property="job"/> <result column="salary" property="salary"/> </resultMap> <resultMap type="emp" id="empRelationMap" extends="empMap"> <association property="dept" javaType="com.anseon.pojo.Dept"> <!--column:Dept表中的字段名或者别名 property:javaType类中的属性名 -->
<id column="dno" property="deptno"/><!--注意这里的dno是别名,对应的是sql语句中起的别名 -->
<result column="dname" property="name"/>
<result column="loc" property="loc"/>
</association>
</resultMap>
<select id="findEmpAndDeptByNo" resultMap="empRelationMap">
select e.*,d.DEPTNO dno,dname,loc
from emp e ,dept d
where e.deptno = d.deptno and e.empno = #{empno}
</select>
这里看清楚了吗?有两个resultMap,一个select,具体关系如下:id=empMap的resultMap:
type本来是完全限定名,由于取了别名,可以直接写emp,所以以下的所有property的值都是emp对象的属性
<id>:这个标签是用来标明表中的主键字段。column必须是sql语句中查询的字段,如果没有取别名,就与表中的字段名一致。property对应类的属性名
<result>:这个标签用来标明表中的非主键字段。column和property跟id标签的意思一样
id=empRelationMap的resultMap:
extends:说明继承哪个resultMap,这样一来就不需要重复写<id>和<result>了
<association>:对应pojo中,Emp类有个Dept类属性,而这个标签就是用来说明找Emp表的时候怎样映射Dept表中的字段到dept属性中。
<association property & javaType>:property对应的是type 为 emp 中的dept属性,javaType对应的是该属性映射为Dept类。因此以下的column都是Dept表中的字段或者别名,property都是Dept类的属性名
这里应该看到,只通过一句sql语句就能将两张表中的数据找到,并映射封装到两个对象中
对应的接口:
public Emp findEmpAndDeptByNo(Integer empno);
test:
@Test public void testResultMap2(){ EmpMapper mapper = sqlSession.getMapper(EmpMapper.class); Emp emp = mapper.findEmpAndDeptByNo(7369); System.out.println(emp); System.out.println(emp.getDept()); }
情况三:
分步查询
其实跟上面的关联查询一样,结果都是将数据封装到两个对象中,不过分步查询是将一条sql语句拆开成单独的几条。关键是要看明白怎么拆成几条sql语句
pojo是一样的,就不写了
mapper文件:
emp的mapper文件:
<!--分步查询 select 引用的查询语句(命名空间+语句的id) column sql查询语句中的字段,查出来的值会当做参数传入另一条sql语句中(虽然是参数,也要跟属性名一致) --> <resultMap type="emp" id="empStepMap" extends="empMap"> <association property="dept" select="com.anseon.mapper.DeptMapper.findDeptByNo" column="deptno"/> </resultMap> <select id="findEmpAndDeptByStep" resultMap="empStepMap"> select * from emp where empno = #{empno} </select>
dept的mapper文件:
<mapper namespace="com.anseon.mapper.DeptMapper"> <resultMap type="dept" id="deptMap"> <id column="deptno" property="deptno"/> <result column="dname" property="name"/> <result column="loc" property="loc"/> </resultMap> <select id="findDeptByNo" resultMap="deptMap"> select * from dept where deptno= #{deptno} </select> </mapper>
这可以做对应:namaspace.id = com.anseon.mapper.DeptMapper.findDeptByNo,这跟emp的mapper 中的select对应
sql语句中的#{deptno}跟emp的mapper文件中的column值对应。
对应的接口:
public Dept findDeptByNo(Integer deptno);
public Emp findEmpAndDeptByStep(Integer empno);
test:省略。。。
以上就是分步查询,将一条sql语句拆分成相应的几条sql语句
情况4:
一对多,主要是pojo中有个list集合,当中的元素是自定义类。
pojo
public class Dept { private Integer deptno; private String name; private String loc; private List<Emp> emps;
mapper文件
dept的mapper文件,这里采用分步查询,分步查询的其中一个优点是:可以实现懒加载
<!--分步查询 支持懒加载--> <resultMap type="dept" id="deptMapStep" extends="deptMap"> <collection property="emps" column="deptno" select="com.anseon.mapper.EmpMapper.findEmpsByDeptno"/> </resultMap> <select id="findDeptByStep" resultMap="deptMapStep"> select * from dept where deptno = #{deptno} </select>
对应的emp的mapper文件<select id="findEmpsByDeptno" resultMap="empMap"> select * from emp where deptno = #{deptno} </select>
这样就是一对多的设置了。主要就是association 换成 collection
关于懒加载:
需要在mybatis的配置文件中设置:
<!--开启懒加载 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 每个属性按需加载 --> <setting name="aggressiveLazyLoading" value="false"/>
但是这个aggressiveLazyLoading有版本问题,需要依照版本来区分默认值