MyBatis注解应用之动态SQL语句

有时候,我们需要在输入的标准下,创建动态的查的语言。MyBatis提供了多个注解如:@InsertProvider,@UpdateProvider,@DeleteProvider和@SelectProvider,这些都是建立动态语言和让MyBatis执行这些语言。

现在让我们来看一下如何使用@ SelectProvider来创建简单的SELECT映射的例子。创建一个TutorDynaSqlProvider.java类,带有findTutorByIdSql()的方法。

package com.owen.mybatis.sqlproviders;
import org.apache.ibatis.jdbc.SQL;
public class TutorDynaSqlProvider
{
public String findTutorByIdSql(int tutorId)
{
return "SELECT TUTOR_ID AS tutorId, NAME, EMAIL FROM TUTORS
WHERE TUTOR_ID="+tutorId;
} }

创建接口类TutorMapper.java.

@SelectProvider(type=TutorDynaSqlProvider.class,
method="findTutorByIdSql")
Tutor findTutorById(int tutorId);

这里我们声明了@ SelectProvider去声明类和方法名,这个将会在SQL声明中执行。但是会用String来构造查询语句时,是困难的,也是容易出错了。所以MyBatis提供了SQL公用方法构造方法,不需要写出完整的String语句。让我们来看一下如何使用org.apache.ibatis.jdbc.SQL的公用方法。

package com.owen.mybatis.sqlproviders;
import org.apache.ibatis.jdbc.SQL;
public class TutorDynaSqlProvider
{
public String findTutorByIdSql(final int tutorId)
{
return new SQL() {{
SELECT("tutor_id as tutorId, name, email");
FROM("tutors");
WHERE("tutor_id="+tutorId);
}}.toString();
} }

在SQL公用的函数中,我们需要构造适当的前缀和需要 的后缀。动态语句的SQL方法可以包含下面的任一参数:

1)        没有参数

2)        与同类型的接口方法的参数一样

3)        java.util.Map

如果SQL的查询不能够提供所依赖的参数,你可以使用无参的SQL方法。

public String findTutorByIdSql()
{
return new SQL() {{
SELECT("tutor_id as tutorId, name, email");
FROM("tutors");
WHERE("tutor_id = #{tutorId}");
}}.toString();
}

这里我们并没有在我们的方法中定义参数,所以是一个无参的方法。

如果一个映射的接口方法只有一个参数,我们可以如下定义SQL的方法:

Tutor findTutorById(int tutorId);

这里的findTutorById(int)的方法拥有一个输入的参数是int的类型。我们可以把findTutorBySql(int)方法作为SQL提供的方法。

public String findTutorByIdSql(final int tutorId)
{
return new SQL() {{
SELECT("tutor_id as tutorId, name, email");
FROM("tutors");
WHERE("tutor_id="+tutorId);
}}.toString();
}

如果Mapper的接口拥有多个参数,我们可以运用java.util.Map的参数类型作为SQL方法提供。所以所有输入的参数都必须是map的类型,并且带有param1、param2等作为key的值,而输入的参数是value的值。你也可以输入的参数为0,1,2,3等作为key值。

@SelectProvider(type=TutorDynaSqlProvider.class,
method="findTutorByNameAndEmailSql")
Tutor findTutorByNameAndEmail(String name, String email);
public String findTutorByNameAndEmailSql(Map<String, Object> map)
{
String name = (String) map.get("param1");
String email = (String) map.get("param2");
//you can also get those values using 0,1 keys
//String name = (String) map.get("0");
//String email = (String) map.get("1");
return new SQL() {{
SELECT("tutor_id as tutorId, name, email");
FROM("tutors");
WHERE("name=#{name} AND email=#{email}");
}}.toString();
}

SQL公用的方法也提供了多样的方法,如JOINS,ORDER_BY,GROUP_BY等。让我们来看一下使用LEFT_OUTER_JOIN的例子:

