mybatis作为轻量级orm框架,需要配置很多sql 语句,sql是比较好控制的,所以都比较喜欢,而一般其他的orm都要学一大堆各种古怪配置,概念,看完文档仍是不明所以。
mybatis的整个流程处理来看,主要有【三方面】
1、sql语句查询后的结果集,简单看做一个二维表格
2、mybatis的mapper.xml,配置对应的sql语句和查询接口方法名id,java的mapper.java【接口】类 (完成orm, 数据库–>mapper.xml【orm纽带】—>mapper.java–>java业务代码)
3、java业务代码调用,调用mybatis通过反射生成的代理类 (【MapperProxyFactory】生成【MapperProxy】,具体代理类)。调用java的mapper.java接口方法,实现查询和其他数据库操作,还需要实体对象entity对应表模型,供接口方法调用返回时,数据填充到实体对象,然后返回。
【单表查询】【自身表查询】
单一表的查询是最简单的操作
//mapper.xml 片段
<select id="selectCourse" resultType="entity.Course">
select * from course where id = #{id}
</select>
//mapper.java 片段
public interface CourseMapper {
Course selectCourse(int id);
}
//业务.java 片段
CourseMapper mapper = session.getMapper(CourseMapper.class);
Course course = mapper.selectCourse(1);
【一对多】两表关联【多对多】三表关联,查询,还有其他【各种复杂】的sql映射
理解了mybatis的处理过程,其实一对多和多对多都是一样的,mybatis完成的只是把sql的查询结果,一个【二维表格通过xml配置映射为java对象】,供我们java面向对象编程,mybatis就是完成这个过程的【封装】
比如,多对多sql,
student表,
course课程表,
sc选课表(只存前两表id)
表结构
student学生表 id name age stuNum学生号
sc 选课表 id stuNum courseNum
course 课程表 id name takeTime学时 courseNum课程号
SELECT
student.id stu_id,
student.name stu_name,
course.id course_id,
course.name course_name,
course.courseNum course_num
from
student INNER JOIN sc
on
student.stuNum = sc.stuNum
INNER JOIN course
on
sc.courseNum = course.courseNum
WHERE
course.courseNum = "c001"
上面是具体sql,(查询每个课程的,选课学生)。然后是mybatis的处理
//CourseMapper.xml 一个select 一个对应的resultMap
<select id="getStu" resultMap="courseStu">
SELECT
student.id stu_id,
student.name stu_name,
course.id course_id,
course.name course_name,
course.courseNum course_num
from
student INNER JOIN sc
on
student.stuNum = sc.stuNum
INNER JOIN course
on
sc.courseNum = course.courseNum
WHERE
course.courseNum = #{courseNum}
</select>
<resultMap type="entity.Course" id="courseStu">
<id property="id" column="course_id" />
<result property="name" column="course_name" />
<result property="courseNum" column="course_num" />
<collection property="students" ofType="entity.Student">
<id property="id" column="stu_id" />
<result property="name" column="stu_name" />
</collection>
</resultMap>
//CourseMapper.java mapper.java接口类
public interface CourseMapper {
Course getStu(String courseNum);
}
//Course.java 实体类 对应表course
public class Course {
private int id;
private String name;
private int takeTime;
private String courseNum;
//students非表结构字段,对应resutlMap的collection
private List<Student> students;
//... normal getter and setter
}
//Test.java 业务调用
Course course1 = mapper.getStu("c001");
System.out.println(course1.getStudents().get(0).getName());
上面代码比较多,可以下载“完整项目”看看。
【总结】
1、业务调用getStu()后,mybatis根据mapper.xml的sql查到结构后(上面的结果图)
2、mybatis根据mapper.xml的配置(resultMap), 把sql的结果转为一个Course实体对象 (注意属性students,不是表结构),Course的students设为三个student对象 (student 是普通实体类,都是表结构的参数属性)
3、mybatis 把上面的Course返回给getStu()的调用者
【多对多查询需要做的】
1、设置实例类的List属性值(Course)
2、配置mapper.xml的resultMap(property是实体类的属性,column是sql结果集的字段[执行sql后看看字段名称],collection配置List类型的属性),定义sql结构集(字段)与java实体类对象属性的映射
3、接口调用,和业务调用测试