目录
1、映射器注解
前言:
映射器虽然能很好的解决了sql拼接的问题,但是它还是相对于有些繁琐, 配置文件的书写本身繁琐,需要掌握的内容也比较多。还有就是我们的接口名要和映射器的id名称相同, 对应起来比较麻烦。
(1)常用的注解
- 基本注解:实现简单的增删改查操作。
- 结果映射注解:实现结果的映射关系,也可以完成级联映射。
- 动态SQL注解:实现动态 SQL 的内容。
2、基本注解
(1)基本注解分类
增加操作:@Insert 类似 < insert > 完成新增。
删除操作:@Delete 类似 < delete > 完成删除。
修改操作:@Update 类似 < update > 完成修改。
查询操作:@Select 类似 < select > 完成查询。
注意:每个注解都有一个宿主,自己的注解关系不要声明,直接调用即可。别人的注解要声明。
(2)Insert新增
功能:完成新增操作,类似配置文件的<insert>元素;
说明:新增时所用的参数取值是接口方法的入参,可以是对象,也可以是 Map 集合。
示例代码:
@Insert("insert into student(sname,birthday,ssex,classid) values(#{sname},#{birthday},#{ssex},#{classid})")
public int addStudent(Student s);
主键回填:
功能:完成数据库自增主键的回填;
主键自增:
功能:完成自定义主键的自增;
(3)@Delete 删除
功能:完成删除操作,类似配置文件的元素;
说明:删除时所用的参数取值是接口方法的入参,可以是对象,也可以是 Map 集合。
示例代码:
@Delete("delete from student where sid = #{value}")
public int deleteStudent(int sid);
(4)@Update 更新
功能:完成更新操作,类似配置文件的<update>元素;
说明:更新时所用的参数取值是接口方法的入参,可以是对象,也可以是 Map 集合。
示例代码:
@Update("update student set sname = #{sname},birthday=#{birthday},ssex=#{ssex},classid=#{classid} where sid = #{sid}")
public int updateStudent(Student s);
(5)@Select 查询
功能:完成查询操作,类似配置文件的<select>元素;
说明:查询时所用的参数取值是接口方法的入参,可以是对象,也可以是 Map 集合。
示例代码:
@Select("select * from student where classid = #{value}")
public List<Student> findStudentByClassid(int classid);
(6)传递多个参数的方式
方法一:Map方式,跟sqlmap一样。
方法二:JavaBean方式,跟sqlmap一样。
方法三:@Param方式
示例代码:
3、结果映射注解
跟映射器中的resultMap一样的性质,就是为了解决有字段对应不上属性,或者属性不知道怎么对应的情况下,注解使用的是Results结果映射。
功能: 完成数据库字段和 JavaBean 属性的映射关系;
说明:每个 @Results 可以包含多个 @Result,其中通过 id 属性来判断是否为主键。
示例代码:
@Results({ @Result(column = "classid", property = "classid")})
@Select("select * from student")
public List<Student> findAllStudentAndClass();
(1)Results复用
@Results和@ResultMap不能同时给一个sql语句,@Results调用是在接口中声明的其他或自己声明的注解,而@ResultMap是从XML中调用的映射器。
(2)一对一映射
功能:一对一的关系映射;
说明:FetchType.lazy是延时加载,FetchType.EAGER是即时加载。
示例代码:
(3)一对多映射
功能:一对多的关系映射;
说明:FetchType.lazy是延时加载,FetchType.EAGER是即时加载。
示例代码:
(4)延时加载和即时加载
FetchType.LAZY(延时加载)
延时加载(Lazy Loading)意味着关联的数据在真正需要用到时才会被加载。这种方式在查询初期不会立即加载所有关联数据,而是在第一次访问这些数据时才进行加载。它有助于提升性能,特别是在关联数据较多且不是每次查询都需要用到时。
@Results({
@Result(property = "id", column = "id"),
@Result(property = "name", column = "name"),
@Result(property = "items", column = "id",
many = @Many(select = "selectItemsByOrderId", fetchType = FetchType.LAZY))
})
List<Order> selectOrders();
在上面的示例中,items属性性的加载策略被设置为FetchType.LAZY,即只有在访问items属性时,才会去加载关联的items数据。
FetchType.EAGER(即时加载)
即时加载(Eager Loading)意味着关联的数据在查询主对象时就会被立即加载。这种方式在查询初期就会加载所有关联数据,适合于每次查询都需要使用到关联数据的情况。
@Results({
@Result(property = "id", column = "id"),
@Result(property = "name", column = "name"),
@Result(property = "items", column = "id",
many = @Many(select = "selectItemsByOrderId", fetchType = FetchType.EAGER))
})
List<Order> selectOrders();
在上面的示例中,items属性的加载策略被设置为FetchType.EAGER,即在查询Order对象时会立即加载所有关联的items数据。
4、动态SQL注解
(1)脚本动态SQL
脚本sql:XML配置方式的动态SQL,是用<script>的方式把它照搬过来,用注解来实现。适用于xml 配置转换到注解配置。
方法中构建sql:@SelectProvider、@InsertProvider、@UpdateProvider、@DeleteProvider 这些方法的使用。
SQL语句构造器:实现动态 SQL 的内容。
(2)@SelectProvider 的用法
创建SQL语句类: 该类包含需要动态生成的 SQL 语句;
创建Mapper接口类:该类和配置文件的接口文件一 样,用来处理数据库操作;
测试验证:编写测试类,测试动态生成的 SQL 语句是否准确。
利用@SelectProvider:将 SQL 语句类和 Mapper 接口类关联,利用 @SelectProvider 的 type 属性和 method 属性;
(3)其他的动态SQL用法
(4)方法中构建动态sql
在接口中定义内部类,来构建需要的动态sql语句,比使用标签的方式结构更加清晰。
示例代码:
type传的值就是内部类的名称,method传的是内部类中的方法名,这样就可以调用方法中的SQL语句了。
(5)SQL语句构造器
因为在内部类的动态sql方法中,用if语句来写动态sql的话很不容易代码维护,所以就用一个语句构造器来代替if。
示例代码:
public String getGzqSelectStudentSql(Student s) {
return new SQL() {
{
// 字段名
SELECT("sid,sname");
SELECT("birthday");
SELECT("ssex,classid");
FROM("student");
if (s.getSsex() != null) {
WHERE("ssex=#{ssex}");
}
if (s.getClassid() != 0) {
WHERE("classid=#{classid}");
}
}
}.toString();
}
功能:解决 Java 代码中嵌入 SQL 语句,通过简单地创建一个实例来调用方法生成SQL语句。
特点:没有过多的使用类如 and 的连接词。