MyBatis (2)
MyBatis的使用第一部分,传送地址:MyBatis的使用(1) 初学者必看 基于xml配置的MyBatis MyBatis的生命周期 ResultMap的使用 日志工厂
文章目录
一、使用注解开发
- 注解使用在Mapper接口的方法上,无需再使用UserMapper.xml文件
public interface UserMapper {
@Select("select * from user limit #{startIndex}, #{pageSize}")
List<User> getUserListById(Map<String, Integer> map);
}
- 需要在核心配置文件mybatis-config.xml中绑定接口
<mappers>
<mapper class="com.qizegao.dao.UserMapper"/>
</mappers>
- 测试
@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();
}
- 日志输出
二、使用注解完成删除操作
- 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注解
*
*/
}
- 需要在核心配置文件mybatis-config.xml中绑定接口
<mappers>
<mapper class="com.qizegao.dao.UserMapper"/>
</mappers>
- 测试
注意:
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();
}
-
日志输出
-
其余使用注解的操作与此类似,不再赘述
三、联合查询
有两张表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>
四、分步查询
- Key类和Lock类
- KeyMapper接口和LockMapper接口中编写
public Key getKeyByIdSimple(Integer id); //KeyMapper中的方法
public Lock getLockByIdSimple(Integer id); //LockMapper中的方法
- 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
- 创建一张数据库表t_teacher
- 创建Teacher类
public class Teacher {
private Integer id;
private String name;
private String course;
private String address;
private Date birth;
//以及其余JavaBean结构
}
- TeacherDao中编写
public List<Teacher> getTeacherByCondition(Teacher teacher);
- 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>
<!-- &表示&,"表示" -->
<if test="name!=null && !name.equals("")">
and teacherName like #{name}
</if>
<if test="birth!=null">
<!-- <表示< -->
and birth_date < #{birth}
</if>
</trim>
</select>
- 测试类中编写
手动创建一个参数中需要的teacher对象,根据需求调用对象的setter方法,sql语句会根据是 否传入对应的属性值而动态的变化
- 注意
去掉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("")">
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("")">
teacherName=#{name},
</if>
<if test="address!=null and !address.equals("")">
address=#{address},
</if>
<if test="birth!=null">
birth_date=#{birth}
</if>
</set>
<where> <!-- where标签代替sql语句手写where -->
id=#{id}
</where>
</update>