Mybatis Lombok使用方法与复杂查询介绍
作者:Decade0712
基本要点
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,javaType是指定属性的类型,这里就是Teacher类 --> <association column="tid" property="teacher" javaType="teacher" select="selectTeacherInfo"/> </resultMap> <!-- 我们查询多对一的方式时,有2种思路 第一种:按查询嵌套处理,类似子查询 --> <select id="getStudentInfo" resultMap="studentInfoMap"> select * from t_decade_student </select> <!-- 子查询语句,需要使用外键作为查询条件 比如这里学生和老师就是用tid关联起来的 --> <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"/> <!-- 这里我们直接把Teacher类和查询语句中输出的字段关联起来 --> <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"> <!--驱动配置,com.mysql.jdbc.driver --> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <!--每一个mapper.xml文件都需要在核心配置文件中注册--> <mappers> <mapper resource="com/decade/mapper/TeacherMapper.xml"/> <mapper class="com.decade.mapper.StudentMapper"/> <!-- <package name="com.decade.mapper"/>--> </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"/> <!-- 因为我们这里需要用到teacher的id作为嵌套查询的条件,所以我们这里的column字段使用id --> <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:如果属性是集合,那么用这个来指定泛型的约束类型
到此这篇关于Mybatis Lombok使用方法与复杂查询介绍的文章就介绍到这了,更多相关Mybatis Lombok内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!