mybatis的动态SQL和模糊查询实例详解

作者:Alan_Xiang 时间:2022-03-10 09:47:03 

现在以一个例子来介绍mybatis的动态SQL和模糊查询:通过多条件查询用户记录,条件为姓名模糊匹配,并且年龄在某两个值之间。

新建表d_user:


create table d_user(
id int primary key auto_increment,
name varchar(10),
age int(3)
);

insert into d_user(name,age) values('Tom',12);
insert into d_user(name,age) values('Bob',13);
insert into d_user(name,age) values('Jack',18);

建表成功:

mybatis的动态SQL和模糊查询实例详解

新建实体类User:


public class User {
private Integer id;
private String name;
private Integer age;

//getters and setters

@Override
public String toString() {
 return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
}

public User(Integer id, String name, Integer age) {
 super();
 this.id = id;
 this.name = name;
 this.age = age;
}

public User() {
 super();
}
}

创建查询条件实体类ConditionUser:


public class ConditionUser {
private String name;
private int minAge;
private int maxAge;

//getters and setters

public ConditionUser(String name, int minAge, int maxAge) {
 super();
 this.name = name;
 this.minAge = minAge;
 this.maxAge = maxAge;
}

public ConditionUser() {
 super();
}
}

新建映射文件userMapper.xml:


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.test7.userMapper">
<select id="getUser" parameterType="ConditionUser" resultType="User">
 SELECT * FROM d_user WHERE age &gt;= #{minAge} AND age &lt;= #{maxAge}
 <if test="name!=null">
  AND name LIKE CONCAT(CONCAT('%',#{name}),'%')</if>
</select>
</mapper>

编写测试类:


public class Test {

private SqlSessionFactory sessionFactory;
private SqlSession session;

@Before
public void init(){
 //读取配置文件
 String resource = "conf.xml";
 InputStream is = this.getClass().getClassLoader().getResourceAsStream(resource);

//创建SqlSessionFactory和SqlSession
 sessionFactory = new SqlSessionFactoryBuilder().build(is);
 session = sessionFactory.openSession();
}

@After
public void free(){
 session.commit();
 session.close();
}

@org.junit.Test
public void getUser() {
 String statement = "com.mybatis.test7.userMapper"+".getUser";
 ConditionUser conditionUser = new ConditionUser("o", 13, 18);
 List<User> list = session.selectList(statement, conditionUser);
 System.out.println(list);
}
}

运行结果:

mybatis的动态SQL和模糊查询实例详解

注意:

1. 在配置文件中编写sql语句时,为防止大于号和小于号在表示大小关系和表示标签符号之间产生混淆,所以通常用&gt;和&lt;来代替sql语句中大于号和小于号。

2. 在SQL语句中添加动态SQL标签if的原因是,当在后台获取的name属性值为null时,防止生成where name like %null%的条件判断语句,正确的逻辑应该是,当传来的name属性值为null时,取消此筛选条件,即不使用where name like ?的判断条件。在mybatis中,可用的动态SQL标签有:if,choose(when,otherwise),trim(where,set),foreach。

3. 在使用模糊查询时,拼接%+#{name}+%的方法有如下几种:

(1).像上述例子中一样,在SQL语句中使用CONCAT关键字。

(2).使用${}代替#{}:


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.test7.userMapper">
<select id="getUser" parameterType="ConditionUser" resultType="User">
 SELECT * FROM d_user WHERE age &gt;= #{minAge} AND age &lt;= #{maxAge}
 <if test="name!=null">
  AND name LIKE '%${name}%'</if>
</select>
</mapper>

注意,默认情况下,使用#{}语法,MyBatis会产生PreparedStatement语句,并且安全地设置PreparedStatement参数,这个过程中MyBatis会进行必要的安全检查和转义。例如:

执行SQL:select * from emp where name = #{employeeName}

参数:employeeName=>Smith

解析后执行的SQL:select * from emp where name = ?

执行SQL:Select * from emp where name = ${employeeName}

参数:employeeName传入值为:Smith

解析后执行的SQL:Select * from emp where name =Smith

综上所述,${}方式可能会引发SQL注入的问题,同时也会影响SQL语句的预编译,所以从安全性和性能的角度出发,应尽量使用#{}。当需要直接插入一个不做任何修改的字符串到SQL语句中,例如在ORDER BY后接一个不添加引号的值作为列名,这时候就需要使用${}。

(3).在程序中拼接。

来源:https://blog.csdn.net/xiangwanpeng/article/details/53790810

标签:mybatis,动态SQL,模糊查询
0
投稿

猜你喜欢

  • 教你怎么使用Java实现WebSocket

    2022-10-31 04:08:50
  • 剖析Java中线程编程的概念

    2022-02-02 04:12:51
  • Spring中自定义数据类型转换的方法详解

    2022-10-09 02:56:51
  • C#中循环语句:while、for、foreach的使用

    2022-05-01 02:42:55
  • Java中逆序遍历List集合的实现

    2022-04-03 23:48:13
  • java 教你如何给你的头像添加一个好看的国旗

    2021-11-11 02:53:25
  • Java面试必备八股文整理

    2023-11-29 12:03:50
  • springboot + mybatis + druid + 多数据源的问题详解

    2023-01-24 15:59:58
  • C#基础入门之值类型和引用类型的区别详析

    2022-02-22 00:14:04
  • java中使用map排序的实例讲解

    2021-06-24 09:34:10
  • MyBatis 如何配置多个别名 typeAliasesPackage

    2021-11-16 06:35:54
  • Java多线程之ThreadLocal浅析

    2023-06-19 19:55:37
  • SpringMVC的源码解析

    2022-10-05 20:12:18
  • SpringBoot工程打包与运行的实现详解

    2023-11-10 23:51:28
  • 深入了解Java对象的克隆

    2021-10-29 13:59:35
  • SpringCloud远程服务调用实战笔记

    2022-07-13 06:40:19
  • HashMap工作原理_动力节点Java学院整理

    2023-06-20 20:33:15
  • C语言中求字符串长度的函数的几种实现方法

    2023-07-04 23:29:05
  • java读取properties配置文件的方法

    2022-02-13 17:15:44
  • Flutter 使用fluro的转场动画进行页面切换

    2023-06-17 11:49:26
  • asp之家 软件编程 m.aspxhome.com