Mybatis框架|动态SQL


Mybatis相比Hibernate能够让我们进行灵活的sql语句拼接,下面介绍动态sql的几种拼接方式。

一、准备数据库表

创建数据库表,并添加记录。创建表的sql语句和添加后的数据库记录如下:

CREATE TABLE `user` (
	`id` INT(20)  AUTO_INCREMENT COMMENT '主键',
	`username` VARCHAR(50) NULL DEFAULT NULL COMMENT '姓名',
	`sex` VARCHAR(1) NULL DEFAULT NULL COMMENT '性别',
	`address` VARCHAR(200) NULL DEFAULT NULL COMMENT '住址',
	`birthday` DATE NULL DEFAULT NULL COMMENT '生日',
	PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1
;

手动向数据库添加如下记录:
在这里插入图片描述

二、动态sql

1.if和where标签

if标签外的where标签本身就相当于写了1=1。
if标签中的sql语句前一般都写上and。

(1)多条件组合查询接口

package com.gql.mapper;

import java.util.List;

import com.gql.pojo.User;
import com.gql.pojo.UserQueryvo;
/**
 * 类说明:
 *		组合查询接口
 * @guoqianliang1998.
 */
public interface UserMapper {
	//多条件组合查询
	List<User> getUserListByCondition(UserQueryvo vo);
}

(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.gql.mapper.UserMapper">

	<select id="getUserListByCondition" parameterType="com.gql.pojo.UserQueryvo" resultType="com.gql.pojo.User">
		SELECT id,
		username name,
		sex,
		address,
		birthday 
		FROM user 
		<where>
			<if test="user!=null">
				<if test="user.name != null and user.name != ''">
					and username LIKE '%${user.name}%'
				</if>
				<if test="user.sex != null and user.sex != ''">
					 AND sex=#{user.sex};
				</if>
			</if>
		</where>

	</select>
</mapper>

(3)多条件组合查询测试

package com.gql.mapper;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

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 com.gql.pojo.User;
import com.gql.pojo.UserQueryvo;

public class UserMapperTest {
	private SqlSessionFactory sqlSessionFactory;
	@Before
	public void init() throws IOException{
		String resource = "mybatis-config.xml";
		InputStream in = Resources.getResourceAsStream(resource);
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);		
	}

	//不输入姓名和性别
	@Test
	public void testGetUserListByCondition1(){
		SqlSession session = sqlSessionFactory.openSession();
		UserMapper userMapper = session.getMapper(UserMapper.class);
		UserQueryvo vo = new UserQueryvo();
		List<User> userList = userMapper.getUserListByCondition(vo);
		for (User i : userList) {
			System.out.println(i.getName());
		}
	}
	
	//仅输入姓名
	@Test
	public void testGetUserListByCondition2(){
		SqlSession session = sqlSessionFactory.openSession();
		UserMapper userMapper = session.getMapper(UserMapper.class);
		UserQueryvo vo = new UserQueryvo();
		User user = new User();
		user.setName("小");
		vo.setUser(user);
		List<User> userList = userMapper.getUserListByCondition(vo);
		for (User i : userList) {
			System.out.println(i.getName());
		}
	}
	
	//同时输入姓名和性别
	@Test
	public void testGetUserListByCondition3(){
		SqlSession session = sqlSessionFactory.openSession();
		UserMapper userMapper = session.getMapper(UserMapper.class);
		UserQueryvo vo = new UserQueryvo();
		User user = new User();
		user.setName("小");
		user.setSex("男");
		vo.setUser(user);
		List<User> userList = userMapper.getUserListByCondition(vo);
		for (User i : userList) {
			System.out.println(i.getName());
		}
	}

三种测试结果分别如下:
(1)不输入姓名和性别


DEBUG [main] - ==>  Preparing: SELECT id, username name, sex, address, birthday FROM user 
DEBUG [main] - <==      Total: 7
程蝶衣
程小楼
周冬雨
王小花
周润发
钟南山
蔡小坤

(2)仅输入姓名

DEBUG [main] - ==>  Preparing: SELECT id, username name, sex, address, birthday FROM user WHERE username LIKE '%小%' 
DEBUG [main] - <==      Total: 3
程小楼
王小花
蔡小坤

(3)同时输入姓名和性别

DEBUG [main] - ==>  Preparing: SELECT id, username name, sex, address, birthday FROM user WHERE username LIKE '%小%' AND sex=?; 
DEBUG [main] - <==      Total: 2
程小楼
蔡小坤

2.sql片段

sql片段使用sql标签,并使用唯一id标记,使用时,使用include标签引用即可。使用sql片段可以提高代码复用率,下面演示使用sql片段进行多条件组合查询总记录数。

(1)多条件组合查询总记录数接口

package com.gql.mapper;
import java.util.List;

import com.gql.pojo.User;
import com.gql.pojo.UserQueryvo;
/**
 * 类说明:
 *		接口
 * @guoqianliang1998.
 */
public interface UserMapper {
	//多条件组合查询总记录数
	int getCountByCondition(UserQueryvo vo);
}

(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.gql.mapper.UserMapper">
	<!-- sql片段 -->
	<sql id="userCondition">
			<if test="user!=null">
				<if test="user.name != null and user.name != ''">
					and username LIKE '%${user.name}%'
				</if>
				<if test="user.sex != null and user.sex != ''">
					 AND sex=#{user.sex};
				</if>
			</if>
	</sql>
	<select id="getCountByCondition" parameterType="com.gql.pojo.UserQueryvo" resultType="int">
		SELECT
		count(1)
		FROM user 
		<where>
			<include refid="userCondition"></include>
		</where>
	</select>
</mapper>

(3)多条件组合查询总记录测试

package com.gql.mapper;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

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 com.gql.pojo.User;
import com.gql.pojo.UserQueryvo;

public class UserMapperTest {
	private SqlSessionFactory sqlSessionFactory;
	@Before
	public void init() throws IOException{
		String resource = "mybatis-config.xml";
		InputStream in = Resources.getResourceAsStream(resource);
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);		
	}
	
	//不输入姓名和性别
	@Test
	public void testGetCountByCondition1(){
		SqlSession session = sqlSessionFactory.openSession();
		UserMapper userMapper = session.getMapper(UserMapper.class);
		UserQueryvo vo = new UserQueryvo();
		int count = userMapper.getCountByCondition(vo);
		System.out.println(count);
	}
	//仅输入姓名
	@Test
	public void testGetCountByCondition2(){
		SqlSession session = sqlSessionFactory.openSession();
		UserMapper userMapper = session.getMapper(UserMapper.class);
		UserQueryvo vo = new UserQueryvo();
		User user = new User();
		user.setName("小");
		vo.setUser(user);
		int count = userMapper.getCountByCondition(vo);
		System.out.println(count);
	}
	//同时输入姓名和性别
	@Test
	public void testGetCountByCondition3(){
		SqlSession session = sqlSessionFactory.openSession();
		UserMapper userMapper = session.getMapper(UserMapper.class);
		UserQueryvo vo = new UserQueryvo();
		User user = new User();
		user.setName("小");
		user.setSex("男");
		vo.setUser(user);
		int count = userMapper.getCountByCondition(vo);
		System.out.println(count);
	}
}

上面三种测试结果分别如下:
(1)不输入姓名和性别

DEBUG [main] - ==>  Preparing: SELECT count(1) FROM user 
DEBUG [main] - <==      Total: 1
7

(2)仅输入姓名

DEBUG [main] - ==>  Preparing: SELECT count(1) FROM user WHERE username LIKE '%小%' 	
DEBUG [main] - <==      Total: 1
3

(3)同时输入姓名和性别

DEBUG [main] - ==>  Preparing: SELECT count(1) FROM user WHERE username LIKE '%小%' AND sex=?; 
DEBUG [main] - <==      Total: 1
2

3.foreach标签

foreach标签的属性 说明
item 集合中元素迭代时的别名,该参数为必选。
index 在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。
open foreach代码的开始符号,一般是(和close=")"合用(常用在in(),values()时。该参数可选。)
close foreach代码的关闭符号
separator 元素之间的分隔符(例如在in()的时候,separator=",")
collection foreach的对象

可以参照下面的用法:

	<select id="getUserListByForeach" parameterType="com.gql.pojo.UserQueryvo" resultType="com.gql.pojo.User">
		SELECT id,
		username,
		sex,
		address,
		birthday 
		FROM user 
		<where>
			id IN
			<if test="ids != null ">
				<foreach collection="ids" item="i" open="(" close=")" separator=",">
					#{i}
				</foreach>
			</if>
		</where>
	</select>
发布了413 篇原创文章 · 获赞 1081 · 访问量 23万+

猜你喜欢

转载自blog.csdn.net/weixin_43691058/article/details/104246249
今日推荐