public class TutorDynaSqlProvider
{
public String selectTutorById()
{
return new SQL() {{
SELECT("t.tutor_id, t.name as tutor_name, email");
SELECT("a.addr_id, street, city, state, zip, country");
SELECT("course_id, c.name as course_name, description,
start_date, end_date");
FROM("TUTORS t");
LEFT_OUTER_JOIN("addresses a on t.addr_id=a.addr_id");
LEFT_OUTER_JOIN("courses c on t.tutor_id=c.tutor_id");
WHERE("t.TUTOR_ID = #{id}");
}}.toString();
} }
public interface TutorMapper
{
@SelectProvider(type=TutorDynaSqlProvider.class,
method="selectTutorById")
@ResultMap("com.owen.mybatis.mappers.TutorMapper.TutorResult")
Tutor selectTutorById(int tutorId);
}

这里并没有使用一对多的注解,我们可以基于XML来配置<resultMap>和映射@ResultMap.

<mapper namespace="com.owen.mybatis.mappers.TutorMapper">
<resultMap type="Address" id="AddressResult">
<id property="id" column="addr_id"/>
<result property="street" column="street"/>
<result property="city" column="city"/>
<result property="state" column="state"/>
<result property="zip" column="zip"/>
<result property="country" column="country"/>
</resultMap>
<resultMap type="Course" id="CourseResult">
<id column="course_id" property="id"/>
<result column="course_name" property="name"/>
<result column="description" property="description"/>
<result column="start_date" property="startDate"/>
<result column="end_date" property="endDate"/>
</resultMap>
<resultMap type="Tutor" id="TutorResult">
<id column="tutor_id" property="id"/>
<result column="tutor_name" property="name"/>
<result column="email" property="email"/>
<association property="address" resultMap="AddressResult"/>
<collection property="courses"
resultMap="CourseResult"></collection>
</resultMap>
</mapper>

使用这个动态的SQL语句,将会查找到教师的信息连带着教师的地址和教授的课程信息。

1. @InserProvider

我们可以创建动态的INSERT查询,使用@Insertprovider.

public class TutorDynaSqlProvider
{
public String insertTutor(final Tutor tutor)
{
return new SQL() {{
INSERT_INTO("TUTORS");
if (tutor.getName() != null) {
VALUES("NAME", "#{name}");
}
if (tutor.getEmail() != null) {
VALUES("EMAIL", "#{email}");
}
}}.toString();
} }
public interface TutorMapper
{
@InsertProvider(type=TutorDynaSqlProvider.class,
method="insertTutor")
@Options(useGeneratedKeys=true, keyProperty="tutorId")
int insertTutor(Tutor tutor);
}

2. @UpdateProvider

     我们可以创建动态的UPDATE语句使用@UpdateProvider。

public class TutorDynaSqlProvider
{
public String updateTutor(final Tutor tutor)
{
return new SQL() {{
UPDATE("TUTORS");
if (tutor.getName() != null) {
SET("NAME = #{name}");
}
if (tutor.getEmail() != null) {
SET("EMAIL = #{email}");
}
WHERE("TUTOR_ID = #{tutorId}");
}}.toString();
} }
public interface TutorMapper
{
@UpdateProvider(type=TutorDynaSqlProvider.class,
method="updateTutor")
int updateTutor(Tutor tutor);
}

3. @DeleteProvider

我们可以创建DELETEf动态语句,使用@DeleProvider

public class TutorDynaSqlProvider
{
public String deleteTutor(int tutorId)
{
return new SQL() {{
DELETE_FROM("TUTORS");
WHERE("TUTOR_ID = #{tutorId}");
}}.toString();
}
}
public interface TutorMapper
{
@DeleteProvider(type=TutorDynaSqlProvider.class,
method="deleteTutor")
int deleteTutor(int tutorId);
}

4.总结

在前面的几个章节中,笔者主要向大家介绍是如何使用注解的方法来处理MyBatis的映射。所以这些知道其实是建立地XML的基础上的,只你理解了XML的使用,我们注解的使用不没的多大问题的。好的,到现在为止,MyBatis的基础用法基本上都已经介绍好的,下一章节,我们将会学习如何将MyBatis与Spring联合使用。源码下载:https://github.com/owenwilliam/mybatis.com.git


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苦茶子12138

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值