范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

MyBatis系列教程四一文读懂MyBatis动态SQL使用

  如果使用传统的JDBC编程,很多时候需要根据具体情况拼接SQL语句,这是一件很痛苦的事情。Mybatis为开发者提供了动态SQL语句的组装能力,并且如此强大的功能只有几个元素就可以完成,十分简单明了。大量的判断都可以在Mybatis的映射XML中完成。大大减少了编码的工作量,这也体现了Mybatis的灵活性和可维护性。下面首先了解一下Mybatis中常用的动态SQL元素。
  元素
  作用
  备注
  if
  判断语句
  单条件分支判断
  choose(when、otherwise)
  相当于Java中的case when
  多条件分支判断
  trim(where、set)
  辅助元素
  用于处理SQL拼装
  foreach
  循环语句
  在in语句等列举条件中常用
  下面,就将上述元素进行深入讨论。 4.1 if元素
  if元素是日常开发中较为常用的判断语句,相当于Java中的if语句,它常常与test属性联合使用。   if元素使用方法比较简单,以第3章中的数据库为例,根据学生姓名进行模糊查询。  映射器中代码如下: 
  接口中定义方法:  public interface StudentMapper {      List findStudentByStudentName(String studentName);  }
  在示例代码中使用了if元素,if元素的test属性中判断studentName是否有值,如果有值则在已有SQL语句后拼接if元素中的语句,如果没有值则不拼接,下面首先传递studentName值做测试,代码如下:  public class Test {      public static void main(String[] args) throws IOException {          final Logger logger = Logger.getLogger(Test.class);          InputStream is = Resources.getResourceAsStream("mybatis-config.xml");            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);          SqlSession session = sqlSessionFactory.openSession();          StudentMapper mapper = session.getMapper(StudentMapper.class);          //1.          List list = mapper.findStudentByStudentName("j");          list.forEach(e->logger.info(e));      }  }
  运行结果如下:
  可以看出,当studentName有值时拼接了SQL语句。  在上例代码中注释1处的方法调用中传入null,再次测试,运行结果如下:
  从结果中可以看出SQL语句并没有拼接if元素中的语句。4.2 choose、when、otherwise元素
  在上一小节中的if元素相当于Java当中的if分支结构,是一种非此即彼的关系,但是在很多时候开发者所面对的不一定是非此即彼的情形,可能有更多的选择或者分支,此时虽说if可以满足需要,但是代码显得很蹩脚。因此Mybatis为开发者提供了类似于多分支的结构,并且这种结构在做根据条件搜索时显得尤为方便,避免了繁复的代码和判断。例如:根据学生姓名或者年龄或者性别检索数据。   在映射器中配置select元素: 
  Mybatis会根据参数的设置进行判断来动态组装SQL,以满足不同的业务需求。   接口中定义方法: public interface StudentMapper {      List searchStudent(Student student);  }
  新建测试类代码如下:  public class Test {      public static void main(String[] args) throws IOException {          final Logger logger = Logger.getLogger(Test.class);          InputStream is = Resources.getResourceAsStream("mybatis-config.xml");            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);          SqlSession session = sqlSessionFactory.openSession();          StudentMapper mapper = session.getMapper(StudentMapper.class);            Student student = new Student();          student.setStudentName("Jack");            List list = mapper.searchStudent(student);          list.forEach(e->logger.info(e));      }  }
  运行结果如下图:
  4.3 where、trim、set元素4.3.1 where元素
  在上面的代码中,每条SQL语句中都添加了一个1=1这个条件,这是因为如果不添加这个条件上一小节中的SQL语句可能会下面这样错误的SQL语句:  SELECT STUDENT_ID,STUDENT_NAME,STUDENT_AGE,STUDENT_GENDER FROM STUDENT WHERE  AND STUDENT_NAME = ?
  但是加上这个莫名其妙的条件又显得很奇怪,在这里就可以使用where元素以达到逾期的效果。对上一小节中的SQL语句进行修改,去掉1=1,并且将choose...when修改为where和if,代码如下:  
  当where元素中的条件只要有一个成立时,会在已有SQL语句后拼接where以及成立的条件,如果没有条件成立,则不会拼接SQL语句,也不会拼接where,下面的示例将演示这种情况: public class Test {     public static void main(String[] args) throws IOException {         final Logger logger = Logger.getLogger(Test.class);         InputStream is = Resources.getResourceAsStream("mybatis-config.xml");          SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);         SqlSession session = sqlSessionFactory.openSession();         StudentMapper mapper = session.getMapper(StudentMapper.class);          List list = mapper.searchStudent(null);         list.forEach(e->logger.info(e));     } }
  运行结果如下:
  在测试类中方法内传入了null,所有的参数都为null,不满足where元素中if元素的条件,因此Mybatis并没有拼接where及条件。4.3.2 trim元素
  有时候需要去掉一些特殊的SQL语法,比如常见的and、or。使用trim元素就可以达到这种效果。 
  注意上面的SQL语句,如果studentName不等于null时,此时的SQL语句会变成: SELECT STUDENT_ID,STUDENT_NAME,STUDENT_AGE,STUDENT_GENDER FROM STUDENT AND STUDENT_NAME = #{studentName}
  这条SQL语句会产生语法错误,trim元素此时就要发挥作用了,会将and替换为where,也就是说trim元素的作用就是将prefixOverrides中配置的值替换为prefix中的值。 4.3.3 set元素
  在日常开发中更新操作出现的也比较频繁,但是在更新操作中通常会只更新几个字段,而不是全部更新,如果将所有的字段都发送给数据库,这样就会带来不必要的内存和宽带开销,set元素就可以解决这种问题,例如更新学生信息。      UPDATE STUDENT                           STUDENT_NAME = #{studentName},                               STUDENT_AGE = #{studentAge},                               STUDENT_GENDER = #{studentGender}                   WHERE STUDENT_ID = #{studentId} 
  接口中定义方法: public interface StudentMapper {     int updateStudent(Student student); }
  新建测试类: public class Test {     public static void main(String[] args) throws IOException {         final Logger logger = Logger.getLogger(Test.class);         InputStream is = Resources.getResourceAsStream("mybatis-config.xml");          SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);         SqlSession session = sqlSessionFactory.openSession();         StudentMapper mapper = session.getMapper(StudentMapper.class);          Student student = new Student();         student.setStudentId(7);         student.setStudentAge(20);          mapper.updateStudent(student);         session.commit();     } }
  运行结果如下:
  因为传入的参数中只有studentAge,因此Mybatis在拼接SQL语句时只拼接了满足studentAge的条件。4.4 foreach元素
  foreach元素是一个循环语句,作用是遍历集合,它能够很好的支持数组和List、Set接口的集合,对此提供遍历功能。例如删除多条数据,就可以使用foreach元素。      DELETE FROM STUDENT WHERE STUDENT_ID IN              #{id}      collection:配置的是传递进来的参数名称,可以是一个数组或者List、set等集合 item:配置的是循环中的元素,可以理解为数组或者集合中的元素的名称 open和close:配置的是以什么符号将这些集合元素包装起来 separator:是各个元素的分隔符
  接口中定义方法: public interface StudentMapper {     int batchDeleteStudent(List list); }
  新建测试类: public class Test {     public static void main(String[] args) throws IOException {         final Logger logger = Logger.getLogger(Test.class);         InputStream is = Resources.getResourceAsStream("mybatis-config.xml");          SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);         SqlSession session = sqlSessionFactory.openSession();         StudentMapper mapper = session.getMapper(StudentMapper.class);          List list = new ArrayList<>();         list.add(1);         list.add(2);          mapper.batchDeleteStudent(list);         session.commit();     } }
  运行结果如下:
  4.5 Mybaits分页4.5.1 RowBounds分页
  Mybatis具有分页功能,其为开发者提供了一个类RowBounds,开发者可以使用RowBounds分页,但是RowBounds分页有一个很重要的缺陷,就是会将所有的数据查询出来后根据从第几条到第几条取出数据返回,当数据量比较小时,这么做没有任何问题,但是当数据量大时,这么做无疑对数据库造成了很大的负担。   RowBounds主要定义了两个参数,offset和limit,offset代表从第几行开始读取数据,limit则是限制返回的记录数。在默认情况下offset设置为0,而limit这是Java所允许的最大整数(2147483647)。  下面通过示例学习RowBounds的用法:
  在接口中定义方法: public interface StudentMapper {     List findStudentByPage(RowBounds rowBounds); }
  新建测试类: public class Test {     public static void main(String[] args) throws IOException {         final Logger logger = Logger.getLogger(Test.class);         InputStream is = Resources.getResourceAsStream("mybatis-config.xml");          SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);         SqlSession session = sqlSessionFactory.openSession();         StudentMapper mapper = session.getMapper(StudentMapper.class); 		//1.         List list = mapper.findStudentByPage(new RowBounds(0,5));         list.forEach(e->logger.info(e));     } }
  在代码中注释1处,调用方法是传入RowBounds对象。即可完成分页。   运行结果如下:
  从结果中可以看出使用RowBounds分页时,会将所有的数据都查询出来,然后从数据中截取目标数据,也就是通常所说的逻辑分页。4.5.2 插件分页
  基于RowBounds分页存在一定缺陷,通常会推荐使用自定义插件分页,并且又第三方提供了性能不错的分页插件PageHelper,下面就改插件做简单示范:   首先,在pom.xml中添加依赖     com.github.pagehelper     pagehelper     最新版本 
  在Mybatis全局文件中进行配置:            
  由于Mybatis的插件是基于代理拦截实现,所以继续使用上例中的接口及测试类,插件会自动帮助开发者在SQL中拼接limit关键字。运行结果如下:
  关于该插件的详细用法,可前往PageHelper插件官网进行查阅。

在那段最黑暗的日子里,真的需要自己拉自己一把有没有人跟我一样,情绪低落的时候,谁也不想联系,独自一人躺在床上,不停的刷着快手,感动着别人的故事,想想自己的经历,然后默默的流下眼泪,那种躺在床上,眼泪划过鼻梁,流进另一只眼睛,一个人对你动情后,会刻意回避这些问题在茫茫人生中,爱情匆匆而来,猝不及防的给人带来惊喜,让人深信爱情就是这个世界上最伟大的东西,能够跨越所有的偏见拥抱你,让你看见不一样的世界。林徽因说每个人的人生都是旅程,只是所走的苦难让你我成长如果可以任由个性和选择,没有人愿意选择人生的苦难与阴暗。但世界终究会有阴晴圆缺,人生也总会有许多爱恨情仇,在生活的岁月里既有阳光,有时候也会阴雨满布,人生的无常才是生命当中最大的生国考中这4个部门最难进,没有十足把握要谨慎报名,别选错了一度的国考在年尾的时候进行,很多人在年初都开始准备,原因就在于这场考试的特殊性。国考设置的岗位相对应来说都是比较重要的,所以考试的难度很高。想要在我国当上公务员,必须通过参加国考省无惧调整!北上资金调仓名单出炉,10股获聪明资金悄然增持市场的聪明资金在A股市场,得益于陆港通互通机制的开通,大陆与香港资本市场双向开放的交易通道也随着打开,从香港交易所借道流入A股的资金,一般也称之为北上资金。基于A股核心资产在估值和分工明确,得州负责冲击美国副总统官邸,佛州负责把奥巴马拖下水前段时间,美国是民主党人的主场,一直在打压共和党人,同时追究特朗普的刑事责任,美国共和党人则是勉强防守。不过现在情况有所反转,因为南部的两大红州一出手就招招见血。就像得州,就用大巴李克农情报线被打马赛克谍战剧信仰上映遥遥无期今年7月,网络上一度传出东方卫视将于7月20日播出年代谍战剧信仰,一时间引来谍战迷们的热议。然而,到了7月20日却未见播出。接着有貌似权威渠道消息称真正播出时间是7月21日,结果7张怡宁抱儿庆生,嫁相差20岁富豪老公嫁对了,大魔王变身温柔妈能看出来这张照片中抱孩子的温柔女人是谁么?是的,张怡宁,号称乒乓球界的大魔王张怡宁。虽说还是以前干练的短发,但是周身多了些许的温柔,真是一时间没有让小编认出来!照片中的张怡宁画着淡温柔且坚定,多半是内心强大的人文花舍一个人真正的强大,是内心强大。作家冯唐曾说每个牛人,都有一个笃定的核,这样在宇宙间才不易被风吹散。笃定的核,便是强大的内心。有人因为一点意外慌不择路,有人因为一点困难倒地不起非洲最美丽的国度,街头都是漂亮的异域美女,甘蔗种植也很出名一国一品走近非洲在非洲有一个特别的国度,和许多人脑海中对整个非洲大陆的认识有很大的区别。在这里看到的人不仅仅只有黑色皮肤,而且这里有很好的治安条件,有全世界最美的海岛风光,境内风景物理学上一个美丽的错误,有时候甚至比真理更难得19世纪末20世纪初,人类物理学不断取得突破,而这一切几乎都离不开对光的探索。麦克斯韦方程组告诉我们,光以波的形式传播,速度为每秒30万公里。但在麦克斯韦方程组推导出来的光的计算公
反复流产元凶是它!一根丝带守住好孕大门红网时刻新闻通讯员何为整理报道怀胎十月辛苦且漫长,但有些孕妈到了孕中晚期,却在没有征兆的情况下发生流产或早产,并且在找不到原因的情况下反复如此。一次次满怀憧憬,却一次次希望落空,自童心童语分享玛利亚蒙台梭利人物生平以下内容来自网络,分享给大家,如有侵权,请私信小编删除。玛利娅蒙台梭利博士是教育史上一位杰出的幼儿教育思想家和改革家意大利历史上第一位学医的女性和第一位女医学博士。1870年8月3家庭教育专家提醒父母教育孩子,抓好这三点,教一次管一生你知道吗?孩子不听话,是因为家长不会说话。孩子叛逆的对象不是家长,而是家长错误的管教方式。不管你承不承认,孩子身上的所有问题,根源都在家长身上。父母想教育孩子,一定要先教育好自己。养生断食9天,血液指标的变化断食有多大的风险昨天分享断食9天的过程中,人体成分的变化。主要是蛋白质和脂肪成分的变化情况。开始后的第3天上午空腹测人体成分,主要消耗的是蛋白质,占比90以上。脂肪只消耗了不到10。3天之后第6天给婴幼儿穿上高跟鞋?家长们为给娃拍照,拼过头了现代快报讯(记者马壮壮见习记者孙苏皖)说到小孩子穿的鞋,很多人第一时间会想到的应该是柔软舒适。不过近日,社交平台上有不少父母晒出自家宝宝穿婴幼儿高跟鞋的照片,引起了网友的关注。有些4岁男孩确诊恶性肿瘤,提醒爸妈孩子出现这些症状尽早就医洗澡这个日常活动,有的孩子很喜欢,但有的孩子对此却很抗拒。4岁的浩浩就属于喜欢洗澡的那种小孩,在给浩浩洗澡时,浩浩妈妈会习惯性的陪同并和浩浩一起玩耍。有一天在洗澡过程中妈妈突然摸到vivoXFold的屏幕如何?折叠无忧,显示解锁均出色当前很多折叠屏手机都有两块屏幕,因此想要给用户带来足够好的屏幕体验,那么就要同时兼顾到两块屏幕才行。vivo推出的全新折叠屏旗舰vivoXFold就搭载了顶级屏幕技术,屏幕材质方面全球首款Web3手机METAVERTU正式发布已向苹果宣战近日,据手机中国了解,在伦敦发布会上,欧洲奢侈品手机品牌VERTU正式发布旗下新品METAVERTU,这也是全球首款Web3手机,为了致敬老东家诺基亚科技以人为本的准则。METAV从5799降到2585元的HUAWEIMate30Pro性价比怎么样?HUAWEIMate30Pro2019年9月发布的一款5G手机,发布是5799降到现在的2585元(8128GB),那这款手机性价比怎么样?现在还值得购买吗?手机屏幕这款手机的屏幕比尔盖茨没有说错,打压只会加快中国成长,好消息接连不断中国人不但不比西方人差,甚至更聪明!比尔盖茨曾在接受媒体采访时表示在大多数西方人的眼里,也包括我在内,认为中国人不懂创新,只知道抄袭花高价引进一些不断前沿的高端技术,但现在我发现,抬腕就能打车?华为Petal出行手表打车即将上线智能手表这个品类的产品,在最初上市时,业界对它的定义,是智能手机屏幕的延伸。显然,这种模糊的产品定义,并不能让智能手表取得成功。后续,手机厂商将智能手表定义为可穿戴式运动健康设备,