Bootstrap

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(是否每次查询都清空缓存)等

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;