MyBatis的使用(2) 使用注解的MyBatis 联合查询 分步查询 动态sql

MyBatis (2)

MyBatis的使用第一部分,传送地址:MyBatis的使用(1) 初学者必看 基于xml配置的MyBatis MyBatis的生命周期 ResultMap的使用 日志工厂

一、使用注解开发

  1. 注解使用在Mapper接口的方法上,无需再使用UserMapper.xml文件
public interface UserMapper {
    
    
    
    @Select("select * from user limit #{startIndex}, #{pageSize}")
    List<User> getUserListById(Map<String, Integer> map);

}

  1. 需要在核心配置文件mybatis-config.xml中绑定接口
<mappers>
    <mapper class="com.qizegao.dao.UserMapper"/>
</mappers>

  1. 测试
@Test
public void test01() {
    
    
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    //向map参数中赋值
    HashMap<String, Integer> map = new HashMap<String, Integer>();
    map.put("startIndex", 0);
    map.put("pageSize", 2);

    List<User> userListById = userMapper.getUserListById(map);
    sqlSession.close();
}

  1. 日志输出

在这里插入图片描述

二、使用注解完成删除操作

  1. Mapper接口中添加注解
public interface UserMapper {
    
    

    @Delete("delete from user where id = #{uid}")
    int deleteUser(@Param("uid") int id);

    /**
     * 1. 方法上的注解还有@Insert()、@Update()两种,分别完成对应的操作
     * 2. 方法中的参数使用@Param注解表示给参数名起别名
     *
     * 注意: (1)参数有多个基本类型和String类型时需要使用@Param注解
     *       (2)参数如果只有一个基本类型时,可以不使用@Param注解,但尽量使用
     *       (3)类类型不需要使用@Param注解
     *
     */

}

  1. 需要在核心配置文件mybatis-config.xml中绑定接口
<mappers>
    <mapper class="com.qizegao.dao.UserMapper"/>
</mappers>

  1. 测试

注意:

public static SqlSession getSqlSession() {
    
    
    //可以在MyBatisUtils工具类中设置sqlSession为自动提交
    return sqlSessionFactory.openSession(true);
}

@Test
public void test01() {
    
    
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    int res = userMapper.deleteUser(3);
    //已经在工具类中设置为自动提交,故此处无需提交事务
    sqlSession.close();
}

  1. 日志输出
    在这里插入图片描述

  2. 其余使用注解的操作与此类似,不再赘述

三、联合查询

有两张表t_key和t_lock,对应关系如下所示:

在这里插入图片描述

1. 级联属性的方式

(1) Key类和Lock类

在这里插入图片描述

(2) KeyMapper接口中声明

public Key getKeyById(Integer id);

(3) KeyMapper.xml中编写

 	<select id="getKeyById" resultMap="mykey">
 		select k.id, k.`keyname`, k.`lockid`, l.`id` lid, l.`lockName` 
		from t_key k
		left join t_lock l on k.`lockid`=l.`id`
		where k.`id`=#{id}
 	</select>

  	<resultMap id="mykey" type="com.qizegao.bean.Key" >
 		<id property="id" column="id"/>
 		<result property="keyName" column="keyname"/>
 		<result property="lock.id" column="lid"/>
 		<result property="lock.lockName" column="lockName"/>
 	</resultMap> 

2. 使用association标签的方式

KeyMapper.xml中编写 (select标签的内容与上述一致)

 	<resultMap id="mykey" type="com.qizegao.bean.Key" >
 		<id property="id" column="id"/>
 		<result property="keyName" column="keyname"/>
 		<!-- 使用association标签表示联合了一个对象 -->
 		<!-- javaType属性指定联合的对象类型 -->
 		<association property="lock" javaType="com.qizegao.bean.Lock">
 			<!-- 定义如何封装lock对象,property属性表示的是lock对象的属性 -->
 			<id property="id" column="lid"/>
 			<result property="lockName" column="lockName"/>
 		</association>
 	</resultMap>

3. 使用collection标签的方式

(1) Key类和Lock类

在这里插入图片描述

(2) LockMapper接口中声明

public Lock getLockById(Integer id);

(3) LockMapper.xml中声明

 	<select id="getLockById" resultMap="mylock">
 		select l.*,k.id kid,k.`keyname`,k.`lockid` 
 		from t_lock l 
		left join t_key k on l.`id`=k.`lockid`
		where l.id=#{id}
 	</select>

 	<resultMap id="mylock" type="com.atguigu.bean.Lock">
 		<id property="id" column="id"/>
 		<result property="lockName" column="lockName"/>
 		<!-- 
 			使用collection标签表示联合了一个集合
 			ofType属性指定集合里面元素的类型
 		-->
 		<collection property="keys" ofType="com.atguigu.bean.Key">
 			<!-- 定义集合中的封装规则,property属性表示的是Key类中的属性 -->
 			<id property="id" column="kid"/>
 			<result property="keyName" column="keyname"/>
 		</collection>
 	</resultMap>

四、分步查询

  1. Key类和Lock类

在这里插入图片描述

  1. KeyMapper接口和LockMapper接口中编写
public Key getKeyByIdSimple(Integer id); //KeyMapper中的方法

public Lock getLockByIdSimple(Integer id); //LockMapper中的方法
  1. KeyMapper.xml和LockMapper.xml中编写
 	<!-- LockMapper.xml中编写 -->
 	<select id="getLockByIdSimple" resultType="com.atguigu.qizegao.Lock">
 		select * from t_lock where id=#{id}
 	</select>

 	<!-- KeyDao.xml中编写 -->
 	<select id="getKeyByIdSimple" resultMap="mykey02">
 		select * from t_key where id=#{id}
 	</select>
 	<resultMap id="mykey02" type="com.qizegao.bean.Key">
 		<id property="id" column="id"/>
 		<result property="keyName" column="keyname"/>
 		<association property="lock" 
 			<!-- 1. select属性执行目标方法对应的sql语句
 				 2. column属性将select查询结果的哪一列封装 				 
 			 -->
 			select="com.qizegao.dao.LockDao.getLockByIdSimple"
 			column="lockid" ></association>
 	</resultMap>

