Mybatis3.0注解动态SQL的demo案例(@SelectProvider、@InsertProvider、@UpdateProvider)

大家在写测试小工具平台(java+springboot+mybatis前后台小系统)之时,会苦于mybatis一个一个摆上所需表字段和实体类成员变量的映射关系。正如mybatis官网资料文档所说:“理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。”(https://mybatis.org/mybatis-3/zh/dynamic-sql.html

就像这样(如下图),密密麻麻,我就问你害不害怕,密集恐惧症的测试开发er估计会崩溃~~~所以要用动态SQL摆脱痛苦!!!

通过注解实现动态sql一共需要四个步骤:1.创建表,2.创建entity类,3.创建mapper类, 4.创建动态sql的Provider类。

1、创建PersonMapper.java(接口):【一般写在dao层】

如下代码, @XXXProvider(type=提供动态SQL的类名.class, method="提供动态SQL的类里面的方法名")  ,

@XXXProvider,就是今天我们所讲的@SelectProvider、@InsertProvider、@UpdateProvider注解关键字。

package com.blueStarWei.mappers;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider;

import com.blueStarWei.entity.TPersonInfo;

public interface PersonMapper {
    
    @SelectProvider(type=PersonDynamicSqlProvider.class, method="select")  //说白了,其实@xxxProvider通过写在dao层的type=PersonDynamicSqlProvider.java这个类中的select方法,生成动态SQL
    List<TPersonInfo> findByNameAndAge(Map<String,Object> map);   //这个传入参数map,其实是通过写在service层传入参数的personMapper.findByNameAndAge(map)传进来的(1、同样也是Map键值类型;2、personMapper是通过@Autowired注解给PersonMapper接口注入进来的)
    
    @InsertProvider(type=PersonDynamicSqlProvider.class, method="insert")
    void insert(TPersonInfo person);
    
    @UpdateProvider(type=PersonDynamicSqlProvider.class, method="update")
    void update(TPersonInfo person);
    
}

2、创建类PersonDynamicSqlProvider.java【一般也写在dao层】

package com.blueStarWei.mappers;

import java.util.Map;

import org.apache.ibatis.jdbc.SQL;

import com.blueStarWei.entity.TPersonInfo;

public class PersonDynamicSqlProvider {

    public String insert(TPersonInfo person){
        return new SQL(){
            {
                INSERT_INTO("T_PERSON_INFO");
                if(person.getName() != null){
                    VALUES("name", "#{name}");                    
                    //VALUES("name", person.getName());
                    //Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'Java' in 'field list'
                }
                if(person.getAge() != null){
                    VALUES("age", "#{age}");
                }
            }
        }.toString();
    }

    //自测打印结果将会是:(如果person.setName("王刚")和person.setAge(22)都分别赋值了“王刚”和22,都不为空):
    /*
    
        INSERT INTO T_PERSON_INFO VALUES(#{name}, #{age})
        
    */

    
    public String update(TPersonInfo person){
        return new SQL(){
            {
                UPDATE("T_PERSON_INFO");
                if(person.getName() != null){
                    SET("name=#{name}");
                }
                if(person.getAge() != null){
                    SET("age=#{age}");
                }
                if(persion.getId() != null){
                    WHERE("id=#{id}");
                }
            }
        }.toString();
    }

    //自测打印结果将会是:(如果person.setName("王刚")和person.setAge(22)都分别赋值了“王刚”和22,person.setId("12345678"),都不为空):
    /*
    
        UPDATE T_PERSON_INFO SET name = #{name}
        WHERE (id = #{id}) 
        
    */

    
    public String select(Map map){
        return new SQL(){
            {
                SELECT("*");
                FROM("T_PERSON_INFO");
                
                if(param.get("id")!=null) {
                    WHERE("id=#{id}");
                }
            }          
        }.toString();
    }



//如果这里我只测试一下select方法,在主方法中如下操作:

public static void main(String[] args) {

        PersonDynamicSqlProvider test = new PersonDynamicSqlProvider();
        Map map =new HashMap();
        map.put("id","12345678");
        
        System.out.println(test.select(map));

    }
/*运行结果:

    SELECT * FROM T_PERSON_INFO
    WHERE ( id = #{id} )


*/



}


3、以上main方法是供自己测试动态SQL写的正确与否 而用的,但是外层(也就是调用方)怎么用呢?【一般写在service层,写好了供以后的controller层调用】

看见第1点的接口PersonMapper了吗?将通过spring框架中的注解关键字(@Autowired)注入接口(附加说明:@Autowired所在spring包:org.springframework.beans.factory.annotation.Autowired)

package com.xxx.service;   //一般写在service层

import org.springframework.beans.factory.annotation.Autowired;

@Autowired
PersonMapper personMapper;

List<TPersonInfo> list = personMapper.findByNameAndAge(map);   
personMapper.insert(tPersonInfo);   
personMapper.update(tPersonInfo);

剩下的就不多说了,上面的map、tPersonInfo这两个传入的参数,根据自己测试或业务上的需要去传值,就OK了!

综上所述,第3点是传实际的值,进入到第1点接口的两个方法中,然后通过@XXXProvider(type=提供动态SQL的类名.class, method="提供动态SQL的类里面的方法名")  ,根据传的这批字段,有哪些不为空的,根据不为空的字段生成mybatis SQL语句,然后将值代入SQL中执行(和传统mybatis一样),这就是动态SQL执行全流程!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值