概念
现有一个数据库:
CREATE TABLE `teacher` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO teacher(`id`, `name`) VALUES (1, '秦老师');
CREATE TABLE `student` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fktid` (`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');
创建结果入图:
创建结果
此时,对学生来说
多个学生关联了一个老师,这叫多对一
对老师来说
一个老师集合了多个学生,这叫一对多
在mybatis中,使用结果集映射可以实现该效果
mybatis的结果集映射resultMap标签中可以定义association和collection来将对象或者List集合映射到实体类的属性中
association:将对象映射到实体类属性 --- 关联
collection:将List集合映射到实体类属性 --- 集合
javatype:用来指定实体类中属性的类型
oftype:用来指定集合中泛型的类型
复杂查询环境搭建
1、创建maven子工程
目录结构
2、在mybatis核心配置文件中,导入需要使用的jar包依赖
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId> <!--log4j日志-->
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId><!--lombok插件-->
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
</dependencies>
3、创建数据库,并插入信息
创建结果
4、创建表对应的实体类
老师实体类
@Data //使用lombok注解简化类,该注解课自动生成get、set、toString等方法
public class teacher {
private int id;
private String name;
public teacher(int id, String name) { //需要手动设置有参构造
this.id = id;
this.name = name;
}
}
学生实体类
@Data
public class student {
private int id;
private String name;
private teacher teacher; //关联teacher
public student(int id, String name, cn.yzx.pojo.teacher teacher) {
this.id = id;
this.name = name;
this.teacher = teacher;
}
}
5、创建实体类对应的Mapper映射
mapper映射
6、在resources配置文件夹下,创建对应包名的文件夹,并创建于mapper映射接口相同的xml文件
xml文件
7、在mybatis-config.xml导入外部数据库配置、设置日志类型、为实体类设置别名、配置环境、注册映射文件
<configuration>
<!--外部导入配置文件-->
<properties resource="db.properties"/>
<!--开启日志-->
<settings>
<setting name="logImpl" value="LOG4J"/>
<!-- <setting name="logImpl" value="STDOUT_LOGGING"/>-->
</settings>
<!--设置别名-->
<typeAliases>
<typeAlias type="cn.yzx.pojo.student" alias="student"/>
<typeAlias type="cn.yzx.pojo.teacher" alias="teacher"/>
</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 resource="cn/yzx/mapper/teacherMapper.xml" />
<mapper resource="cn/yzx/mapper/studentMapper.xml" />
</mappers>
</configuration>
8、在util包下创建mybatisUtil工具类,用于获取连接对象
public class mybatisUtil {
private static SqlSessionFactory sqlSessionFactory = null;
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}catch (Exception e){
e.printStackTrace();
}
}
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
9、在test测试包下创建对用包名,对应测试类进行测试
对应包名、测试类
@Test
public void testFindAllTeacher() {
SqlSession sqlSession = mybatisUtil.getSqlSession();
teacherMapper mapper = sqlSession.getMapper(teacherMapper.class);
teacher allTeacher = mapper.findAllTeacher();
System.out.println(allTeacher);
sqlSession.close();
}
10、正确读取表数据,测试成功,环境搭建完成
测试结果
多对一查询
需求:查询学生信息,并根据学生表的tid获取对应teacher的值
方式一:按照查询,嵌套处理(子查询)
1、在学生mapper接口创建对应方法
2、在xml中创建对应sql语句,因为student中关联了teacher,所以需要使用结果集映射中的association标签将从student表中获取的tid与teacher表中的tid对应获取的teacher对象映射到student实体类的tec属性上,从而获取teacher的信息,其中
xml
3、在test类中进行测试,获取结果
查询结果
方式二:按照结果,嵌套处理(多表查询,推荐方式,不破坏sql)
1、在studentMapper接口中定义方法
2、在xml中创建对应sql语句,进行多表查询直接根据student的tid和teacher的id查询出tname,并设置别名,使用结果集映射将结果映射到对应属性,并使用association将student实体类的tec属性直接映射为teacher类型,并在内部再次映射,与tec对应的teacher类的name属性为多表查询结果重的tname,id为student的tid
3、在test类中进行测试,获取结果
查询结果
一对多查询
需求:查询老师以及老师的所有学生
方式一:按照结果,嵌套处理(多表查询,推荐方式,不破坏sql)
1、修改环境,此时视角为老师,所以student实体类中不需要关联老师,而在老师实体类中则需要定义List集合装载多个学生
@Data
public class student {
private int id;
private String name;
private int tid;
}
@Data
public class teacher {
private int id;
private String name;
private List<student> students; //一个老师有多个学生
}
2、在接口中定义方法
定义方法
3、在xml中定义sql语句
xml
4、在test类中进行测试,获取结果
查询结果
方式二:按照查询,嵌套处理(子查询)
1、在接口中定义方法
2、在xml中定义sql语句
xml
3、在test类中进行测试,获取结果
查询结果
网友评论