MyBatis中的动态SQL

本文详细介绍了MyBatis框架中动态SQL的多种实现方式,包括if标签、where标签、foreach标签的应用场景及具体实现,并提供了丰富的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、Mybatis中的动态sql的实现

    通过mybatis提供的各种标签方法实现动态拼接sql。

2、 If 标签(注意要做不等于空字符串校验

<!-- 传递pojo综合查询用户信息 -->  
<select id="findUserList" parameterType="user" resultType="user">  
    select * from user   
    where 1=1   
    <if test="id!=null and id!=''">  
    and id=#{id}  
    </if>  
    <if test="username!=null and username!=''">  
    and username like '%${username}%'  
    </if>  
</select>  


3、Where标签 (可以自动处理第一个and,也可以用1=1来实现)

<select id="findUserList" parameterType="user" resultType="user">  
   select * from user   
   <where>  
     <if test="id!=null and id!=''">  
         and id=#{id}  
     </if>  
     <if test="username!=null and username!=''">  
         and username like '%${username}%'  
     </if>  
   </where>  
</select>  

4、Foreach标签(向sql传递POJO或者List或者数组

      4.1 foreach标签,应用的情况

    传入多个id查询用户信息,用下边两个sql实现:

    SELECT * FROM USERS WHERE username LIKE '%张%' AND (id=10 OR id =89 OR id=16)

    SELECT * FROM USERS WHERE username LIKE '%张%'  id IN (10,89,16)

      4.2 传入POJO

            4.2.1   POJO的实现

public class QueryVo {
	// 传递多个用户id
	private List<Integer> ids = new ArrayList<Integer>();
	public List<Integer> getIds() {
		return ids;
	}
	public void setIds(List<Integer> ids) {
		this.ids = ids;
	}
}
           4.2.2 mapper.xml

<!-- 用于foreach的动态SQL -->
	<select id="userListForeach" resultType="com.baowei.entity.User"
		parameterType="com.baowei.entity.QueryVo">
		select * from user
		<where>
			<if test="ids != null and ids.size > 0">
				<foreach collection="ids" open=" and id in(" close=")" item="id"
					separator=",">
					#{id}
				</foreach>
			</if>
		</where>
	</select>

          4.2.3 测试代码 

public class TestDongTaiSQL {
	private SqlSession sqlSession;
	@Before
	public void setUp() throws Exception {
		String resource = "SqlMapConfig.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(inputStream);
		sqlSession = sqlSessionFactory.openSession();
	}
	@Test
	public void testuserListForeach() {
		List<Integer> ids = Arrays.asList(1, 10, 3);
		// 获取mapper接口的代理对象
		DynamicSQLMapper dynamicSQLMapper = sqlSession
				.getMapper(DynamicSQLMapper.class);
		QueryVo queryVo = new QueryVo();
		queryVo.setIds(ids);
		// 调用代理对象方法
		List<User> users = dynamicSQLMapper.userListForeach(queryVo);
		System.out.println(users);
		// 关闭session
		// session.close();
	}
}

      4.3 传入List

           传递List类型在编写mapper.xml没有区别,唯一不同的是只有一个List参数时它的参数名为list

          4.3.1 Mapper.xml

  <!--传递单个list -->  
<select id="useListForeachOne" parameterType="java.util.List"  
resultType="user">  
select * from user  
<where>  
    <!-- 传递List,List中是pojo -->  
    <if test="list!=null">  
        <foreach collection="list" item="item" open="and id in("  
            separator="," close=")">  
            #{item.id}  
        </foreach>  
    </if>  
</where>  
</select> 

          4.3.2 Mapper.java代码

// 使用单个的list  
List<User> useListForeachOne(List<User> users);  

          4.3.3 测试代码

public void testoneuserListForeach() {  
        // 获取session  
        SqlSession session = sqlSessionFactory.openSession();  
        // 获取mapper接口的代理对象  
        UserMapper userMapper = session.getMapper(UserMapper.class);  
        // 构造查询条件List  
        List<User> userlist = new ArrayList<User>();  
        User user = new User();  
        user.setId(1);  
        userlist.add(user);  
        user = new User();  
        user.setId(10);  
        userlist.add(user);  
        // 传递userlist列表查询用户列表  
        // 调用代理对象方法  
        List<User> list = userMapper.useListForeachOne(userlist);  
  
        for (int i = 0; i < list.size(); i++) {  
            System.out.println(list.get(i));  
        }  
        // 关闭session  
        session.close();  
    }  

      4.4 传入数组(数值中是pojo)

          4.4.1 Mapper.xml

 <!-- 传递数组综合查询用户信息 -->  
<select id="selectUserByArray" parameterType="Object[]" resultType="user">  
    select * from user   
     <where>  
       <!-- 传递数组 -->  
       <if test="array!=null">  
           <foreach collection="array" index="index" item="item" open="and id in(" separator="," close=")">  
              #{item.id}   
           </foreach>  
       </if>  
    </where>  
</select> 

sql只接收一个数组参数,这时sql解析参数的名称mybatis固定为array,如果数组是通过一个pojo传递到sql则参数的名称为pojo中的属性名。

index:为数组的下标。

item:为数组每个元素的名称,名称随意定义

open:循环开始

close:循环结束

separator:中间分隔输出

         4.4.2 Mapper接口

public List<User> selectUserByArray(Object[] userlist) throws Exception;

          4.4.3 测试代码

public void testselectUserByArray()throws Exception{  
        //获取session  
        SqlSession session = sqlSessionFactory.openSession();  
        //获限mapper接口实例  
        UserMapper userMapper = session.getMapper(UserMapper.class);  
        //构造查询条件List  
        Object[] userlist = new Object[2];  
        User user = new User();  
        user.setId(1);  
        userlist[0]=user;  
        user = new User();  
        user.setId(2);  
        userlist[1]=user;  
        //传递user对象查询用户列表  
        List<User>list = userMapper.selectUserByArray(userlist);  
        //关闭session  
        session.close();  
    }  

5、SQL片段

      Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的,如下:

  <!-- 传递pojo综合查询用户信息 -->  
<select id="findUserList" parameterType="user" resultType="user">  
     select * from user   
      <where>  
        <if test="id!=null and id!=''">  
          and id=#{id}  
        </if>  
        <if test="username!=null and username!=''">  
          and username like '%${username}%'  
        </if>  
     </where>  
</select>  

        将where条件,也会是IF标签抽取出来

<sql id="query_user_where">  
    <if test="id!=null and id!=''">  
        and id=#{id}  
    </if>  
    <if test="username!=null and username!=''">  
        and username like '%${username}%'  
    </if>  
</sql>  

       使用include引用

 <select id="findUserList" parameterType="user" resultType="user">  
        select * from user   
       <where>  
          <include refid="query_user_where"/>  
       </where>  
    </select> 

       引用其它mapper.xml的sql片段,引用时需要加上namespace

<include refid="namespace.sql片段”/> 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值