文档章节

MyBatis SQL注解 动态SQL语句

重城重楼
 重城重楼
发布于 2017/09/11 09:42
字数 1299
阅读 136
收藏 0

MyBatis提供了多个注解如:@InsertProvider,@UpdateProvider,@DeleteProvider和@SelectProvider,这些都是建立动态语言和让MyBatis执行这些语言。

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

PS:  mysql数据进行batch处理的时候,数据库链接一定要修改增加rewriteBatchedStatements=true

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的方法:

  1. 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);  
}  

==========================分割线================================

mybatis中enum类型数据注解的处理方式

一、使用参数构造器的方式来解决

@ConstructorArgs({
        @Arg(column="id",javaType=Integer.class),
        @Arg(column="name",javaType=String.class),
        @Arg(column="enum1",javaType= enum1.class,typeHandler=EnumOrdinalTypeHandler.class)
    })
    @Select(value="select id,name,enum1 from test1 where id=#{id}")
    Zhyonk queryTest(int id);

二、使用结果集映射注解来解决

 @Results({ @Result(property = "enum1", column = "enum1", typeHandler = EnumOrdinalTypeHandler.class) })
    @Select(value = "select id,name,enum1 from test1 where id=#{id}")
    Zhyonk queryTest2(int id);

三、采用@TypeDiscriminator类型鉴别器

@TypeDiscriminator(
            column = "enum1",javaType = enum1.class,typeHandler=EnumOrdinalTypeHandler.class,
            cases={
                    @Case(value="zhyonk",type=Zhyonk.class,results={@Result(property="enum1",column="enum1",typeHandler=EnumOrdinalTypeHandler.class)})
                    ,@Case(value="success",type=Success.class,results={@Result(property="enum1",column="enum1",typeHandler=EnumOrdinalTypeHandler.class)})
            })
    @Select(value="select id,name,enum1 from test1 where id=#{id}")
    Zhyonk queryTest3(int id);

摘自:mybatis -typeHandler 使用

本文转载自:http://blog.csdn.net/owen_william/article/details/51815506

共有 人打赏支持
重城重楼
粉丝 3
博文 46
码字总数 13174
作品 0
南京
程序员
私信 提问
基于注解的Mybatis mapper 接口注意事项

原文:http://my.oschina.net/doctor2014/blog/411580 基于注解的Mybatis mapper 接口功能没有mapper xml配置文件丰富,而且动态sql语句的灵活性不能和xml配置相比。 这里只说一下基于注解的...

Beaver_
2015/05/06
7.6K
2
springboot之简洁集成mybatis

orm框架的本质是简化编程中操作数据库的编码,发展到现在基本上就剩两家了,一个是宣称可以不用写一句SQL的hibernate,一个是可以灵活调试动态sql的mybatis,两者各有特点,在企业级系统开发中...

无语年华
2018/05/22
0
0
Java面试----2018年MyBatis常见实用面试题整理

Java面试----2018年MyBatis常见实用面试题整理 1、什么是MyBatis? 答:MyBatis是一个可以自定义SQL、存储过程和高级映射的持久层框架。 2、讲下MyBatis的缓存 答:MyBatis的缓存分为一级缓存...

优惠券活动
2018/04/29
0
0
Spring Boot干货系列:(九)数据存储篇-SQL关系型数据库之MyBatis的使用

     前言   上篇我们介绍了Spring Boot对传统JdbcTemplate的集成,这次换一下,介绍下Spring Boot中如何集成MyBatis。这里分别介绍注解方式以及XML方式的整合。喜欢哪种方式自己选择。...

后端编程嘟
2017/04/24
0
0
你还在用传统的 JDBC 持久化访问吗

原文出处:locality 前言 这里我会采用mybatis3.2做数据库的持久化,很多小伙伴或许还停留在老师的教导下,仍然停留在使用传统的JDBC持久化访问数据层。今天,我们来聊聊面向接口编程和怎么充...

locality
2017/12/17
0
2

没有更多内容

加载失败,请刷新页面

加载更多

XML

学习目标  能够说出XML的作用  能够编写XML文档声明  能够编写符合语法的XML  能够通过DTD约束编写XML文档  能够通过Schema约束编写XML文档  能够通过Dom4j解析XML文档 第1章 xm...

stars永恒
12分钟前
0
0
RabbitMQ学习(2)

1. 生产者客户端 void basicPublish(String exchange, String routingKey, boolean mandatory, boolean immediate, BasicProperties props, byte[] body) 1. 在生产者客户端发送消息时,首先......

江左煤郎
12分钟前
0
0
day23:curl判断网站状态码|打包压缩家目录小于5k文件|

1、写一个shell 脚本,通过curl -l 返回的状态码来判断访问的网站是否正确(状态码为 200 则正常); 首先如何过滤出来 状态码了; curl -I http://www.yuanhh.com/index.php 2>/dev/null|head...

芬野de博客
33分钟前
1
0
从 for of 聊到 Generator

你能学到什么 对 for of 更深入的理解 iterator 到底是何方神圣? 数组也是对象,为什么不能用 for of 来遍历对象呢? 如何实现对象的 for of? Generator 又是何方神圣? Generator 有什么用呢...

Jack088
45分钟前
3
0
怎么判断go-sql-driver 安装成功

.下载安装   执行下面两个命令:     下载:go get github.com/Go-SQL-Driver/MySQL     安装:go install github.com/Go-SQL-Driver/MySQL   怎么判断go-sql-driver 安装成功 ...

dragon_tech
54分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部