一、案例测试:不使用动态SQL语句
如果需要使用带有复杂参数的SQL语句,比如条件查询语句,需要怎样实现呢?例如,现在需要根据sid、name、age三个字段进行查询记录。
- 首先在映射配置文件中建立查询语句:
<!--多条件查询-->
<select id="selectCondition" resultType="student" parameterType="student">
SELECT * FROM student WHERE sid=#{sid} AND name=#{name} AND age=#{age}
</select>
- 然后在StudentService.class定义条件查询接口,在StudentServiceImpl.class中编写条件查询的代码:
//动态SQL的实现--条件查询
@Override
public List<Student> selectCondition(Student student) {
List<Student> list = null;
SqlSession sqlSession = null;
InputStream is = null;
try {
//1.加载核心配置文件
is = Resources.getResourceAsStream("MyBatisConfig.xml");
//2.获取到SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取到SqlSession对象
sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);//等同于:StudentMapper studentMapper = new StudentMapperImpl();
//5.通过实现类对象调用方法,接收结果
list = studentMapper.selectCondition(student);
} catch (IOException e) {
e.printStackTrace();
}finally {
//6.释放资源
if(sqlSession != null) {
sqlSession.close();
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//7.返回结果
return list;
}
- 控制层测试功能:
//条件查询功能
@Test
public void selectCondition(){
//创建Student对象,设置查询条件
Student stuTmp = new Student();
stuTmp.setSid(2);
stuTmp.setName("小乙");
stuTmp.setAge(24);
List<Student> students = service.selectCondition(stuTmp);
for (Student stu : students) System.out.println(stu);
}
- 结果:此时可以查询到该条记录。但将setSid、setName、setAge中任意一条去掉,即sid、name、age三个参数缺少任意一个,则不能查询到此记录。如果想这三个参数不管传入几个,都能执行查询语句呢?例如,只传入sid,就根据sid查询;传入了sid和age就根据这两个字段查。
二、动态SQL语句
动态SQL根据实体类的不同取值,可以使用不同的SQL语句进行查询。主要用到的标签有如下:
- <where> 用于替换WHERE条件之后的语句
- <if>
<if test="条件判断"> 查询条件拼接 </if>
- <foreach>
<foreach collection="参数容器类型(list、array)" open="开始SQL语句" close="结束SQL语句" item="参数变量名" separator="分隔符"> 获取参数 </foreach>
1.< if>标签使用案例
将第一步中的映射文件中的条件查询语句更改为如下:
<!--多条件查询-->
<select id="selectCondition" resultType="student" parameterType="student">
SELECT * FROM student
<where>
<if test="sid != null">
sid=#{sid}
</if>
<if test="name != null">
AND name=#{name}
</if>
<if test="age != null">
AND age=#{age}
</if>
</where>
</select>
此时不管通过sid、name、age中的一个或多个字段都能查询到该记录。
2.< foreach>标签使用案例
- 首先在映射配置文件中建立查询语句:
<select id="selectByIds" resultType="student" parameterType="list">
SELECT * FROM student
<where>
<foreach collection="list" open="sid IN(" close=")" item="sid" separator=",">
#{sid}
</foreach>
</where>
</select>
- 然后在StudentService.class定义条件查询接口,在StudentServiceImpl.class中编写条件查询的代码:
//根据多个查询有无其中一个
@Override
public List<Student> selectByIds(List<Integer> idList) {
List<Student> list = null;
SqlSession sqlSession = null;
InputStream is = null;
try {
//1.加载核心配置文件
is = Resources.getResourceAsStream("MyBatisConfig.xml");
//2.获取到SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取到SqlSession对象
sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);//等同于:StudentMapper studentMapper = new StudentMapperImpl();
//5.通过实现类对象调用方法,接收结果
list = studentMapper.selectByIds(idList);
} catch (IOException e) {
e.printStackTrace();
}finally {
//6.释放资源
if(sqlSession != null) {
sqlSession.close();
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//7.返回结果
return list;
}
- 最后在控制层中测试:
//根据多个查询有无其中一个
@Test
public void selectByIds(){
//创建idList,设置查询条件
List<Integer> idList = new ArrayList<>();
idList.add(1);
idList.add(2);
List<Student> students = service.selectByIds(idList);
for (Student stu : students) System.out.println(stu);
}
此时可查询到在list中存在的sid的记录。
三、常用SQL语句抽取
像SELECT * FROM
这种SQL语句使用较为频繁,所以可以将其进行抽取,以便于后续复用。这里使用<sql>标签:
<sql id="SQL语句唯一标识"> 抽取的SQL语句 </sql>
通过<include>标签引入定义的SQL语句:
<include refid="SQL语句唯一标识" />
例如,在上一步的<foreach>标签使用时可以使用:
<sql id="select0"> SELECT * FROM student </sql>
<select id="selectByIds" resultType="student" parameterType="list">
<include refid="select0"/>
<where>
<foreach collection="list" open="sid IN(" close=")" item="sid" separator=",">
#{sid}
</foreach>
</where>
</select>