Hello 大家好我是橙子同学,今天分享注解Mybatis注解开发+动态sql
目录
每文一铺垫(今天有小插曲哦)
注解开发
添加 @Insert
删除 @Delete
查询 @Select
修改 @Update
实现结果集封装 @Result
实现一对一结果集封装 @one
实现多对多结果集封装 @Many
动态SQL
标签 <set> <if>
标签<where>
标签<foreach>
标签<choose>
标签 <when>
收尾
每文一铺垫(今天有小插曲哦)
先说一个小插曲,因为 橙子同学确实是快要找实习了,这几天宅在家就想着试试水,毕竟没接触过,也不知道这个圈子的包容性强不强,今天早晨可能没太睡醒,一冲动就给很多公司投递了简历(包括阿里和字节),因为有一个“一键投递”功能,所以我就点了,大概中午的时候接到了一个hr的电话,刚接到电话感觉这个人不太靠谱,因为他说话嗯啊的,还在打哈欠,每问一个问题之前要想好久,说好几个“就是……就是……”,感觉他比我紧张,传达给我的信息就是想要我独立开发一个小程序,前端+后端都是我完成,我的印象里这个东西不应该是分工合作的么,做前端的做页面,做后端的搞功能,这要是一个人做不会累死么(可能是我了解的不多),经过几分钟的聊天之后,他加了我的微信,然后发给了几张拼多多首页,然后一个电话过来,问我这个页面用代码怎么写,此时此刻小橙的内心已经很激动了,因为第一次遇见这样的,好像上来就面试一样,反正我就把我脑子里的东西尽量表达出来,最后的最后他说“好的,了解了,再见” 。不出意外——凉凉了。但是这次给我的感觉就是 hr能不能 睡醒了再沟通,都表达不清楚自己想要的是什么;另外我的技术有待提升,这个圈子是不会给菜鸟机会的,难过的一天……
好啦步入主题:注解开发+动态SQL
注解开发
在之前的Mybatis基础开发操作的时候,我们的sql语句是写在映射文件里的,映射文件提供了“增、删、改、查”标签,然后将映射文件与接口连接,在测试类中调用接口中的方法,今天介绍的注解开发省去了在映射文件中的操作,让我们的代码更加清晰而且简洁。
添加 @Insert
直接在接口“脑袋上”添加注解@Insert,把SQL语句写在后面
补充:@Options 在添加属性的同时获取 属性值
//添加
@Insert("insert into tb_person values(null,#{name},#{age},#{sex})")
@Options(useGeneratedKeys = true,keyProperty = "id",keyColumn = "id")
void addPerson(Person person);
在测试类里测试一下
@Before 是指测试代码执行前先执行的内容
每个测试都需要读取配置文件;获取sqlSession工厂对象;创建dao接口的代理对象;所以我们把他们抽出来放在@Before里,就不需要每次都写啦~
@After 测试代码执行后,执行的内容
关闭操作 释放资源
public class MyTest {
private SqlSession sqlSession ;
private PersonMapper mapper;
@Before
public void before(){
sqlSession = MyBatisUtils.getSqlSession();
mapper = sqlSession.getMapper(PersonMapper.class);
}
@After
public void after(){
sqlSession.close();
}
@Test
public void test1(){
Person person = new Person();
person.setName("李易峰");
person.setAge(23);
person.setSex("男");
mapper.addPerson(person);
System.out.println(person);
}
}
“李易峰”就添加成功啦
删除 @Delete
//删除
@Delete("delete from tb_person where id=#{id}")
void deleteById(Integer id);
查询 @Select
//查询
@Select("select * from tb_person where id=#{id}")
Person findById(Integer id);
修改 @Update
//修改
@Update("update tb_person set name=#{name},age=#{age},sex=#{sex} where id=#{id}")
void updatePerson(Person person);
实现结果集封装 @Result
一对一关联查询
接口
public interface IdCardMapper {
@Select("select * from idcard where id=#{id}")
public IdCard findById(Integer id);
}
实现一对一结果集封装 @one
@Results(id = "personAndCard",value = {
@Result(id = true,property = "id",column = "id"),
@Result(property = "name",column = "name"),
@Result(property = "age",column = "age"),
@Result(property = "idCard",column = "card_id",one = @One(select = "com.mapper.IdCardMapper.findById"))
})
@Select("select * from person where id=#{id}")
Person findById(Integer id);
实现多对多结果集封装 @Many
接口
public interface OrderMapper {
@Select("select * from tb_order where user_id=#{uid}")
List<Order> findByUserId(Integer uid);
}
public interface UserMapper {
@Results(id = "userAndOrder",value = {
@Result(id = true,property = "id",column = "t_id"),
@Result(property = "name",column = "t_name"),
@Result(property = "age",column = "t_age"),
@Result(property = "orders",column = "t_id",
many = @Many(select = "com.mapper.OrderMapper.findByUserId"))
})
@Select("select * from tb_user where t_id=#{id}")
User findById(Integer id);
}
增删改查 关联查询 都实现啦,但是有没有注意到,有的部分很麻烦,比如在增加、修改,需要更新数据的时候,需要把所有的字段都修改,很不方便,橙子只想修改年龄,但是“姓名”“性别”“ID”……都需要传进来修改,很麻烦,字段少的情况下,可以,忍忍就过去了,十几二十几个字段那岂不是太头痛了,所以接下来介绍解决这个问题的方法:动态SQL
动态SQL
动态sql的理念很简单,“哪里不会点哪里~”简单来说就是需要哪个字段 诶,咱就去拼接哪个字段,不用的就不管啦,简单介绍一下动态sql标签。
标签<set> <if>
大家对于<if>标签肯定不陌生,很容易理解,条件判断嘛,<set> 修改 举个栗子:
如果name不为null ,筛选用户名 ;
如果gender不为null ,筛选性别 ;
如果age不为null ,筛选年龄;
如果……
标签<where>
结合之前的sql思考,可知这个标签,就是拼接筛选条件,举个栗子:
如果name不为null ,筛选用户名 ;
如果gender不为null ,筛选性别 ;
如果age不为null ,筛选年龄;
如果……
标签<foreach
>
与JavaScript中的foreach类似,进行遍历操作
属性如下
collection:代表要遍历的集合元素,注意编写时不要写#{}
open:代表语句的开始部分
close:代表结束部分
item:代表遍历集合的每个元素,生成的变量名
sperator:代表分隔符
举个栗子:
<!--根据多个id查询用户信息-->
<select id="findUsersByIds" resultType="user" >
SELECT *from USER
<where>
<foreach collection="array" open="and id in (" close=")" separator="," item="uid">
#{uid}
</foreach>
</where>
</select>
标签<choose>
此标签解释来源:https://www.jianshu.com/p/9f97543b6b2e
有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。而使用if标签时,只要test中的表达式为 true,就会执行 if 标签中的条件。MyBatis 提供了 choose 元素。if标签是与(and)的关系,而 choose 是或(or)的关系。
choose标签是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的sql。类似于Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。
标签<when>
类似于 switch ,按照已经筛选好的条件,当 when 中有条件满足的时候,就会执行 choose,当所有的条件都不满足的时候就执行 otherwise
注解中可以使用动态sql么?可以,当然可以。
用添加字段 举个栗子
@Update("<script>" +
"update tb_person " +
"<set>" +
"<if test='name!=null'>" +
"name=#{name}," +
"</if>" +
"<if test='age!=null'>" +
"age=#{age}," +
"</if>" +
"<if test='sex!=null'>" +
"sex=#{sex}" +
"</if>" +
"</set>" +
"where id=#{id}" +
"</script>")
void updatePerson2(Person person);
哇,头痛,没有提示,简直是手撕sql啊,但凡有一个符号写错了,直接报错,还找不到,还有比这更闹心的么?橙子要说了,还不如用映射文件呢,对啊,那么这个地方,记笔记,可以使用注解+映射文件结合。
在映射文件里面写动态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文件所在路径 -->
<mapper namespace="com.mapper.PersonMapper">
<update id="updatePerson3" parameterType="Person" >
update tb_person
<set>
<if test="name!=null">
name=#{name},
</if>
<if test="age!=null">
age=#{age},
</if>
<if test="sex!=null">
sex=#{sex}
</if>
</set>
where id=#{id}
</update>
</mapper>
接口里和以前一样
void updatePerson3(Person person);
收尾
其实对于动态SQL中的有些标签,我理解的也有些模糊,所以可能有的地方写的不是太清楚,欢迎大家指正,包括在写的过程中我也去查询了其他人是怎么写的,但是主要还是来源于上课老师大大传授给我的,有部分内容也引用了老师的, 跪求我的主讲老师不会刷到我的博客哈哈哈哈,
上期说这期还有一级缓存,二级缓存和和延迟加载, 写完这些我发现太多了,那就继续再往后推一推吧~~
趁着小橙还没火,还不赶紧关注 吼吼吼吼~~