mysql.mybatis动态sql_Mybatis的动态SQL

1 简介

动态SQL是Mybatis强大特性之一。极大的简化我们拼装SQL的操作。

动态SQL元素和使用JSTL或其他类似基于XML的文本处理器相似。

Mybatis采用功能强大的基于OGNL的表达式来简化操作。

if

choose(when、otherwise)

trim(where、set)

foreach

2 环境搭建

导入相关jar包的Maven坐标:

org.mybatis

mybatis

3.4.1

log4j

log4j

1.2.17

mysql

mysql-connector-java

8.0.21

junit

junit

4.13

test

sql脚本

DROP TABLE IF EXISTS `employee`;

CREATE TABLE `employee` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`last_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

`gender` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

`email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

PRIMARY KEY (`id`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

db.propreties

jdbc.url=jdbc:mysql://192.168.134.100:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true

jdbc.driverClass=com.mysql.cj.jdbc.Driver

jdbc.username=root

jdbc.password=123456

log4j.xml

Employee.java

package com.sunxiaping.domain;

import org.apache.ibatis.type.Alias;

@Alias("emp")

public class Employee {

private Integer id;

private String lastName;

private String email;

private String gender;

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public String getLastName() {

return lastName;

}

public void setLastName(String lastName) {

this.lastName = lastName;

}

public String getEmail() {

return email;

}

public void setEmail(String email) {

this.email = email;

}

public String getGender() {

return gender;

}

public void setGender(String gender) {

this.gender = gender;

}

@Override

public String toString() {

return "Employee{" +

"id=" + id +

", lastName='" + lastName + '\'' +

", email='" + email + '\'' +

", gender='" + gender + '\'' +

'}';

}

}

EmployeeMapper.java

package com.sunxiaping.mapper;

public interface EmployeeMapper {

}

EmployeeMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

mybatis-config.xml

/p>

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-config.dtd">

3 if判断

示例:

EmployeeMapper.java

package com.sunxiaping.mapper;

import com.sunxiaping.domain.Employee;

import java.util.List;

public interface EmployeeMapper {

List getEmpsByConditionIf(Employee employee);

}

EmployeeMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

SELECT id as id,last_name as lastName,gender as gender,email as email

FROM employee

WHERE 1 = 1

AND id = #{id,jdbcType=INTEGER}

AND last_name LIKE #{lastName,jdbcType=VARCHAR}

AND gender = #{gender,jdbcType=VARCHAR}

AND email = #{email,jdbcType=VARCHAR}

测试:

package com.sunxiaping;

import com.sunxiaping.domain.Employee;

import com.sunxiaping.mapper.EmployeeMapper;

import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

import java.io.IOException;

import java.io.InputStream;

import java.util.List;

public class EmployeeTest {

SqlSessionFactory sqlSessionFactory = null;

SqlSession sqlSession = null;

EmployeeMapper employeeMapper = null;

@Before

public void before() throws IOException {

String resource = "mybatis-config.xml";

InputStream inputStream = Resources.getResourceAsStream(resource);

sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

sqlSession = sqlSessionFactory.openSession(true);

employeeMapper = sqlSession.getMapper(EmployeeMapper.class);

}

@After

public void after() {

if (null != sqlSession) {

sqlSession.close();

}

}

@Test

public void testFindById() {

Employee example = new Employee();

example.setId(1);

example.setGender("男");

List employeeList = employeeMapper.getEmpsByConditionIf(example);

System.out.println("employeeList = " + employeeList);

}

}

4 where查询条件

如果查询条件中有多个AND或OR语句,Mybatis推荐使用where标签,其内部会自动将多余的AND或OR去掉。当然,where标签强制类似AND xxx=xxx,AND xxx=xxx的方式。

示例:

EmployeeMapper.java

package com.sunxiaping.mapper;

import com.sunxiaping.domain.Employee;

import java.util.List;

public interface EmployeeMapper {

List getEmpsByConditionWhere(Employee employee);

}

EmployeeMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

SELECT id as id,last_name as lastName,gender as gender,email as email

FROM employee

id = #{id,jdbcType=INTEGER}

AND last_name LIKE #{lastName,jdbcType=VARCHAR}

AND gender = #{gender,jdbcType=VARCHAR}

AND email = #{email,jdbcType=VARCHAR}

测试:

package com.sunxiaping;

import com.sunxiaping.domain.Employee;

import com.sunxiaping.mapper.EmployeeMapper;

import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

import java.io.IOException;

import java.io.InputStream;

import java.util.List;

public class EmployeeTest {

SqlSessionFactory sqlSessionFactory = null;

SqlSession sqlSession = null;

EmployeeMapper employeeMapper = null;

@Before

public void before() throws IOException {

String resource = "mybatis-config.xml";

InputStream inputStream = Resources.getResourceAsStream(resource);

sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

sqlSession = sqlSessionFactory.openSession(true);

employeeMapper = sqlSession.getMapper(EmployeeMapper.class);

}

@After

public void after() {

if (null != sqlSession) {

sqlSession.close();

}

}

@Test

public void testFindById() {

Employee example = new Employee();

example.setGender("男");

List employeeList = employeeMapper.getEmpsByConditionWhere(example);

System.out.println("employeeList = " + employeeList);

}

}

5 trim自定义字符串截取

上面的where标签有限制,一旦使用了类似xxx=xxx AND,xxx=xxx AND的情况,where标签就失效了,这个时候可以使用trim自定义字符串截取,当前,trim标签也可以模拟出where标签的效果。

示例:

EmployeeMapper.java

package com.sunxiaping.mapper;

import com.sunxiaping.domain.Employee;

import java.util.List;

public interface EmployeeMapper {

List getEmpsByConditionTrim(Employee employee);

}

EmployeeMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

SELECT id as id,last_name as lastName,gender as gender,email as email

FROM employee

id = #{id,jdbcType=INTEGER} AND

last_name LIKE #{lastName,jdbcType=VARCHAR} AND

gender = #{gender,jdbcType=VARCHAR} AND

email = #{email,jdbcType=VARCHAR}

测试:

package com.sunxiaping;

import com.sunxiaping.domain.Employee;

import com.sunxiaping.mapper.EmployeeMapper;

import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

import java.io.IOException;

import java.io.InputStream;

import java.util.List;

public class EmployeeTest {

SqlSessionFactory sqlSessionFactory = null;

SqlSession sqlSession = null;

EmployeeMapper employeeMapper = null;

@Before

public void before() throws IOException {

String resource = "mybatis-config.xml";

InputStream inputStream = Resources.getResourceAsStream(resource);

sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

sqlSession = sqlSessionFactory.openSession(true);

employeeMapper = sqlSession.getMapper(EmployeeMapper.class);

}

@After

public void after() {

if (null != sqlSession) {

sqlSession.close();

}

}

@Test

public void testFindById() {

Employee example = new Employee();

example.setGender("男");

List employeeList = employeeMapper.getEmpsByConditionTrim(example);

System.out.println("employeeList = " + employeeList);

}

}

6 choose分支选择

有点类似Java中的switch-case语句。

示例:如果查询条件中有id,就用id查询;如果查询条件中有lastName,就用lastName查询;如果查询条件中有gender,就用gener查询;否则,用emial查询。

EmployeeMapper.java

package com.sunxiaping.mapper;

import com.sunxiaping.domain.Employee;

import java.util.List;

public interface EmployeeMapper {

List getEmpsByConditionChoose(Employee employee);

}

EmployeeMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

SELECT id as id,last_name as lastName,gender as gender,email as email

FROM employee

id = #{id,jdbcType=INTEGER}

last_name = #{lastName,jdbcType=VARCHAR}

gender = #{gender,jdbcType=VARCHAR}

email = #{email,jdbcType=VARCHAR}

7 set更新

set标签一般结合if标签实现动态更新。Mybatis中的set标签会自动将最右边多出的“,”去掉。

示例:

EmployeeMapper.java

package com.sunxiaping.mapper;

import com.sunxiaping.domain.Employee;

public interface EmployeeMapper {

void updateEmployee(Employee employee);

}

EmployeeMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

UPDATE employee

last_name = #{lastName,jdbcType=VARCHAR},

gender = #{gender,jdbcType=VARCHAR},

email = #{email,jdbcType=VARCHAR}

id = #{id,jdbcType=INTEGER}

8 foreach遍历

foreach标签类似于jstl中的标签,都是迭代一个集合中的对象。

示例:

EmployeeMapper.java

package com.sunxiaping.mapper;

import com.sunxiaping.domain.Employee;

import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface EmployeeMapper {

List findEmpsByConditionForeach(@Param("ids") List ids);

}

EmployeeMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

SELECT id as id,last_name as lastName,gender as gender,email as email

FROM employee

#{id,jdbcType=INTEGER}

9 MySQL下的foreach批量插入的两种方式

第一种批量插入数据的SQL方式如下:

INSERT INTO 表名(字段1,字段2,...) VALUES (值1,值2,...),(值1,值2,...);

示例:

EmployeeMapper.java

package com.sunxiaping.mapper;

import com.sunxiaping.domain.Employee;

import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface EmployeeMapper {

void batchInsertEmps(@Param("emps") List employees);

}

EmployeeMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

(#{emp.lastName,jdbcType=VARCHAR},#{emp.gender,jdbcType=VARCHAR},#{emp.email,jdbcType=VARCHAR})

第二种批量插入数据的SQL方式如下:

INSERT INTO 表名(字段1,字段2,...) VALUES (值1,值2,...);

INSERT INTO 表名(字段1,字段2,...) VALUES (值1,值2,...);

但是,在JDBC操纵MySQL的时候,需要在jdbc.url上加上“allowMultiQueries=true”参数,当然这个参数也可以用于批量删除、批量更新。

示例:

db.properties

jdbc.url=jdbc:mysql://192.168.134.100:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true&allowMultiQueries=true

jdbc.driverClass=com.mysql.cj.jdbc.Driver

jdbc.username=root

jdbc.password=123456

EmployeeMapper.java

package com.sunxiaping.mapper;

import com.sunxiaping.domain.Employee;

import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface EmployeeMapper {

void batchInsertEmps(@Param("emps") List employees);

}

EmployeeMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

INSERT INTO employee (last_name,gender,email) VALUES (#{emp.lastName,jdbcType=VARCHAR},#{emp.gender,jdbcType=VARCHAR},#{emp.email,jdbcType=VARCHAR})

10 Oracle下的foreach批量插入的两种方式

第一种批量插入数据的SQL方式如下:

begin

INSERT INTO 表名(字段1,字段2,...) VALUES (值1,值2,...);

INSERT INTO 表名(字段1,字段2,...) VALUES (值1,值2,...);

end;

示例:

EmployeeMapper.java

package com.sunxiaping.mapper;

import com.sunxiaping.domain.Employee;

import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface EmployeeMapper {

void batchInsertEmps(@Param("emps") List employees);

}

EmployeeMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

INSERT INTO employee (id,last_name,gender,email) VALUES (#{employee_seq.nextval},#{emp.lastName,jdbcType=VARCHAR},#{emp.gender,jdbcType=VARCHAR},#{emp.email,jdbcType=VARCHAR});

第二种批量插入数据的SQL方式如下:

INSERT INTO 表名(字段1,字段2,...)

SELECT 别名1,别名2,... FROM (

SELECT 值1 别名1,值2 别名2,... FROM dual

UNION

SELECT 值1 别名1,值2 别名2<?xml version="1.0" encoding="UTF-8" ?>

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

SELECT #{emp.lastName,jdbcType=VARCHAR} lastName,#{emp.gender,jdbcType=VARCHAR} gender,#{emp.email,jdbcType=VARCHAR} email FROM dual

,... FROM dual

)

示例:

EmployeeMapper.java

package com.sunxiaping.mapper;

import com.sunxiaping.domain.Employee;

import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface EmployeeMapper {

void batchInsertEmps(@Param("emps") List employees);

}

EmployeeMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

SELECT #{emp.lastName,jdbcType=VARCHAR} lastName,#{emp.gender,jdbcType=VARCHAR} gender,#{emp.email,jdbcType=VARCHAR} email FROM dual

11 内置参数

Mybatis不只是方法传递过来的参数可以用来判断,取值…,Mybatis默认还有两个默认的参数:_parameter和_databaseId。

_parameter:代表整个参数。

如果是单个参数:_parameter就是这个参数。

如果是多个参数:参数会封装到一个Map中,_parameter就是代表这个Map。

_databaseId:如果在全局配置文件中配置了databaseIdProvider标签,那么_databaseId就是代表当前数据库的别名。

示例:

mybatis-config.xml

/p>

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-config.dtd">

EmployeeMapper.java

package com.sunxiaping.mapper;

import com.sunxiaping.domain.Employee;

import java.util.List;

public interface EmployeeMapper {

List findByBuiltParameter();

}

EmployeeMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

SELECT id as id,last_name as lastName,email as email ,gender as gender

FROM employee

LIMIT 0,5

SELECT * FROM

(SELECT e.*,rownum as r1 FROM employee e WHERE rownum < 5)

WHERE r1 > 1

12 bind绑定

bind标签可以从OGNL表达式中创建一个变量并将其绑定到上下文。

示例:

EmployeeMapper.java

package com.sunxiaping.mapper;

import com.sunxiaping.domain.Employee;

import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface EmployeeMapper {

List findByLastNameLike(@Param("lastName") String lastName);

}

EmployeeMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

SELECT id as id,last_name as lastName,email as email ,gender as gender

FROM employee

WHERE last_name like #{_lastName,jdbcType=VARCHAR}

测试:

package com.sunxiaping;

import com.sunxiaping.domain.Employee;

import com.sunxiaping.mapper.EmployeeMapper;

import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

import java.io.IOException;

import java.io.InputStream;

import java.util.List;

public class EmployeeTest {

SqlSessionFactory sqlSessionFactory = null;

SqlSession sqlSession = null;

EmployeeMapper employeeMapper = null;

@Before

public void before() throws IOException {

String resource = "mybatis-config.xml";

InputStream inputStream = Resources.getResourceAsStream(resource);

sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

sqlSession = sqlSessionFactory.openSession(true);

employeeMapper = sqlSession.getMapper(EmployeeMapper.class);

}

@After

public void after() {

if (null != sqlSession) {

sqlSession.close();

}

}

@Test

public void testFindById() {

List employeeList = employeeMapper.findByLastNameLike("a");

System.out.println("employeeList = " + employeeList);

}

}

13 抽取可重用的SQL片段

sql标签可以抽取可重用的SQL片段,方便后面引用。

示例:

EmployeeMapper.java

package com.sunxiaping.mapper;

import com.sunxiaping.domain.Employee;

import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface EmployeeMapper {

List findByLastNameLike(@Param("lastName") String lastName);

}

EmployeeMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

id as id,last_name as lastName,email as email ,gender as gender

SELECT

FROM employee

WHERE last_name like #{_lastName,jdbcType=VARCHAR}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值