1.ResultMap结果集映射
1.1解决属性名和字段名不一致的问题
-
pojo代码:
package com.it.pojo; public class User { private int id; private String name; // 此时属性名和数据库表中的字段名字不相同,结果就是查不出pwd的结果 // 原因:sql=select name,id,pwd from user。 // 数据库表中名为pwd而映射表中是password private String password; }
没处理之前:
-
接口实现.xml代码:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="edu.xalead.Dao.UserMapper"> <!-- id为你添加的resultMap标签的名字。。type为要映射的类的名字--> <resultMap id="UserMap" type="User"> <!-- column是列的意思,就是对应数据库表中的列的名字, property是属性的意思,也就是对应实体类的属性名字。 --> <result column="pwd" property="password"/> </resultMap> <!--方法二:添加一个resultMap标签--> <select id="getUserById" resultMap="UserMap"> select * from mybatis.user where id = #{id} </select> <!--方法一:起一个别名--> <!--<select id="getUserById" resultType="User" parameterType="int"> select id,name,pwd as password from mybatis_test.m_user where id=#{id} </select>--> </mapper>
结果:
2.复杂查询
2.1 环境搭建:
添加2张新表和内容
-
CREATE TABLE `student` ( `id` int(10) NOT NULL, `name` varchar(30) DEFAULT NULL, `tid` int(10) DEFAULT NULL, PRIMARY KEY (`id`), KEY `ftkid` (`tid`), CONSTRAINT `ftkid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `teacher` ( `id` int(10) NOT NULL, `name` varchar(30) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
导入lombok
-
新建实体类Teacherm,Student
-
建立Mapper接口
-
建立Mapper.Xml文件
-
在核心配置文件中绑定我们注册的Mapper接口或文件
-
mybatis-config.xml代码为:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!--引入外部配置文件--> <properties resource="db.properties"/> <settings> <setting name="logImpl" value="LOG4J"/> </settings> <typeAliases> <package name="edu/xalead/pojo"/> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <mappers> <mapper class="edu.xalead.dao.TeacherMapper"/> <mapper class="edu.xalead.dao.StudentMapper"/> </mappers> </configuration>
2.2 多对一
查询所有学生对应老师的信息
- 多个学生,对应一个老师
- 对于学生这边而言是关联: 多个学生,关联一个老师【多对一】
- 对于老师而言是集合,一个老师有很多学生【一对多】
方法一(按查询嵌套处理(子查询))
-
StudentMapper代码为:
package edu.xalead.dao; import edu.xalead.pojo.Student; import java.util.List; public interface StudentMapper { //查询所有老师和学生的信息 public List<Student> getStudent(); }
-
实体Student代码为:
package edu.xalead.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class Student { private int id; private String name; //多个学生关联一个老师(用对象)多对一是关联 private Teacher teacher; }
-
老师实体类:
package edu.xalead.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; @Data @AllArgsConstructor @NoArgsConstructor public class Teacher { private int id; private String name; }
-
resources.edu.xalead.Dao.StudentMapper.xml代码为:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespacce = 绑定一个对应的Dao/Mapper接口 对应之前的实现接口--> <mapper namespace="edu.xalead.dao.StudentMapper"> <!-- 思路: 1. 查询所有学生的信息 2. 根据查出来的tid,去找对应的老师 --> <!--方法一--> <select id="getStudent" resultMap="studentTeacher"> select * from mybatis_test.student </select> <resultMap id="studentTeacher" type="Student"> <!--复杂属性处理 对象用association --> <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/> </resultMap> <select id="getTeacher" resultType="teacher"> select * from mybatis_test.teacher where id = #{tid} </select> </mapper>
测试:
@Test
public void test2(){
SqlSession session = MybatisUtils.getSqlSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
List<Student> studentList = mapper.getStudent();
for (Student student : studentList) {
System.out.println(student);
}
session.close();
}
结果:
方法二(按结果嵌套处理(关联查询))
-
其他与方法一相同,修改resources.edu.xalead.Dao.StudentMapper.xml代码为:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespacce = 绑定一个对应的Dao/Mapper接口 对应之前的实现接口--> <mapper namespace="edu.xalead.dao.StudentMapper"> <!-- 思路: 1. 查询所有学生的信息 2. 根据查出来的tid,去找对应的老师 --> <!--方法二--> <select id="getStudent2" resultMap="studentTeacher2"> select s.id sid,s.name sname,t.name tname from student s,teacher t where s.tid = t.id; </select> <resultMap id="studentTeacher2" type="Student"> <result property="id" column="sid"/> <result property="name" column="sname"/> <association property="teacher" javaType="Teacher"> <result property="name" column="tname"/> </association> </resultMap> </mapper>
10.3 一对多
通过一个老师查询多个学生,通过老师查询学生的信息同上有两种方法:
方法一二混合
-
接口StudentMapper为空,TeacherMapper代码:
package edu.xalead.dao; import edu.xalead.pojo.Teacher; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import java.util.List; public interface TeacherMapper { //获取指定老师下的所有学生及老师的信息 public Teacher getTeacher(@Param("tid") int id); public Teacher getTeacher2(@Param("tid") int id); }
-
pojo.Student代码:
package edu.xalead.pojo; import lombok.Data; @Data public class Student { private int id; private String name; private int tid; }
-
pojo.Teacher代码:
package edu.xalead.pojo; import lombok.Data; import java.util.List; @Data public class Teacher { private int id; private String name; //老师拥有多个学生 private List<Student> students; }
-
修改resources.edu.xalead.Dao.TeacherMapper.xml代码为:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespacce = 绑定一个对应的Dao/Mapper接口 对应之前的实现接口--> <mapper namespace="edu.xalead.dao.TeacherMapper"> <!--按结果嵌套查询--> <select id="getTeacher" resultMap="teacherStudent" parameterType="int"> select s.id sid,s.name sname,t.name tname, t.id tid from student s,teacher t where s.tid=t.id and t.id = #{tid} </select> <resultMap id="teacherStudent" type="Teacher"> <result property="id" column="tid"/> <result property="name" column="tname"/> <!--集合用 collection javaType="" 这是指定特殊字段属性的类型 ofType 集合中的泛型信息 --> <collection property="students" javaType="ArrayList" ofType="Student"> <result property="id" column="sid"/> <result property="name" column="sname"/> <result property="tid" column="tid"/> </collection> </resultMap> <!--方法二 按照查询嵌套--> <select id="getTeacher2" resultMap="teacherStudent2" parameterType="int"> select * from mybatis_test.teacher where id = #{tid} </select> <resultMap id="teacherStudent2" type="Teacher"> <!--没有变的字段也要写出来,否则结果中为空--> <result property="id" column="id"/> <collection property="students" column="id" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId"></collection> </resultMap> <select id="getStudentByTeacherId" resultType="Student" parameterType="int"> select * from mybatis_test.student where tid = #{id} </select> </mapper>
测试:
package edu.xalead.dao;
import edu.xalead.pojo.Teacher;
import edu.xalead.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
public class MyTest {
@Test
public void test(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher2(1);
System.out.println(teacher);
sqlSession.close();
}
}
结果:
注意:
- 关联- association [多对一]
- 集合- collection [一对多]
- javaType & ofType
- javaType 用来指定实体类中属性的类型(接口的返回值类型)
- ofType 用来指定映射到List或者集合中的pojo类型,泛型的类型
- 在resultMap 映射时,复杂情况时,也要把对应关系写出来到result中,否则结果中该字段为空或0
- 两种方法各有优缺,看自己掌握情况,个人推荐第一种
- 保证sql的可读性,尽量保证通俗易懂
- 注意一对多和多对一中,属性名和字段名的问题!
- 如果问题不好排查,可以使用日志,建议使用log4j
面试高频:
- mysql引擎
- InnoDB底层原理
- 索引
- 索引优化!
欢迎访问我的个人博客:http://www.ayjup.cn