7.MyBatis 核心配置以及动态SQL

7.1 MyBatis的核心对象

7.1.1SqlSessionFactory

它是一个十分重要的对象,是单个数据库映射关系经过编译后的内存镜像,主要作用是用来创建Session,SqlSessionFactory对象是线程安全的,它一旦被创建,在整个应用执行期间都会存在,如果我们多次创建同一个数据库的SqlSessionFactory,那么此数据库的资源很容易被耗尽。因此,通常每一个数据库都会只对应一个SqlSessionFactory。

7.1.2SqlSession

它是应用程序与持久层之间执行交互操作的一个单线程对象,其主要作用是执行持久化操作,SqlSession包括了所有的执行SQL操作的方法,它是线程不安全的,因此其使用范围最好在一次请求或一个方法中,
利用工具类创建SqlSession

package com.itheima.utils;
import java.io.Reader;
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 MybatisUtils {
    
    
	private static SqlSessionFactory sqlSessionFactory = null;
	static {
    
    
		try {
    
    
			Reader reader = 
					Resources.getResourceAsReader("mybatis-config.xml");
			sqlSessionFactory = 
					new SqlSessionFactoryBuilder().build(reader);
		} catch (Exception e) {
    
    
			e.printStackTrace();
		}
	}
	public static SqlSession getSession() {
    
    
		return sqlSessionFactory.openSession();
	}
}

7.1.3< sql > 元素

这个并非核心对象,这是一个配置元素标签,这个元素相当于声明了一个变量
定义格式如下

<sql id="customerColumns">id,username,jobs,phone</sql>

这个就像我们定义String name = “hellloworld” 赋予name了值
这里我们通过sql便签赋予customerColumns值id,username,jobs,phone
这样我们可以写出以下语句

<select id="findCustomerById" parameterType="Integer" 
 		resultType="com.itheima.po.Customer"> 
 		select <include refid="customerColumns"></include>from t_customer where id = #{id} 
	</select> 

相当于select id,username,jobs,phone from t_custome r where id = #{id}
复杂的嵌套格式
思路:嵌套定义查找的表名

from t_customer

对其拆分

<sql id="customerColumns">id,username,jobs,phone</sql>
<sql id="tablename">${prefix}customer</sql>
<sql id="someinclude">from <include refid="${include_target}"></include></sql>
<select id="findCustomerById" parameterType="Integer" 
 		resultType="com.itheima.po.Customer"> 
 	select <include refid="customerColumns"></include>
 	<include refid="someinclude">
 		<property name="prefix" value="t_"/>
 		<property name="include_target" value="tablename"/>
 		</include>
 	   where id = #{id} 
	</select> 

转换之后

select id,username,jobs,phone from t_customer where id = ? 

7.2 动态SQL

7.2.1 if元素

就是个判断语句

	<select id = "findBynameAndJobs" parameterType="com.itheima.po.Customer"
			resultType="com.itheima.po.Customer">
			select * from t_customer where 1=1
		    <if test = "username != null and username != ''">
				and username like concat('%',#{username},'%')
			</if>
			<if test = "jobs != null and jobs != ''">
				and jobs like concat('%',#{jobs},'%')
			</if>
	</select>

值得注意:username != '‘与username !=’ '(单引号之间加了空格会报错)

select * from t_customer where 1=1 and username like concat('%',?,'%') and jobs like concat('%',?,'%')

7.2.2 choose when otherwise元素

多个选项选择一个选项

	</select>
	<!-- choose元素  when元素 otherwise -->
		<select id = "findBynameOrJobs" parameterType="com.itheima.po.Customer"
			resultType="com.itheima.po.Customer">
			select * from t_customer where 1=1
			<choose>
			    <when test = "username != null and username != ''">
					and username like concat('%',#{username},'%')
				</when>
				<when test = "jobs != null and jobs != ''">
					and jobs like concat('%',#{jobs},'%')
				</when>
				<otherwise>
					and phone is not null
				</otherwise>
			</choose>
	</select>

当用户名不空时

select * from t_customer where 1=1 and username like concat('%',?,'%')

当用户名为空,职业非空

select * from t_customer where 1=1 and jobs like concat('%',?,'%') 

7.2.3where 和 trim 元素

在之前写的语句中,我们会发现都带有 1=1 感觉这个时废话,但是如果去掉的话,生成的SQL语句就会变成了

select * from t_customer where and jobs like concat('%',?,'%')

这样必定会报错了
在这里插入图片描述
有没有其他的解决方法呢?
方法一:使用where元素
直接在外面使用where元素包裹即可

select * from t_customer 
			<where>
			<choose>
			    <when test = "username != null and username != ''">
					and username like concat('%',#{username},'%')
				</when>
				<when test = "jobs != null and jobs != ''">
					and jobs like concat('%',#{jobs},'%')
				</when>
				<otherwise>
					and phone is not null
				</otherwise>
			</choose>
			</where>

生成sql

select * from t_customer WHERE jobs like concat('%',?,'%') 

方法二:使用trim元素

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ...
</trim>

prefix代表语句的前缀
prefixOverrides代表需要去除的那些特殊的字符串

7.2.3 set 元素

用来更新元素,set元素会动态前置set关键字,同时也会自动消除最后一个逗号,set内的元素如果为空会出现sql语法错误。

	<update id="updateCustomer" parameterType="com.itheima.po.Customer">
	update t_customer 
	<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>
update t_customer SET username = ? jobs = ?, phone = ? where id = ? 

7.2.4 foreach 元素

用于数组和集合循环遍历

	<select id="findByArray" parameterType="List"
	resultType="com.itheima.po.Customer">
		select * from t_customer
		where id in
		<foreach collection="list" item="id" index="index"
				open="(" separator="," close=")">
				#{id}</foreach>
	</select>
  • item:配置的是循环中当前的元素
  • index:配置的是当前元素在集合的位置的下表
  • collection:配置的list是传递过来的参数类型(首字母小写)
  • open和close:配置的是以什么符号将这些集合元素包装起来
  • separator:配置的是各个元素的间隔符

7.2.5 bind 元素

既解决防止动态SQL注入,一方面提高可移植性
直接引用bind元素的name属性值即可进行SQL组装

<select id="findCustomerByName2" parameterType="String"
		resultType="com.itheima.po.Customer">
		<bind name="pattern_name" value="'%'+username+'%'"/>
		select * from t_customer where username like #{pattern_name}
</select>

猜你喜欢

转载自blog.csdn.net/q54188p/article/details/113680302
今日推荐