五、动态sql

  1. 创建一张数据库表t_teacher

在这里插入图片描述

  1. 创建Teacher类
public class Teacher {
    
    

	private Integer id;
	private String name;
	private String course;
	private String address;
	private Date birth;
	//以及其余JavaBean结构
	
}
  1. TeacherDao中编写
public List<Teacher> getTeacherByCondition(Teacher teacher);
  1. TeacherDao.xml中编写
	<resultMap id="teacherMap" type="com.qizegao.bean.Teacher">
		<id property="id" column="id" />
		<result property="address" column="address" />
		<result property="birth" column="birth_date" />
		<result property="course" column="class_name" />
		<result property="name" column="teacherName" />
	</resultMap>
	
	<select id="getTeacherByCondition" resultMap="teacherMap">
		
			select * from t_teacher
		
		<!-- trim标签用来截取字符串:
		
				(1) prefix属性为sql整体添加一个前缀,一般设置为where,
				    当没有条件符合where时,会自动去掉where前缀
				    
				(2) prefixOverrides属性去除每个if标签中指定的前缀,一般设置为and
					当某个and后面的条件不满足时,自动去掉and前缀
					
				(3) suffix和suffixOverrides属性使用与上述类似  		
		 -->

		<trim prefix="where" prefixOverrides="and">
		
			<!-- if标签的test属性写判断条件,
			     当满足判断条件时就将if标签体中的sql语句拼接到if标签体外的sql语句上
			     如 "id != null" 表示传入的JavaBean的id属性值不为null时才满足条件
		    -->
		
			<if test="id!=null">
				id > #{id} and
			</if>

			<!-- &amp;表示&,&quot;表示" -->
			<if test="name!=null &amp;&amp; !name.equals(&quot;&quot;)">
				and teacherName like #{name} 
			</if>
			
			<if test="birth!=null">
			    <!-- &lt;表示< -->
				and birth_date &lt; #{birth} 
			</if>
		</trim>
	</select>
  1. 测试类中编写

手动创建一个参数中需要的teacher对象,根据需求调用对象的setter方法,sql语句会根据是 否传入对应的属性值而动态的变化

  1. 注意

去掉trim标签,使用 if标签 可以自动的去除if标签中的前缀and

六、动态sql的其他标签

1. foreach标签

(1) TeacherDao中编写

public List<Teacher> getTeacherByIdIn(@Param("ids")List<Integer> ids);

(2) TeacherDao.xml中编写

	<select id="getTeacherByIdIn" resultMap="teacherMap">
		
		SELECT * FROM t_teacher WHERE id IN
		
		<!-- foreach标签用来遍历集合
				1. collection属性指定要遍历的集合 
				2. item属性为每次遍历出的元素起一个变量名
				3. separator属性定义遍历到的元素的分隔符
				4. open属性定义foreach标签中的sql语句以什么开始
				5. close属性定义foreach标签中的sql语句以什么结束
				6. index属性表示索引:
					(1) 如果遍历的是一个list: 
							index:指定的变量保存了当前索引 
							item:保存当前遍历的元素的值 
					(2) 如果遍历的是一个map: 
							index:指定的变量保存了当前遍历的元素的key 
							item:保存当前遍历的元素的值
		-->
		
		<if test="ids.size >0">
			<foreach collection="ids" item="id_item" separator="," open="("
				close=")">
				#{id_item} <!-- 取出遍历的元素的值 -->
			</foreach>
		</if>
	</select>

2. choose标签

(1) TeacherDao中编写

public List<Teacher> getTeacherByConditionChoose(Teacher teacher);

(2) TeacherDao.xml中编写

	<select id="getTeacherByConditionChoose" resultMap="teacherMap">
		select * from t_teacher
		
		<!-- sql语句不写where,使用where标签 -->
		
		<where> <!-- 相当于在sql语句补了一个where,且自动去除and或or -->

			<!-- choose标签是从上向下判断,
				 一旦满足了when条件,就将when标签中的sql语句添加到原sql语句后面
				 一旦满足了一个when标签就不会去判断其余的when标签,跳出choose标签
			 -->
			
			<choose>
				<when test="id!=null">
					id=#{id}
				</when>
				<when test="name!=null and !name.equals(&quot;&quot;)">
					teacherName=#{name}
				</when>
				<when test="birth!=null">
					birth_date = #{birth}
				</when>
				<otherwise>
					1=1 <!-- 永远为true -->
				</otherwise>
			</choose>
		</where>
	</select>

3. set标签

(1) TeacherDao中编写

public int updateTeacher(Teacher teacher);

(2) TeacherDao.xml中编写

	<update id="updateTeacher">
		UPDATE t_teacher
		
		<!-- 使用set标签代替sql语句中的set
			 可以自动的去掉if标签中sql语句后面多余的逗号
		 -->
		
		<set>
			<if test="name!=null and !name.equals(&quot;&quot;)">
				teacherName=#{name},
			</if>
			<if test="address!=null and !address.equals(&quot;&quot;)">
				address=#{address},
			</if>
			<if test="birth!=null">
				birth_date=#{birth}
			</if>
		</set>
		<where> <!-- where标签代替sql语句手写where -->
			id=#{id}
		</where>
	</update>

猜你喜欢

转载自blog.csdn.net/weixin_49343190/article/details/110390862