详细介绍:MyBatis框架 - 映射文件动态SQL

搭建通用代码

  1. 通用的实体类User:
    package com.tx.entity;
    import java.io.Serializable;
    import java.util.Date;
    import java.util.List;
    // 实体类
    public class User implements Serializable {
    // 字段 - 与mysql中的字段要一致
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    // 定义ids属性,用来存储所有的id
    private List<Integer> ids;
      public Integer getId() {
      return id;
      }
      public void setId(Integer id) {
      this.id = id;
      }
      public String getUsername() {
      return username;
      }
      public void setUsername(String username) {
      this.username = username;
      }
      public Date getBirthday() {
      return birthday;
      }
      public void setBirthday(Date birthday) {
      this.birthday = birthday;
      }
      public String getSex() {
      return sex;
      }
      public void setSex(String sex) {
      this.sex = sex;
      }
      public String getAddress() {
      return address;
      }
      public void setAddress(String address) {
      this.address = address;
      }
      public List<Integer> getIds() {
        return ids;
        }
        public void setIds(List<Integer> ids) {
          this.ids = ids;
          }
          @Override
          public String toString() {
          return "User{" +
          "id=" + id +
          ", username='" + username + '\'' +
          ", birthday=" + birthday +
          ", sex='" + sex + '\'' +
          ", address='" + address + '\'' +
          ", ids=" + ids +
          '}';
          }
          }
  2. 通用的接口类UserMapper:
    package com.tx.mapper;
    import com.tx.entity.User;
    import java.util.List;
    // 动态SQL语句 - if标签、where标签、foreach标签的使用
    public interface UserMapper2 {
    // 条件查询
    public List<User> findByWhere(User user);
      // 通过ids查找需要的id们
      public List<User> findByIds(User user);
        }
  3. 通用的SqlMapConfig.xml
    <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE configuration
      PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
      "http://mybatis.org/dtd/mybatis-3-config.dtd">
      <configuration>
        <!--主配置文件-->
          <!--配置环境们-->
              <environments default="mysql">
              <!--配置环境-->
                  <environment id="mysql">
                  <!--配置事务的类型,使用本地事务策略-->
                  <transactionManager type="JDBC"></transactionManager>
                    <!--配置是否使用连接池 POOLED表示使用链接池,UNPOOLED表示不使用连接池-->
                        <dataSource type="POOLED">
                        <property name="driver" value="com.mysql.jdbc.Driver"/>
                        <property name="url" value="jdbc:mysql:///mybatis_db"/>
                        <property name="username" value="root"/>
                        <property name="password" value="root"/>
                      </dataSource>
                    </environment>
                  </environments>
                  <!--加载映射文件-->
                    <mappers>
                    <mapper resource="mapper/UserMapper2.xml"></mapper>
                    </mappers>
                  </configuration>
  4. 通用的测试类UserTest:
    • 注意:只写测试前(加载主配置文件、创建sql会话工厂、创建sql会话)、测试后(关闭资源)的代码,具体测试代码会跟随不同的动态sql写。
    package com.tx.test;
    import com.tx.entity.User;
    import com.tx.mapper.UserMapper2;
    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.Before;
    import org.junit.Test;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.List;
    // 动态SQL语句 - if标签、where标签、foreach标签的使用
    public class UserTest2 {
    private InputStream in;
    private SqlSessionFactory factory;
    private SqlSession session;
    @Before
    public void init() throws IOException {
    // 1. 加载主配置文件
    in = Resources.getResourceAsStream("SqlMapConfig2.xml");
    // 2. 创建sql会话工厂对象
    factory = new SqlSessionFactoryBuilder().build(in);
    // 3. 创建sql会话对象
    session = factory.openSession();
    }
    public void destory() throws IOException {
    // 5. 关闭资源
    session.close();
    in.close();
    }
    }

一、动态SQL语句 - if标签

UserMapper.xml配置文件:

<select id="findByWhere" parameterType="com.tx.entity.User" resultType="com.tx.entity.User">
  select * from user where 1 = 1
    <if test="username != null and username !=''">
    and username like #{username}
  </if>
    <if test="sex !=null and sex !=''">
    and sex = #{sex}
  </if>
