Dynamic SQL - Mybatis

Posted Erato Rabbit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dynamic SQL - Mybatis相关的知识,希望对你有一定的参考价值。

1 Static SQL/Ordinary Multi Conditons Query

1/ Declare method in interface EmpMapper

//Query according to id, lastName, age, sex. Query Employee by Multiple conditions
public List<Emp> getEmpListByMultiConditions(Emp emp);

2/ Configure SQL Statement in EmpMapper.xml

2 Tag If

1/ Declare method in interface EmpMapper

public List<Employee> getEmpsByConditionsIf(Employee employee);

2/ Configure SQL statement in EmpMapper.xml

    <select id="getByConditionIf" resultType="Employee">
        select * from tbl_employee
        where id = -1
        
            <if test="lastName!=null and lastName!=''">
                and last_name like #lastName
            </if>
            <if test="email!=null and email.trim()!=&quot;&quot;">
                and email = #email
            </if>
            <if test="gender==0 or gender==1">
                and gender = #gender
            </if>
    
    </select>

<test> is OGNL(Object-Graph Navigation Language) statement
OGNL - Apache Commons OGNL - Object Graph Navigation Library

If you meet special character, escape it.

" : "
& : &

@Test
public void testSelectIf() 

	Employee emp = new Employee();
	emp.setLastName("Zhang");
	List<Emp> emps = empDao.getByConditionIf(emp);
	
	emps.forEach(emp -> sout(stu + ","));

根据上面三个代码块,将其中的内容转为等价的 sql 语句如下:👇👇👇

select *
from student
where id=-1 or name="张起灵" or age=20

Tag where

使用标签,在有 query condition 时,mybatis 会自动添加上 where 子句;没有 query condition 时,不会添加 where 子句.

需要注意的是,第一个标签中的SQL 片断,and 写不写都行。如果写上了 and ,tag where 会将离它最近的 and 或者 or 删掉。

但其它中 SQL 片断的 and,必须写上。否则 SQL 语句将拼接出错。

Reference

MyBatis(五)动态SQL 之 if 与 where 标签 - 格物致知_Tony - 博客园 (cnblogs.com)

IDEA+SpringBoot MyBatis Dynamic SQL的初体验(二)

在上节IDEA+SpringBoot MyBatis Dynamic SQL的初体验(一)中,讲解了Mybatis Dynamic SQL数据库生成https://www.cnblogs.com/hjm0928/p/9955228.html

现在那看一下怎么使用

先看一下项目结构

可以看到实体类,Mapper文件和DynamicSqlSupport文件都生成成功了

第一步 修改application.properties修改为application.yml  内容如下

spring:
    datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/nice_test?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=UTC
        username: pigge
        password: 123456
    http:
        encoding:
            force: true
mybatis:
    mapper-locations: com.pigge.mybatistest.mapper
server:
    tomcat:
        uri-encoding: UTF-8
    port: 8080
logging:
    level:
        # 打开日志输出
        com.pigge.mybatistest: DEBUG
    path: logs\\spring
debug: true

在创建UserService类

package com.pigge.mybatistest.service;

import com.pigge.mybatistest.entity.User;
import com.pigge.mybatistest.util.Page;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
* @author hjm0928
*/
public interface UserService {
/**
* 根据用户名查询表内数据
* @param username 用户名
* @return 数据列表
*/
User selectByUsername(@Param("username")String username);

/**
* 分页查找数据
* @param page 分页工具类
* @return 记录集
*/
List<User> selectAll(Page page);
}

UserServiceImpl类

package com.pigge.mybatistest.service.impl;

import com.pigge.mybatistest.entity.User;
import com.pigge.mybatistest.mapper.UserDynamicSqlSupport;
import com.pigge.mybatistest.mapper.UserMapper;
import com.pigge.mybatistest.service.UserService;
import com.pigge.mybatistest.util.Page;
import com.sun.org.apache.bcel.internal.generic.InstructionComparator;
import com.sun.org.apache.bcel.internal.generic.Select;
import org.mybatis.dynamic.sql.render.RenderingStrategy;
import org.mybatis.dynamic.sql.where.condition.IsEqualTo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

import static org.mybatis.dynamic.sql.select.SelectDSL.select;


/**
 * @author hjm0928
 */
@Service
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;

    @Autowired
    public UserServiceImpl(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Override
    public User selectByUsername(String username) {
        InstructionComparator select = Select.getComparator();
        //SQL语句为 select username, password, tel from user where username = ?; 参数username
        User user = userMapper.selectOne(
                select(
                        UserDynamicSqlSupport.username,
                        UserDynamicSqlSupport.password,
                        UserDynamicSqlSupport.tel
                ).from(UserDynamicSqlSupport.user)
                .where(UserDynamicSqlSupport.username, IsEqualTo.of(()->username))
                .build()
                .render(RenderingStrategy.MYBATIS3)
        );
        //SQL语句 select username....(所有字段) from user where username = ?; 参数username
        user = userMapper.selectByExample()
                .where(UserDynamicSqlSupport.username, IsEqualTo.of(()->username))
                .build()
                .execute()
                .get(0);
        return user;
    }

    @Override
    public List<User> selectAll(Page page) {
        //下一节实现 因为Mybatis Dynamic Sql没有默认的分页支持, 只能自定义
        return null;
    }
}

UserController类

package com.pigge.mybatistest.controller;

import com.fasterxml.jackson.databind.util.JSONPObject;
import com.pigge.mybatistest.entity.User;
import com.pigge.mybatistest.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author hjm0928
 */
@Controller
public class UserController {

    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @RequestMapping("/get")
    @ResponseBody
    private User get(String username){
        return userService.selectByUsername(username);
    }
}

此时项目结构为

运行MyBatisTestApplication类, 在浏览器中输入http://localhost:8080/get?username=youUsername 其页面结果为

后台日志输出为

ok  测试成功

 

以上是关于Dynamic SQL - Mybatis的主要内容,如果未能解决你的问题,请参考以下文章

如何在xml文件中申明dynamic元素类型

IDEA+SpringBoot MyBatis Dynamic SQL的初体验(二)

帮助使用Dynamic PL/SQL,函数抛出异常

Oracle Native Dynamic SQL PL/SQL 语句没有开始和结束

真正的Mybatis动态sql —MyBatis Dynamic SQL

Mysql Programming CS 155P笔记 Dynamic SQL