SSM【Mybatis篇-动态SQL】

动态SQL

1、元素
元素是最常用的判断语句,主要用于实现某些简单的条件选择。在实际应用中,我们可能会通过多个条件来精确地查询某个数据。
(1)在Eclipse中,创建一个名为 chapter07的Web项目。
SSM【Mybatis篇-动态SQL】_第1张图片
(2)将JAR包和src目录下的文件复制到chapter07中。
SSM【Mybatis篇-动态SQL】_第2张图片
mybatis-config.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>
	<properties resource="db.properties" />
	<environments default="mysql">
		<environment id="mysql">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="com/ssm/mapper/UserMapper.xml" />
	</mappers>
	</configuration>

(3)将配置文件中的数据库信息修改为外部引用的形式。即在项目的src目录下,创建一个db.properties的配置文件。

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_mybatis
jdbc.username=root
jdbc.password=root

(4)创建一个com.ssm.util包,在该包下创建工具类MybatisUtil。

package com.ssm.util;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;


public class MybatisUtil {
	private static SqlSessionFactory factory=null;
	static{
	
	try {
		String resource="mybatis-config.xml";
		InputStream inputStream;
		inputStream = Resources.getResourceAsStream(resource);
		 factory=new SqlSessionFactoryBuilder().build(inputStream);
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
	}
	public static SqlSession getSession(){
		return factory.openSession();
		
	}
}

(5)修改映射文件 UserMapper.xml,在映射文件中使用元素编写根据用户姓名(username)和职业(jobs)组合条件查询用户信息列表的动态SQL。

<?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.ssm.mapper.UserMapper">
		<select id="findUserByNameJobs" parameterType="com.ssm.po.User" resultType="com.ssm.po.User">
			select * from t_user where 1=1
			<if test="username !=null and username !=''">
				and username like concat('%',#{username},'%') 
			</if>
			<if test="jobs !=null and jobs!=''">
				and jobs=#{jobs}
			</if>
		</select>	 
	</mapper

(6)在测试类 MybatisTest中,编写测试方法 findUserByNameAndJobsTest()

package com.ssm.test;

import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.ssm.po.User;
import com.ssm.util.MybatisUtil;

public class MyBatisTest {
	@Test
	public void findUserByusernameandjobsTest(){
		SqlSession session=MybatisUtil.getSession();
		User user=new User();
		user.setUsername("zhangsan");
		user.setJobs("teacher");
		List<User> list=session.selectList("com.ssm.mapper.UserMapper.findUserByNameJobs",user);
		for(User users:list){
			System.out.println(users.toString());
		}
		session.close();
	}
}

2、 元素
在使用元素时,只要test属性中的表达式为true,就会执行元素中的条件语句,但是在实际应用中,有时只需要从多个选项中选择一个去执行。< choose>、、< otherwise>元素类似于Java语言中使用 switch…case…default语句。
在UserMaper中添加

<select id="findUserByNameORJobs" parameterType="com.ssm.po.User" resultType="com.ssm.po.User">
			select * from t_user where 1=1
			<choose>
				<when test="username !=null and username !=''">
				and username like concat('%',#{username},'%')
				</when>
				<when test="jobs !=null and jobs !=''">
				and jobs=#{jobs}
				</when>
				<otherwise>
					and phone is not null
				</otherwise>
			</choose>
		</select>

在测试类中添加findUserByNameORJobsTest()测试方法

@Test
public void findUserByNameORJobsTest(){
	SqlSession session=MybatisUtil.getSession();
	User user=new User();
	user.setUsername("lisi");
	user.setJobs("teacher");
	List<User> list=session.selectList("com.ssm.mapper.UserMapper.findUserByNameORJobs",user);
	for(User users:list){
		System.out.println(users);
	}
	session.close();
	
}

3、元素
映射文件中编写的SQL后面都加入了“where1=1”的条件,是为了保证当条件不成立时,拼接起来的SQL语句在执行时不会报错,即使得SQL不出现语法错误。那么在 MyBatis中,有没有什么办法不用加入“1=1”这样的条件,也能使拼接后的SQL成立呢?针对这种情况, MyBatis提供了< where>元素来处理这样的问题。

以根据用户名和职业祝贺条件查询用户信息为例

将select元素进行替换

<select  id="findUserByNameJobs" parameterType="com.ssm.po.User" resultType="com.ssm.po.User">
		 	select * from t_user
		 	<where>
		 		<if test="username !=null and username !=''">
		 		and username like concat('%',#{username},'%')
		 		</if>
		 		<if test="jobs !=null and jobs !=''">
		 		and jobs=#{jobs}
		 		</if>
		 	</where>
		 </select>

上述代码用where元素将where 1=1进行了替换。where元素会自动的判断组合条件下拼装的SQL语句,只有where元素内的条件成立才会在SQL语句中加入where关键字,否则不会添加。
4、元素
MyBatis中提供了元素来完成这一工作。元素主要用于更新操作,其主要作用是在动态包含的SQL语句前输出一个SET关键字,并将SQL语句中最后一个多余的逗号去除。
注意:在映射文件中使用元素组合进行update语句动态SQL组装时,如果元素内包含的内容都为空,则会出现SQL语法错误。所以在使用元素进行字段信息更新时,要确保传入的更新字段不能都为空。

更新用户信息案例

UserMapper.xml中添加

<update id="updateUser" parameterType="com.ssm.po.User">
		update t_user
		<set>
			<if test="username !=null and username !=''">
				username=#{username}
			</if>
			<if test="jobs !=null and jobs !=''">
				,jobs=#{jobs}
			</if>
			<if test="phone !=null and phone !=''">
				,phone=#{phone}
			</if>
		</set>
		where id=#{id}
	</update>

在其测试类中添加更新的测试方法(注意:在更新时要在session关闭前写上提交事务session.commit();

@Test
public void updateUserTest(){
	SqlSession session=MybatisUtil.getSession();
	User user=new User();
	user.setId(2);
	user.setUsername("hqx");
	user.setJobs("teacher");
	user.setPhone("123456789");
	int num=session.update("com.ssm.mapper.UserMapper.updateUser",user);
	if(num>0){
		System.out.println("更新成功"+num);
	}else{
		System.out.println("更新失败");
	}
	session.commit();
	session.close();
}

5、元素
MyBatis中已经提供了一种用于数组和集合循环遍历的方式,那就是使用< foreach>元素。假设在一个用户表中有1000条数据,现在需要将id值小于100的用户信息全部查询出来就可以通过元素来解决。

<!--<foreach>元素使用 -->
	<select id="findUserByIds" parameterType="List" resultType="com.ssm.po.User">
			select * from t_user where id in
		<foreach item="id" index="index" collection="list" open="(" separator="," close=")">
		   #{id}
		</foreach>
	</select>

的几种属性描述:
item:配置的是循环中当前的元素
index:当前元素在集合中的位置下标
collection:配置的list是传递过来的参数类型(首字母小写),可以是一个array、list(或collection)等
对于collection:

  • 传入的是单参数且参数类型是一个数组或List时,collection属性时array、list(或collection)。
  • 如果传入的参数有多个,需要把它封装成Map,collection属性值为Map的值。
  • 传入的参数是POJO包装类,属性值为该包装类中需要进行遍历的数组或集合的属性名。

open和close:配置以什么符号将这些集合元素包装起来

separator:配置的是各元素的间隔符

/*
 * 根据用户编号批量查询用户信息
 */
@Test
public void	findUserByIdsTest(){
	SqlSession sqlSession = MybatisUtil.getSession();
	List<Integer> ids=new ArrayList<Integer>();
	ids.add(2);
	ids.add(3);
	List<User> users = sqlSession.selectList("com.ssm.mapper.UserMapper.findUserByIds", ids);
	for (User user : users) {
		System.out.println(user.toString());
	}
	sqlSession.close();
	
}

6、元素
MyBatis提供了元素来解决映射文件中的SQL就要根据不同的情况提供不同形式的实现这一问题,只要使用 My Batis的语言即可与所需参数连接。主要用于实现模糊查询。

<select id="findUserByname" parameterType="com.ssm.po.User" resultType="com.ssm.po.User">
	<bind name="p_username" value="'%'+username+'%'" />
	select * from t_user
	where username like #{p_username}
	</select>

测试类

@Test
public void findUserBynameTest(){
	SqlSession session=MybatisUtil.getSession();
	User user=new User();
	user.setUsername("s");
	List<User> list=session.selectList("com.ssm.mapper.UserMapper.findUserByname",user);
	for(User users : list){
		System.out.println(users.toString());
	}
	session.close();
}

你可能感兴趣的:(ssm(框架学习),java,后端,mysql,架构,sql)