10.多对一处理
题目需求
- 一个班级很多个学生,但是班主任只有一个
- 每一个学生表,的tid都对应班主任,这就是多对一
前期准备–复杂环境搭建:
在数据库中,建立student和teacher
CREATE TABLE `teacher`(
`id` INT(10) NOT NULL PRIMARY KEY,
`name` VARCHAR(30) DEFAULT NULL
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO teacher(`id`,`name`) VALUES(1,'陈老师');
SELECT * FROM teacher
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);
SELECT * FROM student
idea连接数据库,建立maven项目,导入lombok包(可选)
建立如下文件,
-
dao包中建立接口,StudentMapper.java,TeacherMapper.java
-
pojo包中建立实体类,Student.java,Teacher.java
-
utils包建立MybatisUtils.java的SqlSession配置类
-
在resources中,建立一个新的目录com.kuang.dao(和接口一样),建立
-
StudentMapper.xml,
-
TeacherMapper.xml。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper> </mapper>
-
db.properties
-
mybatis-config.xml
在测试后会发现,如果mapper是class绑定,会在Target中将接口StudentMapper.java和StudentMapper.xml生成在一起。
如果有错误,大概率是绑定位置找不到,回头看看mapper映射。
10.1resultMap嵌套查询,
1.查询学生信息以及老师的名字
1.teacher和Student两个实体类,都加@Data,使得不用去写get,set等方法
import lombok.Data;
@Data
public class Student {
private int id;
private String name;
//使用组合,每一个学生关联一个老师
private Teacher teacher;
}
import lombok.Data;
@Data
public class Teacher {
private int id;
private String name;
}
注意,这里的Student实体类的teacher属性是一个对象。使用组合的方式。这个要和Student表中的tid属性关联。
2.MybatisUtils工具类。
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
//静态代码会在初始会被加载
static {
try {
//使用mybatis第一步,获取sqlSessionFactory对象
String resource="mybatis-config.xml";
InputStream inputStream= Resources.getResourceAsStream(resource);
sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//sqlSessionFactory是能执行sql的对象
} catch (IOException e) {
e.printStackTrace();
}
}
//这里是在静态代码块之外,
//有了SqlSessionFactory,就可以获取SqlSession的实例,sqlSession包含了数据库执行的SQL的所有方法
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession(true);
//当这里为true时,自动提交事务
}
}
3.resources包下的连接数据库文件的配置
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=sa
4.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配置文件必须在最上面,在xml中标签要按顺序写-->
<properties resource="db.properties">
</properties>
<settings>
<!--标准的日志工厂模式-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--别名,xml中的别名标签必须放在第三个位置。默认的
<typeAlias type="com.kuang.pojo.User" alias="User"></typeAlias>-->
<typeAliases>
<typeAlias type="com.kuang.pojo.Student" alias="Student"></typeAlias>
<typeAlias type="com.kuang.pojo.Teacher" alias="Teacher"></typeAlias>
</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>
<!--之前使用xml开发,需要绑定mapper.xml
现在使用注解开发需要绑定接口(我们在接口上面写的注解)
-->
<mappers>
<mapper class="com.kuang.dao.TeacherMapper"></mapper>
<mapper class="com.kuang.dao.StudentMapper"></mapper>
</mappers>
</configuration>
注意,
-
这里的别名是实体类的别名,
-
mapper的映射文件要对应到相应的接口
-
用class时,接口和xml配置文件要目录相同。
-
接口名要和xml配置文件名相同
5.设置接口和方法StudentMapper,TeacherMapper,
import com.kuang.pojo.Student;
import java.util.List;
public interface StudentMapper {
//查询所有的学生信息以及对应的老师的名字
public List<Student> getStudent();
}
import com.kuang.pojo.Teacher;
public interface TeacherMapper {
Teacher getTeacher(int id);
}
6.最重要的部分,配置接口的xml文件
StudentMapper.xml和TeacherMapper.xml(因为mapper映射前面用的是class,所以必须接口和xml同名,且目录相同)
方式一,子查询
StudentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.dao.StudentMapper">
<!---方式一,子查询-->
<select id="getStudent" resultMap="StudentTeacher">
select * from student
</select>
<resultMap id="StudentTeacher" type="Student">
<result property="id" column="id"></result>
<result property="name" column="name"></result>
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher">
</association>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from teacher where id=#{id}
</select>
</mapper>
方式二。更具结果集映射查询
<!--********************方式二,根据结果集映射查询-->
<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>
<result property="name" column="sname"></result>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"></result>
</association>
</resultMap>
思路:
1.查询所有的学生
2.根据查询的学生tid,寻找对应的老师
我们需要的查询结果SQL: select s.id,s.name,t.name from student s,teacher t where s.tid=t.id;
当查询的对象复杂时,需要用到结果集映射
association **对象**使用它
collection **集合**使用它
解释
association中,
property对应的是Student类的teacher属性,
column是对应Student表的tid字段,
javaType是对应的Teacher类
select是子查询,对应的是select * from teacher where id=#{id}的查询id
注意,在Student的查询中是resultMap,
TeacherMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.dao.TeacherMapper">
</mapper>
7.测试
@Test
//查询学生信息并且包含老师的名字
public void getStudent(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> studentList = mapper.getStudent();
for (Student student:studentList
) {
System.out.println(student);
}
sqlSession.close();
}