Java学习路线:MyBatis(七)使用注解开发
目录
用注解实现增删改查
注解实现自定义映射
注解实现复杂查询
@Many
@One
用注解实现构造方法
注解开启缓存
在前面学习了使用xml映射器实现配置MyBatis,但还是觉得有点麻烦
而MyBatis提供了一种更简洁的方法——使用注解进行开发
用注解实现增删改查
当我们使用xml进行映射器编写时,需要先定义映射规则和SQL语句,再将其封装到接口中,通过调用接口执行:
<insert id="insertStudent" parameterType="student" flushCache="false">
insert into student(number,name,gender) values(#{number},#{name},#{gender});
</insert>
在接口中定义:
int insertStudent(student s);
使用注解可以直接实现这个操作:
@Insert("insert into student(number,name,gender) values(#{number},#{name},#{gender})")
int insertStudent(student s);
想使用注解的话,还需要在MyBatis文件中进行配置的修改
在mybatis-config.xml文件中,原本定义的是
<mappers>
<mapper resource="com/test/Mapper/TestMapper.xml"/>
</mappers>
然而这里已经不需要xml文件了,因此将其修改为:
<mappers>
<mapper class="com.test.Mapper.TestMapper"/>
</mappers>
class中填写指定的mapper接口
如果同时有很多mapper,一个一个写很麻烦,也可以直接指定一个package,package下所有的mapper都有效
<mappers>
<mapper package="com.test.Mapper"/>
</mappers>
通过指定 class/package,让MyBatis知道我们这里有一个通过注解实现的映射器
注解实现自定义映射
使用@Results注解可以实现自定义映射
在.xml文件中,自定义映射是这样的:
<resultMap id="asTeacher" type="teacher">
<id column="tid" property="tid"/>
<result column="name" property="name"/>
</resultMap>
<select id="getTeacherById" resultMap="asTeacher">
select * from teacher
</select>
如果使用注解,则变成这样:
@Results({
@Result(id = true, column = "tid", property = "tid"),
@Result(column = "name", property = "name")
})
@Select("select * from teahcer")
List<teacher> getTeacherById();
在注解中,Results是一个注解数组,每一个@Result注解都对应一个单独的字段配置
设置id=true表示当前字段是主键
注解实现复杂查询
前提知识:
Java学习路线:MyBatis(四)复杂查询-CSDN博客
@Many
还是使用之前在:
Java学习路线:MyBatis(四)复杂查询-CSDN博客
中提到的例子,假设一个老师教授多个学生
老师的类为:
public class teacher {
int tid;
String name;
List<student> studentList;
}
使用注解的方法实现复杂查询的代码如下:
@Results({
@Result(id = true, column = "tid", property = "tid"),
@Result(column = "name", property = "name"),
@Result(column = "tid", property = "studentList",many =
@Many(select = "getStudentById")
)
})
@Select("select * from teahcer where tid=#{tid}")
List<teacher> getTeacherById(int tid);
@Select("select * from student inner join teach on student.sid=teach.sid where tid=#{tid}")
student getStudentById(int tid);
在上述代码中,和普通查询不一样的是,多出了一行
@Result(column = "tid", property = "studentList",many =
@Many(select = "getStudentById")
)
在这一行中,column表示传入many的参数(tid),property表示Java中对应的字段
many是Result的一个内置属性,通过@many来选择studentList中存入的内容
在这里存入的内容即getStudentById的返回结果
@One
除了@Many标签,Result中还有一个标签@One,可以用于实现一对一的关系,相当于xml文件中的association
假设学生类和老师类为:
@Data
@Accessors(chain = true)
public class student {
int number;
String name;
String gender;
teacher teacher;
}
public class teacher {
int tid;
String name;
}
每个学生对应一个老师,每个老师教授多个学生,我们想实现查询学生的时候,同时也查询到这个学生对应的老师,用注解实现如下:
@Results({
@Result( column = "sid", property = "sid"),
@Result( column = "name", property = "name"),
@Result( column = "sid", property = "teacher",one =
@One(select = "getTeacherByStudentId"))
})
@Select("select * from student where sid=#{sid}")
student getStudentById(int sid);
@Select("select * from teacher inner join teach on teacher.tid=teach.tid where sid={sid}")
teacher getTeacherByStudentId(int sid);
在这里,使用@One规定了Student中teacher字段对应的内容
用注解实现构造方法
之前在xml文件中,使用<constructor>标签可以指定构造方法,那么用注解如何指定构造方法呢?
@ConstructorArgs({
@Arg(column = "sid", javaType = int.class),
@Arg(column = "name", javaType = String.class)
})
@Select("select * from student where sid= #{sid}")
student getStudentById(int sid);
在上述代码中,使用@ConstructorArgs指定了构造方法,选择了参数为sid和name的构造方法,javaType表示参数在Java中的类型
但是,当我们传入多个参数时,MyBatis会报错,例如:
@Select("select * from student where sid= #{sid} and name = #{name}")
student getStudentById(int sid,String name);
对于上述代码,MyBatis会出现如下错误:
那假如想要传多个参数,应该如何使用呢?
这时,需要在参数前加上@Param注解
@Select("select * from student where sid= #{sid} and name = #{name}")
student getStudentById(@Param("sid") int sid,@Param("name") String name);
@Param括号中填的是上面#{xxx}括号中的内容
作用是让MyBatis知道传入的参数是如何对应的
如果传入的参数有对象类型, 则在SQL语句中访问对象的属性,需要明确参数是哪个对象的属性
@Insert("insert into student(sid,name) values(#{sid},#{student.name})")
student getStudentById(@Param("sid") int sid,@Param("student") student s);
注解开启缓存
使用注解配置缓存需要在接口前面添加@CacheNamespace,和xml一样,注解中也存在readWrite、eviation、flushInterval等属性
@CacheNamespace(readWrite = true)
public interface TestMapper {
想要对某一个操作开启缓存,只需要在该方法前添加@Options(useCache=true)
@Options(useCache=true)
student getStudentById(int sid);
同理,@Options注解中也有许多参数可以调整,例如flushCache(是否每次查询都清空缓存)等