• MyBatis(中)


    目录

    1、动态sql:

    1、if标签:

    2、where标签:

    3、 trim标签:

    4、set标签:

    5、choose when otherwise:

    6、模糊查询的写法:

     7、foreach标签:

    (1)批量删除:

    (2)批量插入:

    8、include标签:

    2、MyBatis的高级映射:

    1、多对一:

    (1)级联属性映射:

    (2)association:

    (3)分步:

     2、一对多:

    (1)collection标签:

    (2)分步:


    1、动态sql:

    1、if标签:

    mapper接口:

    1. //if 标签 多条件查询
    2. List selectByMultiConditional(@Param("brand") String brand,@Param("guidePrice") Double guidePrice,@Param("carType") String carType);

    mapper映射文件:

    1. <select id="selectByMultiConditional" resultType="Car">
    2. select *
    3. from t_car
    4. where 1=1
    5. <if test="brand !=null and brand!=''">
    6. and brand like "%"#{brand}"%"
    7. if>
    8. <if test="guidePrice !=null and guidePrice!=''">
    9. and guide_price > #{guidePrice}
    10. if>
    11. <if test="carType !=null and carType!=''">
    12. and car_type =#{carType}
    13. if>
    14. select>

     测试类:

    1. /**
    2. * 使用if标签多条件查询
    3. */
    4. @Test
    5. public void test1(){
    6. SqlSession sqlSession = SqlSessionUtil.openSession();
    7. CarMapper mapper = sqlSession.getMapper(CarMapper.class);
    8. List carList = mapper.selectByMultiConditional(null,null,null);//什么参数也没有
    9. carList.forEach(car -> {
    10. System.out.println(car);
    11. });
    12. System.out.println("--------------");
    13. List carList1 = mapper.selectByMultiConditional("保时捷", 100.0, null);//两个参数
    14. carList1.forEach(car -> {
    15. System.out.println(car);
    16. });
    17. System.out.println("--------------");
    18. List carList2 = mapper.selectByMultiConditional("比亚迪", 25.0, "混动");
    19. carList2.forEach(car -> {
    20. System.out.println(car);
    21. });

    2、where标签:

    where标签的作用:让where子句更加动态智能。

    • 所有条件都为空时,where标签保证不会生成where子句。
    • 自动去除某些条件前面多余的and或or。

     mapper接口:

    1. //if 和 where标签一起使用
    2. List selectByMultiConditionalWithWhere(@Param("brand") String brand,@Param("guidePrice") Double guidePrice,@Param("carType") String carType);

    mapper映射文件:

    1. <select id="selectByMultiConditionalWithWhere" resultType="Car">
    2. select *
    3. from t_car
    4. <where>
    5. <if test="brand !=null and brand!=''">
    6. and brand like "%"#{brand}"%"
    7. if>
    8. <if test="guidePrice !=null and guidePrice!=''">
    9. and guide_price > #{guidePrice}
    10. if>
    11. <if test="carType !=null and carType!=''">
    12. and car_type =#{carType}
    13. if>
    14. where>
    15. select>

     测试类:

    1. /**
    2. * 使用if 和 where 标签多条件查询
    3. */
    4. @Test
    5. public void test2(){
    6. SqlSession sqlSession = SqlSessionUtil.openSession();
    7. CarMapper mapper = sqlSession.getMapper(CarMapper.class);
    8. List carList = mapper.selectByMultiConditionalWithWhere(null,null,null);//什么参数也没有
    9. carList.forEach(car -> {
    10. System.out.println(car);
    11. });
    12. System.out.println("--------------");
    13. List carList1 = mapper.selectByMultiConditionalWithWhere("保时捷", 100.0, null);//两个参数
    14. carList1.forEach(car -> {
    15. System.out.println(car);
    16. });
    17. System.out.println("--------------");
    18. List carList2 = mapper.selectByMultiConditionalWithWhere("比亚迪", 25.0, "混动");
    19. carList2.forEach(car -> {
    20. System.out.println(car);
    21. });
    22. System.out.println("--------------");
    23. List carList3 = mapper.selectByMultiConditionalWithWhere(null, 100.0, null);
    24. carList3.forEach(car -> {
    25. System.out.println(car);
    26. });
    27. }

    总结:

            使用where的标签的话可以去where语句的前面的and或者or,但是不可去除条件语句的后面的and或者or 

    3、 trim标签

    trim标签的属性:

    • prefix:在trim标签中的语句前添加内容
    • suffix:在trim标签中的语句后添加内容
    • prefixOverrides:前缀覆盖掉(去掉)
    • suffixOverrides:后缀覆盖掉(去掉)

    mapper接口:

    1. <select id="selectByMultiConditionalWithTrim" resultType="Car">
    2. select *
    3. from t_car
    4. <trim prefix="where" suffixOverrides="or|and">
    5. <if test="brand !=null and brand!=''">
    6. brand like "%"#{brand}"%" and
    7. if>
    8. <if test="guidePrice !=null and guidePrice!=''">
    9. guide_price > #{guidePrice} and
    10. if>
    11. <if test="carType !=null and carType!=''">
    12. car_type =#{carType}
    13. if>
    14. trim>
    15. select>

    测试和接大差不差,就不复制粘贴啦,主要是看Trim标签怎么使用的! 

    4、set标签:

    主要使用在update语句当中,用来生成set关键字,同时去掉最后多余的“,”

    比如我们只更新提交的不为空的字段,如果提交的数据是空或者"",那么这个字段我们将不更新。

     mapper接口:

    1. //set 标签 通常用于更新操作
    2. int updateCarWithSetById(Car car);

    mapper映射文件:

    1. <update id="updateCarWithSetById">
    2. update t_car
    3. <set>
    4. <if test="carNum != null and carNum != ''">car_num = #{carNum},if>
    5. <if test="brand != null and brand != ''">brand = #{brand},if>
    6. <if test="guidePrice != null and guidePrice != ''">guide_price = #{guidePrice},if>
    7. <if test="produceTime != null and produceTime != ''">produce_time = #{produceTime},if>
    8. <if test="carType != null and carType != ''">car_type = #{carType},if>
    9. set>
    10. where
    11. id =#{id}
    12. update>

    测试方法:

    1. //测试 set标签
    2. @Test
    3. public void test5(){
    4. SqlSession sqlSession = SqlSessionUtil.openSession();
    5. CarMapper mapper = sqlSession.getMapper(CarMapper.class);
    6. int count = mapper.updateCarWithSetById(new Car(169L, "凯迪拉克", null, 12.5, null, "燃油"));
    7. System.out.println(count);
    8. sqlSession.commit();
    9. sqlSession.close();
    10. }

    5、choose when otherwise

    语法格式:

    1. <choose>
    2. <when>when>
    3. <when>when>
    4. <when>when>
    5. <otherwise>otherwise>
    6. choose>

    相当于java中的if-else  只有一个分支会被执行!!

    需求:先根据品牌查询,如果没有提供品牌,再根据指导价格查询,如果没有提供指导价格,就根据生产日期查询。

    mapper接口:

    1. //choose when otherwise
    2. /*需求:先根据品牌查询,如果没有提供品牌,再根据指导价格查询,如果没有提供指导价格,就根据生产日期查询。*/
    3. List selectByChoose (@Param("brand") String brand,@Param("guidePrice") Double guidePrice,@Param("produceTime") String produceTime);

    mapper映射文件:

    1. <select id="selectByChoose" resultType="Car">
    2. select *
    3. from t_car
    4. <where>
    5. <choose>
    6. <when test="brand != null and brand != ''">brand = #{brand}when>
    7. <when test="guidePrice != null and guidePrice != ''">guide_price = #{guidePrice}when>
    8. <otherwise>produce_time = #{produceTime}otherwise>
    9. choose>
    10. where>
    11. select>

     测试类:

    1. //测试 choose when otherwise
    2. @Test
    3. public void test6(){
    4. SqlSession sqlSession = SqlSessionUtil.openSession();
    5. CarMapper mapper = sqlSession.getMapper(CarMapper.class);
    6. List carList = mapper.selectByChoose("比亚迪汉", null, "2000-01-02");
    7. carList.forEach(car -> {
    8. System.out.println(car);
    9. });
    10. System.out.println("-------------------");
    11. List carList1 = mapper.selectByChoose(null, 120.0, "2000-01-02");
    12. carList1.forEach(car -> {
    13. System.out.println(car);
    14. });
    15. System.out.println("-------------------");
    16. List carList2 = mapper.selectByChoose(null, null, "2000-01-02");
    17. carList2.forEach(car -> {
    18. System.out.println(car);
    19. });
    20. }

    测试结果:

            这里的sql语句可以很直观的看出来,这个choose的特点就是只有一个条件会被执行,即使其传递的参数也符合要求。

    6、模糊查询的写法:

    1. 方法一:
    2. brand like '%${brand}%'
    3. 方法二:
    4. brand like concat('%',#{brand},'%')
    5. 方式三:
    6. brand like "%"#{brand}"%"

    经常使用方式三!

     7、foreach标签:

    (1)批量删除:

    mapper接口:

    1. //foreach 通过ids来批量删除
    2. int deleteByIdsUseForeach(@Param("ids") Long[] ids);

     mapper映射文件:

    1. <delete id="deleteByIdsUseForeach">
    2. delete
    3. from t_car
    4. where id in (
    5. <foreach collection="ids" item="id" separator="," >
    6. #{id}
    7. foreach>
    8. )
    9. delete>

    小括号也可以不写 就是 in(....)

    1. <delete id="deleteByIdsUseForeach">
    2. delete
    3. from t_car
    4. where id in
    5. <foreach collection="ids" item="id" separator="," open="(" close=")">
    6. #{id}
    7. foreach>
    8. delete>

     上面是使用in的方式来实现的批量删除的操作,那么如果是实现的是or的关键字的话,那么sql的语句可以这样写:

    1. <delete id="deleteBatchByForeach2">
    2. delete from t_car where
    3. <foreach collection="ids" item="id" separator="or">
    4. id = #{id}
    5. foreach>
    6. delete>

    测试类:

    1. //测试批量删除
    2. @Test
    3. public void test7(){
    4. SqlSession sqlSession = SqlSessionUtil.openSession();
    5. CarMapper mapper = sqlSession.getMapper(CarMapper.class);
    6. Long[] ids ={198L,199L,200L};
    7. int count = mapper.deleteByIdsUseForeach(ids);
    8. System.out.println(count);
    9. sqlSession.commit();
    10. sqlSession.close();
    11. }
    (2)批量插入:

    mapper接口:

    1. //foreach 实现批量插入
    2. int insertBatchByForeach(@Param("carList") List carList);

    mapper映射文件:

    1. "insertBatchByForeach">
    2. insert into t_car values
    3. "carList" item="car" separator=",">
    4. (null,#{car.carNum},#{car.brand},#{car.guidePrice},#{car.produceTime},#{car.carType})

    测试类:

    1. //批量插入
    2. @Test
    3. public void test8() {
    4. SqlSession sqlSession = SqlSessionUtil.openSession();
    5. CarMapper mapper = sqlSession.getMapper(CarMapper.class);
    6. Car car1=new Car(null,"雷克萨斯","1334",56.0,"2015-7-25","燃油");
    7. Car car2=new Car(null,"阿斯顿·马丁DBS","6989",400.5,"2022-7-1","混动");
    8. Car car3=new Car(null,"迈凯伦GT","7997",123.2,"2019-10-25","燃油");
    9. List carList=new ArrayList<>();
    10. Collections.addAll(carList,car1,car2,car3);
    11. int count = mapper.insertBatchByForeach(carList);
    12. System.out.println(count);
    13. sqlSession.commit();
    14. sqlSession.close();
    15. }

    8、include标签:

    sql标签用来声明sql片段

    include标签用来将声明的sql片段包含到某个sql语句当中

    作用:代码复用。易维护。

    1. <sql id="carCols">id,car_num carNum,brand,guide_price guidePrice,produce_time produceTime,car_type carTypesql>
    2. <select id="selectAllRetMap" resultType="map">
    3. select <include refid="carCols"/> from t_car
    4. select>
    5. <select id="selectAllRetListMap" resultType="map">
    6. select <include refid="carCols"/> carType from t_car
    7. select>
    8. <select id="selectByIdRetMap" resultType="map">
    9. select <include refid="carCols"/> from t_car where id = #{id}
    10. select>

    2、MyBatis的高级映射:

    1、多对一:

    (1)级联属性映射:

    mapper接口:

    1. //根据sid获取去学生对象,同时获取学生关联的班级信息
    2. Student selectBySid(Integer sid);

    mapper映射文件:

    1. <resultMap id="studentResultMap" type="Student">
    2. <id property="sid" column="sid">id>
    3. <result property="sname" column="sname">result>
    4. <result property="clazz.cid" column="cid">result>
    5. <result property="clazz.cname" column="cname">result>
    6. resultMap>
    7. <select id="selectBySid" resultMap="studentResultMap">
    8. select s.sid, s.sname, c.cid, c.cname
    9. from t_stu as s
    10. left join t_clazz as c on s.cid = c.cid
    11. where s.sid = #{sid}
    12. select>

    测试:

    1. //多对一 级联属性映射
    2. @Test
    3. public void test1(){
    4. SqlSession sqlSession = SqlSessionUtil.openSession();
    5. StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    6. Student student = mapper.selectBySid(100);
    7. System.out.println(student);
    8. }
    (2)association:

     mapper接口:

    1. //association标签
    2. Student selectBySidAssociation(Integer sid);

    mapper映射文件:

    1. <resultMap id="studentResultMapAssociation" type="Student">
    2. <id property="sid" column="sid">id>
    3. <result property="sname" column="sname">result>
    4. <association property="clazz" javaType="Clazz">
    5. <id property="cid" column="cid">id>
    6. <result property="cname" column="cname">result>
    7. association>
    8. resultMap>
    9. <select id="selectBySidAssociation" resultMap="studentResultMapAssociation">
    10. select s.sid, s.sname, c.cid, c.cname
    11. from t_stu as s
    12. left join t_clazz as c on s.cid = c.cid
    13. where s.sid = #{sid}
    14. select>

    测试:

    1. //多对一 使用association标签
    2. @Test
    3. public void test2(){
    4. SqlSession sqlSession = SqlSessionUtil.openSession();
    5. StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    6. Student student = mapper.selectBySidAssociation(100);
    7. System.out.println(student);
    8. }
    (3)分步:

    mapper接口   第一步  查cid

    1. //分步查询的第一步 通过sid查出来学生信息
    2. Student selectBySidOne(Integer sid);

     mapper映射文件:

    1. <resultMap id="selectByIdOne" type="student">
    2. <id property="sid" column="sid">id>
    3. <result property="sname" column="sname">result>
    4. <association property="clazz" select="com.songzhishu.mybatis.mapper.ClazzMapper.selectByCidTwo" column="cid">
    5. association>
    6. resultMap>
    7. <select id="selectBySidOne" resultMap="selectByIdOne">
    8. select sid,sname,cid
    9. from t_stu
    10. where sid = #{sid}
    11. select>

    mapper接口:  第二步 查信息

    1. //分步查询 根据班级id查询班级信息
    2. Clazz selectByCidTwo(Integer cid);

    mapper映射问价:

    1. <select id="selectByCidTwo" resultType="Clazz">
    2. select *
    3. from t_clazz
    4. where cid = #{cid}
    5. select>

     测试:

    1. //多对一 分步查询
    2. @Test
    3. public void test3(){
    4. SqlSession sqlSession = SqlSessionUtil.openSession();
    5. StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    6. Student student = mapper.selectBySidOne(101);
    7. System.out.println(student);
    8. }

            首先说一下,就是复用性好是什么意思,这里讲的是我现在的需求是根据学生的sid来出查询出来学生的班级信息,然后就编写了两个sql语句,一个是根据sid查学生的信息,然后另外一个是根据cid查询出来班级的信息,这是两个sql语句,分别摘开都可以使用的,这就是可以复用。

            然后就是我们现在的需求是有限定的条件,通过sid确定学生,然后根据学生确定班级,但是我不是每一次都要想查询班级的信息呀,那怎么办,这就要提出来延迟加载。

            他的核心就是用的时候使用select语句,不用的时候不使用,这样可以减少查询的条件提高性能!开启延迟加载的方式也很简单 ,再Assoication标签内部的属性中加上,fetchType属性,在默认的情况先,懒加载是关闭的

    1. <association property="clazz" select="com.songzhishu.mybatis.mapper.ClazzMapper.selectByCidTwo" column="cid"
    2. fetchType="lazy">

    测试:

    1. @Test
    2. public void test3(){
    3. SqlSession sqlSession = SqlSessionUtil.openSession();
    4. StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    5. Student student = mapper.selectBySidOne(101);
    6. System.out.println(student.getSname());//只要名字 //只执行一条sql
    7. System.out.println(student); //要全部的信息 //执行两个
    8. }

     这里我将测试的语句都写出来啦,测试后的时候可以注释掉其中一个!

    上面的只是针对这个一个Association标签内部的分步开启延迟加载,如果想在全局开启的话,可以在核心配置文件中设置一下字段:

    1. <setting name="lazyLoadingEnabled" value="true"/>

            这样全局的分步都可以使用延迟加载的方式,需要的时候才使用分步,不需要的时候就采用延迟加载从而达到性能的优化,如果配置后针对某一部分的分部的操作不需要使用延迟加载的话,也就可以在Association字段中设置:

    fetchType="eager"

     2、一对多:

    (1)collection标签:

    mapper接口 Clazz

    1. //根据班级编号查询班级信息
    2. Clazz selectByCid(Integer cid);

     mapper映射文件:

    1. <resultMap id="selectByCidMap" type="Clazz">
    2. <id property="cid" column="cid">id>
    3. <result property="cname" column="canme">result>
    4. <collection property="studentList" ofType="student">
    5. <id property="sid" column="sid">id>
    6. <result property="sname" column="sname">result>
    7. collection>
    8. resultMap>
    9. <select id="selectByCid" resultMap="selectByCidMap">
    10. select c.cid,c.cname,s.sid, s.sname
    11. from t_clazz as c
    12. left join t_stu as s on c.cid = s.cid
    13. where c.cid = #{cid}
    14. select>

    测试:

    1. //一对多
    2. @Test
    3. public void test4(){
    4. SqlSession sqlSession = SqlSessionUtil.openSession();
    5. ClazzMapper mapper = sqlSession.getMapper(ClazzMapper.class);
    6. Clazz clazz = mapper.selectByCid(1000);
    7. System.out.println(clazz);
    8. }
    (2)分步:

    mapper接口:  cLazz 第一步

    1. //分步查询 跟据编号获取班级信息
    2. Clazz selectByCidOne(Integer cid);

    mapper映射文件:  一对多

    1. <resultMap id="selectByCidOneMap" type="clazz">
    2. <id property="cid" column="cid">id>
    3. <result property="cname" column="cname">result>
    4. <collection property="studentList" ofType="student" select="com.songzhishu.mybatis.mapper.StudentMapper.selectByCidTwo" column="cid">
    5. collection>
    6. resultMap>
    7. <select id="selectByCidOne" resultMap="selectByCidOneMap">
    8. select cid,cname
    9. from t_clazz
    10. where cid = #{cid}
    11. select>

    mapper接口 student

    1. //一对多 第二步 根据cid查询 学生信息
    2. List selectByCidTwo(Integer cid);

    mapper映射文件:

    测试类

    1. //一对多 分步
    2. @Test
    3. public void test5(){
    4. SqlSession sqlSession = SqlSessionUtil.openSession();
    5. ClazzMapper mapper = sqlSession.getMapper(ClazzMapper.class);
    6. Clazz clazz = mapper.selectByCidOne(1001);
    7. System.out.println(clazz);
    8. }

  • 相关阅读:
    项目管理软件dhtmlxGantt配置教程(五):如何对列进行排序
    企业现代化管理模式,数据指标体系应该如何构建?
    R语言选择data.table数据中的多个数据列并重命名筛选的数据列
    探针台选型应该注意哪些事项
    Linux 入门篇
    Go采集代理框架
    入门深度学习—从配置python到网络模型
    通过位运算,实现单字段标识多个状态位
    大数据知识面试题-Kafka(2022版)
    校正叠加(calibrated stacking)方法—技术
  • 原文地址:https://blog.csdn.net/keleID/article/details/133817383