闲话
快乐的周末又来了,希望这周能把Mybatis整理完
基本要点
1、Lombok
作用:在我们的实体类中,我们再也不需要声明get、set、有参无参等方法,统统可以通过Lombok注解来实现同样的功能
使用步骤:
- 安装插件:setting—>plugin中搜索Lombok进行安装
- 引入依赖:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
- 使用注解,下面介绍一点常用的
@Data:get/set 无参构造 tostring hascode equals @AllArgsConstructor:有参构造,使用之后,无参构造需要显示定义 @NoArgsConstructor:无参构造
局限性:
- 只支持所有参数类型的有参构造
- 降低了源码的可读性和完整性
2、多对一处理
假设我和我的朋友们都喜欢高代课,我们四个的老师叫赵哥 对于赵哥来说,他是一个教我们四个,一对多称为集合 对于我们来说,我们四个都是赵哥小弟,多对一称为关联
1)需求
现在,我们的家长想知道,为什么我们四个人的高代成绩为什么有的人过了有的人没过 到底是不是一个老师教的,所以需要从我们入手,查出我们各自的高代老师
2)实现
首先我们先在数据库中创建学生表和教师表,插入一下我们和赵哥的信息
create table t_decade_teacher
(
`id` INT(10) NOT NUll,
`name` VARCHAR(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB CHARACTER SET = utf8;
insert into t_decade_teacher(`id`,`name`)values(1,'赵哥');
create table t_decade_student
(
`id` INT(10) NOT NULL,
`name` VARCHAR(50) DEFAULT null,
`tid` INT(10) DEFAULT null,
PRIMARY KEY (`id`),
FOREIGN key (`tid`) REFERENCES `t_decade_teacher` (`id`)
) ENGINE=INNODB CHARACTER SET = utf8;
insert into t_decade_student(`id`,`name`,`tid`)VALUES(1,'十年',1);
insert into t_decade_student(`id`,`name`,`tid`)VALUES(2,'石少爷',1);
insert into t_decade_student(`id`,`name`,`tid`)VALUES(3,'天宇',1);
insert into t_decade_student(`id`,`name`,`tid`)VALUES(4,'明哥',1);
然后我们新建对应的实体类
package com.decade.pojo;
import lombok.Data;
@Data
public class Teacher {
private int id;
private String name;
}
package com.decade.pojo;
import lombok.Data;
@Data
public class Student {
private int id;
private String name;
private Teacher teacher;
}
新建我们学生的接口类
package com.decade.mapper;
public interface StudentMapper {
List<Student> getStudentInfo();
List<Student> getStudentInfo2();
}
然后是对应的SQL映射文件(我放在了resource文件夹下,注意映射文件所在的包路径需要和Java文件夹下的接口类的路径保持一致,因为我用了2种映射器的注册方式)
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.decade.mapper.StudentMapper">
<resultMap id="studentInfoMap" type="student">
<result column="id" property="id"/>
<result column="name" property="name"/>
<association column="tid" property="teacher" javaType="teacher" select="selectTeacherInfo"/>
</resultMap>
<select id="getStudentInfo" resultMap="studentInfoMap">
select * from t_decade_student
</select>
<select id="selectTeacherInfo" resultType="teacher">
select * from t_decade_teacher where id = #{id}
</select>
<resultMap id="studentInfoMap2" type="student">
<result column="sid" property="id"/>
<result column="sname" property="name"/>
<association property="teacher" javaType="teacher">
<result column="tid" property="id"/>
<result column="tname" property="name"/>
</association>
</resultMap>
<select id="getStudentInfo2" resultMap="studentInfoMap2">
select s.id as sid, s.name as sname,t.id as tid, t.name as tname
from t_decade_student s left join t_decade_teacher t
on s.tid = t.id
</select>
</mapper>
并在核心配置文件中进行注册 我这里使用映射器接口和相对于类路径的资源引用两种方式进行注册
<?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 resource="db.properties">
<property name="username" value="decade"/>
<property name="password" value="11111"/>
</properties>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<package name="com.decade.pojo"/>
</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="com/decade/mapper/TeacherMapper.xml"/>
<mapper class="com.decade.mapper.StudentMapper"/>
</mappers>
</configuration>
最后我们写一个测试类进行测试
import com.decade.mapper.StudentMapper;
import com.decade.pojo.Student;
import com.decade.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class MyTest {
@Test
public void test2() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> student = mapper.getStudentInfo();
student.forEach(System.out::println);
System.out.println("=========================");
List<Student> studentInfo = mapper.getStudentInfo2();
studentInfo.forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
} finally {
sqlSession.close();
}
}
}
运行结果如下,我靠,居然都是赵哥教的,看来他针对我!
3、一对多
现在,我们换一个角度,我们想从赵哥下手,查出他所有学生的信息
我们在上面例子的基础上调整一下学生和老师的实体类
package com.decade.pojo;
import lombok.Data;
@Data
public class Student2 {
private int id;
private String name;
private int tid;
}
package com.decade.pojo;
import lombok.Data;
import java.util.List;
@Data
public class Teacher2 {
private int id;
private String name;
private List<Student2> studentList;
}
新建赵哥他们老师的接口类和对应的SQL映射文件
package com.decade.mapper;
import com.decade.pojo.Teacher2;
import org.apache.ibatis.annotations.Param;
public interface TeacherMapper {
Teacher2 selectTeacherInfo(@Param("id") int id);
Teacher2 selectTeacherInfo2(@Param("id") int id);
}
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.decade.mapper.TeacherMapper">
<resultMap id="teacherInfoMap" type="com.decade.pojo.Teacher2">
<result column="id" property="id"/>
<result column="name" property="name"/>
<collection property="studentList" javaType="ArrayList"
ofType="student2" select="selectStudentByTeacher" column="id"/>
</resultMap>
<select id="selectTeacherInfo" resultMap="teacherInfoMap">
select * from t_decade_teacher where id = #{id}
</select>
<select id="selectStudentByTeacher" resultType="student2">
select * from t_decade_student where tid = #{id}
</select>
<resultMap id="teacherInfoMap2" type="teacher2">
<result column="tid" property="id"/>
<result column="tname" property="name"/>
<collection property="studentList" ofType="student2">
<result column="sid" property="id"/>
<result column="sname" property="name"/>
<result column="stid" property="tid"/>
</collection>
</resultMap>
<select id="selectTeacherInfo2" resultMap="teacherInfoMap2">
select t.id as tid, t.name as tname, s.id as sid, s.name as sname, s.tid as stid
from t_decade_teacher t left join t_decade_student s
on t.id = s.tid
where t.id = #{id}
</select>
</mapper>
最后我们写一个测试方法进行测试
import com.decade.mapper.TeacherMapper;
import com.decade.pojo.Teacher2;
import com.decade.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
public class MyTest {
@Test
public void test() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher2 teacherInfo = mapper.selectTeacherInfo(1);
System.out.println(teacherInfo);
System.out.println("=================================");
Teacher2 teacherInfo2 = mapper.selectTeacherInfo2(1);
System.out.println(teacherInfo2);
} catch (Exception e) {
e.printStackTrace();
} finally {
sqlSession.close();
}
}
}
运行结果如下
结果集映射resultMap中涉及到一对多就用集合collection,涉及到多对一就用关联association
javaType:用来指定实体类中属性的类型
ofType:如果属性是集合,那么用这个来指定泛型的约束类型
如有错误,欢迎指正!
|