</select>

where 1 = 1的作用:

  • 为了构建查询条件时,避免处理where后的第一个条件是否需要and的问题。
  • select * from user where 1 = 1 and …… 无论后面的条件是否满足,都不会造成语法错误
  • 可以使用标签代替where 1 = 1

测试代码:

// 4.1 条件查询
@Test
public void testFindByWhere(){
// 创建实体类对象,进行查询条件设置
User user = new User();
user.setUsername("%熊%");
user.setSex("女");
// 条件查询
UserMapper2 mapper = session.getMapper(UserMapper2.class);
List<User> list = mapper.findByWhere(user);
  for (User user1:list){
  System.out.println(user1);
  }
  }

二、动态SQL语句 - where标签

where标签的目的:去掉where 1 = 1
UserMapper.xml配置文件:

<select id="findByWhere" parameterType="com.tx.entity.User" resultType="com.tx.entity.User">
  select * from user
  <where>
      <if test="username != null and username !=''">
      and username like #{username}
    </if>
      <if test="sex !=null and sex !=''">
      and sex = #{sex}
    </if>
  </where>
</select>

测试代码:使用if标签的测试代码。

三、动态SQL语句 - foreach标签

UserMapper.xml配置文件,有两种实现方式:

  • 方式一:select * from user where id = 1 or id = 2 or id = 3
    <!--方式一:-->
      <!--select * from user where id = 1 or id = 2 or id = 3-->
        <!--open:从id开始
        separator:连接条件
        item:连接符
        -->
          <select id="findByIds" parameterType="com.tx.entity.User" resultType="com.tx.entity.User">
          select * from user
          <where>
              <foreach collection="ids" open="id = " separator="or id = " item="i">
              #{i}
            </foreach>
          </where>
        </select>
  • 方式二:select * from user where id in(1,2,3)
    <!--方式二:-->
      <!--select * from user where id in(1,2,3) -->
          <select id="findByIds" parameterType="com.tx.entity.User" resultType="com.tx.entity.User">
          select * from user
          <where>
              <foreach collection="ids" open="id in (" separator="," close=")" item="i">
              #{i}
            </foreach>
          </where>
        </select>

测试代码:

// 4.2 id集合查询
@Test
public void testFindByIds() throws IOException {
// 创建List集合
User user = new User();
List<Integer> ids = new ArrayList<>();
  ids.add(1);
  ids.add(2);
  ids.add(5);
  // 添加一个null,结果显示没有
  ids.add(10);
  user.setIds(ids);
  // 条件查询
  UserMapper2 mapper = session.getMapper(UserMapper2.class);
  List<User> list = mapper.findByIds(user);
    for (User user1:list){
    System.out.println(user1);
    }
    }

四、提取公共的SQL语句

写了这么多的sql语句,可以看出select * from user是公用的,可以将这句单独提出来,后续使用的话,可使用<include>标签引用。
后续写项目,会使用大量复杂的sql语句,可以将公共的提炼出来,这样可以避免代码冗余,且方便。
UserMapper2.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">
  <!--namespace:Dao层的接口类的全包名-->
      <mapper namespace="com.tx.mapper.UserMapper2">
      <!--提供公共的SQL-->
          <sql id="findAllsql">
          select * from user
        </sql>
          <select id="findByWhere" parameterType="user" resultType="user">
          <include refid="findAllsql" />
          <where>
              <if test="username != null and username != ''">
              and username like #{username}
            </if>
              <if test="sex != null and sex != ''">
              and sex like #{sex}
            </if>
          </where>
        </select>
          <select id="findByIds" parameterType="user" resultType="user">
          <include refid="findAllsql"/>
          <where>
              <foreach collection="ids" open="id in ( " separator="," close=")" item="i">
              #{i}
            </foreach>
          </where>
        </select>
      </mapper>
posted @ 2025-12-26 10:39  clnchanpin  阅读(3)  评论(0)    收藏  举报