文章目录
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>