1. 创建数据库表
tb_classroom 帖子表
-- Table: public.tb_classroom
-- DROP TABLE public.tb_classroom;
CREATE TABLE public.tb_classroom
(
id integer NOT NULL DEFAULT nextval('tb_classroom_id_seq'::regclass),
classroom_no character varying(20) COLLATE pg_catalog."default" NOT NULL,
name character varying(20) COLLATE pg_catalog."default" NOT NULL,
CONSTRAINT tb_classroom_pkey PRIMARY KEY (id)
)
WITH (
OIDS = FALSE
)
TABLESPACE pg_default;
ALTER TABLE public.tb_classroom
OWNER to postgres;
COMMENT ON TABLE public.tb_classroom
IS '班级信息表';
-- Index: unique_index_on_classroom_no
-- DROP INDEX public.unique_index_on_classroom_no;
CREATE UNIQUE INDEX unique_index_on_classroom_no
ON public.tb_classroom USING btree
(classroom_no COLLATE pg_catalog."default")
TABLESPACE pg_default;
插入数据:
INSERT INTO "public"."tb_classroom" VALUES ('1', 'C003001', '三年一班');
INSERT INTO "public"."tb_classroom" VALUES ('3', 'C003002', '三年二班');
tb_student 用户表
-- Table: public.tb_student
-- DROP TABLE public.tb_student;
CREATE TABLE public.tb_student
(
id integer NOT NULL DEFAULT nextval('tb_student_id_seq'::regclass),
student_no character varying(20) COLLATE pg_catalog."default" NOT NULL,
name character varying(20) COLLATE pg_catalog."default" NOT NULL,
age smallint NOT NULL,
score real NOT NULL,
classroom_no character varying(20) COLLATE pg_catalog."default" NOT NULL,
CONSTRAINT tb_student_pkey PRIMARY KEY (id)
)
WITH (
OIDS = FALSE
)
TABLESPACE pg_default;
ALTER TABLE public.tb_student
OWNER to postgres;
COMMENT ON TABLE public.tb_student
IS '学生信息表';
-- Index: unique_index_on_student_no
-- DROP INDEX public.unique_index_on_student_no;
CREATE UNIQUE INDEX unique_index_on_student_no
ON public.tb_student USING btree
(student_no COLLATE pg_catalog."default")
TABLESPACE pg_default;
插入数据:
INSERT INTO "public"."tb_student" VALUES ('1', 'S315060012', '小明', '25', '88.5', 'C003001');
INSERT INTO "public"."tb_student" VALUES ('2', 'S315060039', '小黄', '24', '92.5', 'C003001');
INSERT INTO "public"."tb_student" VALUES ('3', 'S315060011', '小白', '22', '85', 'C003002');
2. 创建POJO对象
Classroom 对象
package com.tao.springmybatispostgresql.entity;
import lombok.*;
import java.util.List;
/**
* 班级实体, 对应数据库中的tb_classroom表
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Classroom {
private Integer id;
private String classroomNo;
private String name;
/**
* 注意: 我们在Classroom类中定义一个studentList,
* 用来表示在同一个班的所有学生的集合.
* 这里虽然在tb_classroom表中没有对应的字段, 但是也是可以这样定义的.
*/
private List<Student> studentList;
}
Student 对象
package com.tao.springmybatispostgresql.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 学生实体, 对应数据库中的tb_student表
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private Integer id;
private String studentNo;
private String name;
private Integer age;
private Float score;
private String classroomNo;
}
3. 创建接口和xml文件
IClassroomMapper 接口
package com.tao.springmybatispostgresql.mapper;
import com.tao.springmybatispostgresql.entity.Classroom;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
/**
* 班级实体对应的数据操作接口
*/
@Mapper
@Repository("classroomMapper")
public interface IClassroomMapper {
/**
* 通过classroomNo获取对应Classroom对象的信息
* @param classroomNo
* @return
*/
Classroom getClassroomByNo(String classroomNo);
}
ClassroomMapper.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="com.tao.springmybatispostgresql.mapper.IClassroomMapper">
<resultMap id="classroomResultMap" type="com.tao.springmybatispostgresql.entity.Classroom">
<id property="id" column="c_id"/>
<result property="classroomNo" column="classroom_no"/>
<result property="name" column="classroom_name"/>
<collection property="studentList" ofType="com.tao.springmybatispostgresql.entity.Student">
<id property="id" column="s_id"/>
<result property="studentNo" column="student_no"/>
<result property="name" column="student_name"/>
<result property="age" column="age"/>
<result property="score" column="score"/>
<result property="classroomNo" column="classroom_no"/>
</collection>
</resultMap>
<select id="getClassroomByNo" parameterType="String" resultMap="classroomResultMap">
SELECT
c.id AS c_id,
c.classroom_no,
c.name AS classroom_name,
s.id AS s_id,
s.student_no,
s.name AS student_name,
s.age,
s.score,
s.classroom_no
FROM tb_classroom c, tb_student s
WHERE s.classroom_no = c.classroom_no AND c.classroom_no = #{classroomNo}
</select>
</mapper>
4. Controller 测试
package com.tao.springmybatispostgresql.web.controller;
import com.tao.springmybatispostgresql.entity.Classroom;
import com.tao.springmybatispostgresql.entity.Post;
import com.tao.springmybatispostgresql.mapper.IClassroomMapper;
import com.tao.springmybatispostgresql.mapper.IPostMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
IClassroomMapper classroomMapper;
@GetMapping("/classroom/get/{classroomNo}")
public Classroom getClassroomInfoByClassroomNo(@PathVariable("classroomNo") String classroomNo) {
Classroom classroom = classroomMapper.getClassroomByNo(classroomNo);
return classroom;
}
}
5. 结果截图
6. 几个坑需要注意
1、两张表有相同的属性字段 name
, 导致查询结果中 Classroom
的 name
字段值会覆盖 Student
中 name
字段值, 因此出现如下现象:
问题出在 ClassroomMapper.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="com.tao.springmybatispostgresql.mapper.IClassroomMapper">
<resultMap id="classroomResultMap" type="com.tao.springmybatispostgresql.entity.Classroom">
<id property="id" column="c_id"/>
<result property="classroomNo" column="classroom_no"/>
<result property="name" column="name"/>
<collection property="studentList" ofType="com.tao.springmybatispostgresql.entity.Student">
<id property="id" column="s_id"/>
<result property="studentNo" column="student_no"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="score" column="score"/>
<result property="classroomNo" column="classroom_no"/>
</collection>
</resultMap>
<select id="getClassroomByNo" parameterType="String" resultMap="classroomResultMap">
SELECT
c.id AS c_id,
c.classroom_no,
c.name,
s.id AS s_id,
s.student_no,
s.name,
s.age,
s.score,
s.classroom_no
FROM tb_classroom c, tb_student s
WHERE s.classroom_no = c.classroom_no AND c.classroom_no = #{classroomNo}
</select>
</mapper>
解决办法:
对于相同的字段, 在写SQL的时候最好起不同的别名来区分!!!
修改之后的 ClassroomMapper.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="com.tao.springmybatispostgresql.mapper.IClassroomMapper">
<resultMap id="classroomResultMap" type="com.tao.springmybatispostgresql.entity.Classroom">
<id property="id" column="c_id"/>
<result property="classroomNo" column="classroom_no"/>
<result property="name" column="classroom_name"/>
<collection property="studentList" ofType="com.tao.springmybatispostgresql.entity.Student">
<id property="id" column="s_id"/>
<result property="studentNo" column="student_no"/>
<result property="name" column="student_name"/>
<result property="age" column="age"/>
<result property="score" column="score"/>
<result property="classroomNo" column="classroom_no"/>
</collection>
</resultMap>
<select id="getClassroomByNo" parameterType="String" resultMap="classroomResultMap">
SELECT
c.id AS c_id,
c.classroom_no,
c.name AS classroom_name,
s.id AS s_id,
s.student_no,
s.name AS student_name,
s.age,
s.score,
s.classroom_no
FROM tb_classroom c, tb_student s
WHERE s.classroom_no = c.classroom_no AND c.classroom_no = #{classroomNo}
</select>
</mapper>
修改之后返回的数据不会存在覆盖的问题:
2、SQL文件没有问题, 但是无论如何 studentList
只输出一个 Student
对象.
这个问题出现的原因是 Classroom
和 Student
表中有相同的字段 id
:
对应的 ClassroomMapper.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="com.tao.springmybatispostgresql.mapper.IClassroomMapper">
<resultMap id="classroomResultMap" type="com.tao.springmybatispostgresql.entity.Classroom">
<id property="id" column="id"/>
<result property="classroomNo" column="classroom_no"/>
<result property="name" column="classroom_name"/>
<collection property="studentList" ofType="com.tao.springmybatispostgresql.entity.Student">
<id property="id" column="id"/>
<result property="studentNo" column="student_no"/>
<result property="name" column="student_name"/>
<result property="age" column="age"/>
<result property="score" column="score"/>
<result property="classroomNo" column="classroom_no"/>
</collection>
</resultMap>
<select id="getClassroomByNo" parameterType="String" resultMap="classroomResultMap">
SELECT
c.id,
c.classroom_no,
c.name AS classroom_name,
s.id,
s.student_no,
s.name AS student_name,
s.age,
s.score,
s.classroom_no
FROM tb_classroom c, tb_student s
WHERE s.classroom_no = c.classroom_no AND c.classroom_no = #{classroomNo}
</select>
</mapper>
这个问题的解决办法是:
在写SQL的时候对两张表的
id
字段起别名, 避免使用相同的名!!!
修改之后的 ClassroomMapper.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="com.tao.springmybatispostgresql.mapper.IClassroomMapper">
<resultMap id="classroomResultMap" type="com.tao.springmybatispostgresql.entity.Classroom">
<id property="id" column="c_id"/>
<result property="classroomNo" column="classroom_no"/>
<result property="name" column="classroom_name"/>
<collection property="studentList" ofType="com.tao.springmybatispostgresql.entity.Student">
<id property="id" column="s_id"/>
<result property="studentNo" column="student_no"/>
<result property="name" column="student_name"/>
<result property="age" column="age"/>
<result property="score" column="score"/>
<result property="classroomNo" column="classroom_no"/>
</collection>
</resultMap>
<select id="getClassroomByNo" parameterType="String" resultMap="classroomResultMap">
SELECT
c.id AS c_id,
c.classroom_no,
c.name AS classroom_name,
s.id AS s_id,
s.student_no,
s.name AS student_name,
s.age,
s.score,
s.classroom_no
FROM tb_classroom c, tb_student s
WHERE s.classroom_no = c.classroom_no AND c.classroom_no = #{classroomNo}
</select>
</mapper>
修改之后的返回结果恢复正常: