在上一篇博客中讲到了简单的MyBatis操作,使用的是最简单的一张表的查询。但在实际操作中,基本上都会用到多张表,今天我们就来了解一下MyBatis中的高级映射,其中的配置文件请见上一篇博客:
MyBatis高级映射
1.一对一查询
首先新建两个数据表:teacher和teacheridcard
teacher表包含id和name,表示老师的编号和姓名,teacheridcard中包含id和idcard,表示老师的编号和身份证号,我们希望通过idcard来查询到teacher的姓名。
MyBatis的实现方式有两种:
1.resultType实现
resultType表示最终的查询结果只能返回到一个java包装类上,我们可以通过继承的方式实现:首先新建一个Teacher类和TeacherIdcard类:
package pojo;
public class Teacher {
private int id;
private String name;
//getter and setter
}
public class TeacherIdcard extends Teacher{
private String idcard;
//getter and setter
}
接着写通过idcard查询姓名的sql命令:
最后测试一下输出:
public class TestTeacher {
public static void main(String[] args) throws IOException {
InputStream inputStream= Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();
TeacherIdcard teacher=session.selectOne("findnamebycard","123456");
System.out.println(teacher.getName());
}
}
输出结果为李华:
2.resultMap实现
resultMap可以将数据字段映射到名称不一样的实体类型属性上,不再局限于一个java类,修改TeacherIdcard类:
public class TeacherIdcard{
Teacher teacher;
int id;
String idcard;
//getter and setter
}
使用resultMap实现的xml文件代码:
其中resultMap中的id标签表示对应的主键,result对应于非主键,column表示对应的表中的列值,property表示对应类中的名称,association表示关联的嵌套结果
最后简单修改一下测试类即可测试出相同结果:
public static void main(String[] args) throws IOException {
InputStream inputStream= Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();
TeacherIdcard teacher=session.selectOne("findnamebycard2","123456");
System.out.println(teacher.getTeacher().getName());
}
2.一对多查询
一间教室里有许多学生,通过教室号来查询学生就是一种一对多的查询方式,我们现在数据库中新建Class的表,包含id和name。然后在Student表中增加一项classid,表示学生属于哪个班级。
编写class类:
public class Class {
private int id;
private String name;
//getter and setter
}
修改Student类,在上面增加私有属性classid和其get set方法。编写根据教室号查询学生名称的select代码:
最后进行测试:
List students=session.selectList("findstudentbyclassname",1);
for(Student student:students){
System.out.println(student.getName());
}
3.多对多查询
一个学生可以有多个老师,一个老师教多个学生,这样的形式就是多对多的查询方法,我们通过实际的代码来模拟多对多的实例:首先再建一个数据库表teacherwithstudent,里面包含stuid和teaid,另外我们还需要student和teacher两张表,两张表中的数据如下所示:
接着编写数据库查询语句,我们要实现查找某一个老师下所有的学生名单:
输入李华进行测试:
List students=session.selectList("findstudentbyteacher", "李华");
for(Student student:students){
System.out.println(student.getName());
}
最终输出小红和小张,这就是多对多的查询,想要了解更多的数据库查询方式可以系统深入地学习数据库的知识。
------------------------------------------------------------------------------------------------------------------------------------
Mapper的动态代理
在前面的测试中我们会发现,如果每次测试都需要把mapper中对应的id名称都写出来会特别麻烦,还容易出错,比如下面的代码:
List students=session.selectList("findstudentbyteacher", "李华");
它的意思就是找到相对应xml文件中,id为findstudentbyteacher,输入参数为“李华”的数据库查询语句,但是却十分麻烦。对于上面这个问题,我们可以采用Mapper动态代理来解决。通过 Mapper 动态代理机制,可以只编写数据交互的接口及方法定义和对应的 Mapper 映射文件,下面通过例子来详细了解一下:首先我们还是用Student类来应用Mapper的动态代理,新建一个Studentmapper.xml文件:
注意这里的namespace中指定的是mapper包下我们自定义的一个接口StudentMapper,我们就是要使用这个接口,这样就可以在业务类中使用mapper代理了:
public interface StudentMapper {
List selectstudent() throws Exception;
void insertstudent(Student student) throws Exception;
void deletestudent(int id) throws Exception;
void updatestudent(Student student) throws Exception;
}
记得在mybatis-config.xml文件中配置Mapper映射文件,测试代码session需要调用getMapper方法来实现动态代理,接着直接调用接口的方法就可以了
@Test
public void test() throws Exception {
InputStream inputStream= Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=factory.openSession();
StudentMapper studentMapper=session.getMapper(StudentMapper.class);
List students=studentMapper.selectstudent();
for (Student student:students){
System.out.println(student.getName());
}
}
输出结果:
------------------------------------------------------------------------------------------------------------------------------------
使用注解开发Mybatis
使用注解开发可以让程序看起来更加简洁和容易理解,MyBatis也提供了不少注解,上面的这个例子,我们可以省略掉xml的编写过程,直接用注解来实现,具体代码如下:
public interface StudentMapper {
@Select("select * from student")
List selectstudent() throws Exception;
@Insert("insert into student(id,name) values (#{id},#{name})")
void insertstudent(Student student) throws Exception;
@Delete(" delete from student where id=(#{id})")
void deletestudent(int id) throws Exception;
@Update("update student set name=#{name} where id=#{id}")
void updatestudent(Student student) throws Exception;
}
在mybatis-config.xml文件中修改映射信息:这样就实现了和xml同样的功能。