SQL语句写起来太繁琐?你可以试试 MyBatis “动态” SQL

文章目录

  • 动态SQL介绍
  • 实体类属性
  • sql
  • where... if
  • set...if
  • foreach

动态SQL介绍

  • 动态SQL是Mybatis强大的特性之一。极大的简化了我们拼装SQL的操作
  • 动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似
  • MyBatis 采用功能强大的基于 OGNL 的表达式来简化操作。

实体类属性

public class Book implements Serializable {
	private static final long serialVersionUID = 1L;
	private Integer id;
	private String isbn;
	private String title;
	private String author;
	private Double price;
	private Date date;
	private String cover;
	private Publisher publisher;
}

sql

: 将sql语句定义为一个变量
: 引用定义好的sql

例如:

定义sql标签

<sql id="tab">
		SELECT * FROM book_tab
</sql>

查询所有的书,引用了定义好的sql

<select id="findAll" resultMap="BookMap" >
		<include refid="tab"/>
</select>

test代码:

	@Test
	public void findAll() {
		MybatisUtil db = MybatisUtil.getInstance();
		SqlSession sqlSession = db.opeSqlSession();
		IBookMapper mapper = sqlSession.getMapper(IBookMapper.class);
		List<Book> books = mapper.findAll();

		Iterator<Book> iterator = books.iterator();

		while (iterator.hasNext()) {
			System.out.println(iterator.next());
		}
		sqlSession.commit();
		sqlSession.close();
	}

结果:
在这里插入图片描述
根据日志可以清除的看到 正确的引用了sql标签

where… if

使用动态SQL最常见情景是根据条件包含where子句的一部分
当我们希望全查询的时候,if 子句的作用就在这里,它根据你所传递的参数来判断是否进行拼接。

  • where:代表的是where子句
  • if代表的条件的判断

例如:
如果我们希望通过author和title进行查询

select代码:

<select id="findByCondition" resultMap="BookMap">
		<include refid="tab"/>
		<where>
			 <if test="author!=null">
	   	AND book_author=#{author}
	   </if>
	   <if test="isbn!=null">
	   	AND book_isbn=#{isbn}
	   </if>
	   <if test="title!=null">
	   	AND book_title=#{title}
	   </if>
	   <if test="price!=null">
	   	AND book_price=#{price}
	   </if>
		</where>
	
	</select>

where 标签 说明此处后面是一个where 查询,如果if中的不为null。则将 if 标签中语句进行拼接。
测试代码:

@Test
	public void findByCondition() {
		MybatisUtil db = MybatisUtil.getInstance();
		SqlSession sqlSession = db.opeSqlSession();
		IBookMapper mapper = sqlSession.getMapper(IBookMapper.class);

		Book book = new Book();
		book.setTitle("java");
		book.setAuthor("hahah");

		List<Book> list = mapper.findByCondition(book);
		list.forEach(e->System.out.println(e));

		sqlSession.commit();
		sqlSession.close();
	}

测试结果:
在这里插入图片描述
我们在测试代码中只设置了author和title 的值所有在进行SQL拼接的时候,只对author和title两项进行了拼接,由此我们就实现了动态变迁,根据需求来动态的实现不同的sql语句。

如果不设置任何的值,则会进行全查询

set…if

和where类似

<select id="updateBook" resultMap="BookMap" >
	
		UPDATE book_tab 
		<set>
			<if test="author!=null">
				 book_author=#{author},
			</if>
			<if test="isbn!=null">
				 book_isbn=#{isbn},
			</if>
			<if test="title!=null">
				 book_title=#{title},
			</if>
			<if test="price!=null">
				 book_price=#{price},
			</if>
		</set>
		
		WHERE book_id = #{id}
	
	
	</select>

test代码:

@Test
	public void updateBook() {
		MybatisUtil db = MybatisUtil.getInstance();
		SqlSession sqlSession = db.opeSqlSession();
		IBookMapper mapper = sqlSession.getMapper(IBookMapper.class);

		Book book = new Book();
		book.setId(12);
		book.setTitle("java");
		book.setAuthor("hahah");

		mapper.updateBook(book);

		sqlSession.commit();
		sqlSession.close();
	}

结果:
在这里插入图片描述

foreach

  • 动态 SQL 的另外一个常用的必要操作是需要对一个集合进行遍历,通常是在构建 IN 条件语句的时候。

foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符。

代码:

<select id="findByAuthors" resultMap="BookMap">
		<include refid="tab" />
		WHERE book_author IN

		<foreach collection="authors" item="x" open="(" close=")"
			separator=",">
			#{x}
		</foreach>

	</select>

separator为分隔符

test代码:

@Test
	public void findByAuthors() {
	SqlSession sqlSession = MybatisUtil.getInstance().opeSqlSession();
		
		IBookMapper mapper = sqlSession.getMapper(IBookMapper.class);
		
		List<String> authors = new ArrayList<>();
		authors.add("吴承恩");
		authors.add("陈俊宇");
		
		List<Book> list = mapper.findByAuthors(authors);
		
		list.forEach(e->System.out.println(e));
		
		
		
		sqlSession.commit();
		sqlSession.close();
	}

测试结果:

在这里插入图片描述

你可能感兴趣的:(JAVA,sql,java,数据库,mybatis,动态SQL)