• mybatis动态sql和分页


    目录

    1、mybatis动态sql

            1.1 if标签

            1.2 foreach标签

    2、模糊查询

    3、查询返回结果集的处理

    4、分页查询

    5、特殊字符处理


    1、mybatis动态sql

            1.1 if标签

                在自定义MVC时,像我们写修改的sql语句,比如:

                update t_student set sid =?,sname=?,sex=?,sage=?.. where sid=?

                如下图,在IDEA中Maven项目中逆向生成的修改语句则大大不同,它添加了if判断

     自定义MVC的sql语句的弊端:

              假如一个学生编辑界面 student.jsp

               

                   

                    

               

             我们传了两个值进去,意味着后台student实体类

             只有sname,sex属性值没有为空,其他为空,进一步的我们的sql语句会演成如下:

              update t_student set sname=张三,sex=男,sage=null.. where sid=?

            其他的全为null空值

     如果是下面这种sql语句,它能将前台的没有的值直接剔除掉,这就是if标签的作用

      update t_student
     
              sname = 张三
      
              sex= 男
    
      where bid = #{bid,jdbcType=INTEGER} 
    

            1.2 foreach标签

    比如:Integer[ ] ints = {1,2,3,4,5,6}-->1,2,3,4,5,6

    将上面的数组变成一个字符串

    我们通常是foreach遍历

    StringBuffer sb = new StringBuffer();

    for(int i:ints){

            sb.append(i).apped(",");

    }

    System.out.println(sb);

    像这样的话结果最后会多出一个逗号:

    1,2,3,4,5,6,

    我们用substring去截掉最后一个逗号,如下结果

    1,2,3,4,5,6

    mybatis提供了foreach标签,只需要我们提供数组就可以了

         在IDEAMaven项目自动生成的增删改查代码BookMapper.xml中在写一个查询语句

    在我们 BookMapper中添加该方法

     

    在bookBiz添加

    1. ​​​​package com.zwc.biz;
    2. import com.zwc.model.Book;
    3. import java.util.List;
    4. /**
    5. * @authorzwc
    6. * @site www.javazwc.com
    7. * @company xxx公司
    8. * @create  2022-08-10 21:22
    9. */
    10. public interface BookBiz {
    11. int deleteByPrimaryKey(Integer bid);
    12. Book selectByPrimaryKey(Integer bid);
    13. List selectByIn(List bookIds);
    14. }

    Alt+enter在BookBizImpl添加

    BookBizImpl: 


     在BookBizImpl光标放在方法上,ALt+enter键添加在test类

    Test测试类:

    2、模糊查询

    三种模糊查询方式 :#、$、concat

    1. <select id="selectBooksLike1" resultType="com.zwc.model.Book" parameterType="java.lang.String">
    2. select * from t_mvc_book where bname like #{bname}
    3. </select>
    4. <select id="selectBooksLike2" resultType="com.zwc.model.Book" parameterType="java.lang.String">
    5. select * from t_mvc_book where bname like '${bname}'
    6. </select>
    7. <select id="selectBooksLike3" resultType="com.zwc.model.Book" parameterType="java.lang.String">
    8. select * from t_mvc_book where bname like concat(concat('%',#{bname}),'%')
    9. </select>

    在Bookmapper.xml中加入下面三中模糊查询方法

     在BookMapper.java中加入方法

    在BookBiz中加入方法

    在实现类BookBizimpl中加入

    @Override
    public List selectBooksLike1(String bname) {
        return bookMapper.selectBooksLike1(bname);
    }
    
    @Override
    public List selectBooksLike2(String bname) {
        return bookMapper.selectBooksLike2(bname);
    }
    
    @Override
    public List selectBooksLike3(String bname) {
        return bookMapper.selectBooksLike3(bname);
    }

    测试:

    第一种模糊查询:

    Sql语句: 

    第二个方法控制台查询结果和sql语句 

    总结:

    我们可以看出第一种模糊查询的sql语句条件后是占位符

    第二中是参数传入

    可以得出:

    MyBatis中#和$的区别
    1. # 将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。
       如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by '111', 
           如果传入的值是id,则解析成的sql为order by "id".

    2. $ 将传入的数据直接显示生成在sql中。
       如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,
           如果传入的值是id,则解析成的sql为order by id.
     
    3. #方式能够很大程度防止sql注入。
     
    4. $方式无法防止Sql注入。
     
    5. $方式一般用于传入数据库对象,例如传入表名. 
     
    6. 一般能用#的就别用$. 

    第三种

    与第一、二不同的是第三不需要加百分号

    3、查询返回结果集的处理

    将下面方法中加入BookMapper

    
      
      
      
      
    
    对比一下list1和list2
    
      

    自定义MVC中的baseDao

    executeQuery-——>list ——>单表查询——>Mybatis中的ResultType

    executeQuery-——>list ——>多表查询——>Mybatis中的ResultMap

    将下面的resultMap改成resultType 

     

    测试:

     可以看到方法同样测试成功,说明如果是单表的情况下,resultMap与resultType都可以使用


    传了一个对象BookVo 

    BookVo:

    1. package com.zwc.model;
    2. import java.util.List;
    3. /**
    4. * @authorzwc
    5. * @site www.javazwc.com
    6. * @company xxx公司
    7. * @create  2022-08-12 9:01
    8. */
    9. public class BookVO extends Book{
    10. private List bookIds;
    11. public List getBookIds() {
    12. return bookIds;
    13. }
    14. public void setBookIds(List bookIds) {
    15. this.bookIds = bookIds;
    16. }
    17. }

    BookBiz:

    1. List list1();
    2. List list2();
    3. List list3(BookVO vo);
    4. List list4();
    5. Map list5(Map map);

     BookBizImpl:

    1. @Override
    2. public List list1() {
    3. return bookMapper.list1();
    4. }
    5. @Override
    6. public List list2() {
    7. return bookMapper.list1();
    8. }
    9. @Override
    10. public List list3(BookVO vo) {
    11. return bookMapper.list3(vo);
    12. }
    13. @Override
    14. public List list4() {
    15. return bookMapper.list4();
    16. }
    17. @Override
    18. public Map list5(Map map) {
    19. return bookMapper.list5(map);
    20. }

    list1:

     

    list2:

    从list1和list2可以得出结论:

     list1和list2的结论是:对于单表查询而言,可以用ResultMap/ResultType接受,但是多表必须使用Resultmap接受

     list3:

    如果相传多个参数,在bookvo中加入即可

    list4: 

    list5 :

    结论:

    在上述的list4和list5两个方法中说明了不管返回一条数据,还是多条数据,都应该用java.util.Map进行接收,如果是一条数剧,那么返回值是Map,如果是多条,那么返回值是list

    4、分页查询

    将下面的分页插接件代码放入pom.xml

    
      org.apache.logging.log4j
      log4j-web
      2.9.1
    
    

    在将分页拦截器以下放入Mybatis.cfg.xml

    <plugins>
        
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
        plugin>
    plugins>

     要放在在配置环境前

     

    util工具类

    1. package com.zwc.util;
    2. import javax.servlet.http.HttpServletRequest;
    3. import java.io.Serializable;
    4. import java.util.Map;
    5. public class PageBean implements Serializable {
    6. private static final long serialVersionUID = 2422581023658455731L;
    7. //页码
    8. private int page=1;
    9. //每页显示记录数
    10. private int rows=10;
    11. //总记录数
    12. private int total=0;
    13. //是否分页
    14. private boolean isPagination=true;
    15. //上一次的请求路径
    16. private String url;
    17. //获取所有的请求参数
    18. private Map map;
    19. public PageBean() {
    20. super();
    21. }
    22. //设置请求参数
    23. public void setRequest(HttpServletRequest req) {
    24. String page=req.getParameter("page");
    25. String rows=req.getParameter("rows");
    26. String pagination=req.getParameter("pagination");
    27. this.setPage(page);
    28. this.setRows(rows);
    29. this.setPagination(pagination);
    30. this.url=req.getContextPath()+req.getServletPath();
    31. this.map=req.getParameterMap();
    32. }
    33. public String getUrl() {
    34. return url;
    35. }
    36. public void setUrl(String url) {
    37. this.url = url;
    38. }
    39. public Map getMap() {
    40. return map;
    41. }
    42. public void setMap(Map map) {
    43. this.map = map;
    44. }
    45. public int getPage() {
    46. return page;
    47. }
    48. public void setPage(int page) {
    49. this.page = page;
    50. }
    51. public void setPage(String page) {
    52. if(null!=page&&!"".equals(page.trim()))
    53. this.page = Integer.parseInt(page);
    54. }
    55. public int getRows() {
    56. return rows;
    57. }
    58. public void setRows(int rows) {
    59. this.rows = rows;
    60. }
    61. public void setRows(String rows) {
    62. if(null!=rows&&!"".equals(rows.trim()))
    63. this.rows = Integer.parseInt(rows);
    64. }
    65. public int getTotal() {
    66. return total;
    67. }
    68. public void setTotal(int total) {
    69. this.total = total;
    70. }
    71. public void setTotal(String total) {
    72. this.total = Integer.parseInt(total);
    73. }
    74. public boolean isPagination() {
    75. return isPagination;
    76. }
    77. public void setPagination(boolean isPagination) {
    78. this.isPagination = isPagination;
    79. }
    80. public void setPagination(String isPagination) {
    81. if(null!=isPagination&&!"".equals(isPagination.trim()))
    82. this.isPagination = Boolean.parseBoolean(isPagination);
    83. }
    84. /**
    85. * 获取分页起始标记位置
    86. * @return
    87. */
    88. public int getStartIndex() {
    89. //(当前页码-1)*显示记录数
    90. return (this.getPage()-1)*this.rows;
    91. }
    92. /**
    93. * 末页
    94. * @return
    95. */
    96. public int getMaxPage() {
    97. int totalpage=this.total/this.rows;
    98. if(this.total%this.rows!=0)
    99. totalpage++;
    100. return totalpage;
    101. }
    102. /**
    103. * 下一页
    104. * @return
    105. */
    106. public int getNextPage() {
    107. int nextPage=this.page+1;
    108. if(this.page>=this.getMaxPage())
    109. nextPage=this.getMaxPage();
    110. return nextPage;
    111. }
    112. /**
    113. * 上一页
    114. * @return
    115. */
    116. public int getPreivousPage() {
    117. int previousPage=this.page-1;
    118. if(previousPage<1)
    119. previousPage=1;
    120. return previousPage;
    121. }
    122. @Override
    123. public String toString() {
    124. return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", isPagination=" + isPagination
    125. + "]";
    126. }
    127. }

    BookMapper写入方法: 

     

    BookBiz: 

     

    BookBizimpl :

    1. @Override
    2. public List listPage(Map map, PageBean pageBean) {
    3. // 分页插件相关代码,固定代码
    4. // 判断是否分页
    5. if(pageBean!=null&&pageBean.isPagination()){
    6. // 拿到页数和行数
    7. PageHelper.startPage(pageBean.getPage(),pageBean.getRows());
    8. }
    9. //核心部分 结果
    10. List maps = bookMapper.listPage(map);
    11. if(pageBean!=null&& pageBean.isPagination()){
    12. // 处理结果的前提,是需要分页的
    13. // maps经过第三方插件进行处理 分页
    14. PageInfo info = new PageInfo(maps);
    15. pageBean.setTotal(info.getTotal()+"");
    16. }
    17. return maps;
    18. }

    测试类:

    1. @Test
    2. public void listPage() {
    3. Map map = new HashMap();
    4. map.put("bname","圣墟");
    5. // 查询出第二页20条数据
    6. PageBean pageBean = new PageBean();
    7. pageBean.setPage(2);
    8. pageBean.setRows(20);
    9. bookBiz.listPage(map,pageBean).forEach(System.out::println);
    10. }

    结果: 

    5、特殊字符处理

    给CDATA所包裹的特殊字符,都会被转义成sql语句中的字符 


     BookMapper:

    Bookbiz:

    1. List list6(BookVO bookVo);
    2. List list7(BookVO bookVo);

    BookBizimpl:

    1. @Override
    2. public List list6(BookVO bookVo) {
    3. return bookMapper.list6(bookVo);
    4. }
    5. @Override
    6. public List list7(BookVO bookVo) {
    7. return bookMapper.list7(bookVo);
    8. }

    Test:

    1. @Test
    2. public void list6() {
    3. BookVO vo = new BookVO();
    4. vo.setMin(44);
    5. vo.setMin(28);
    6. bookBiz.list6(vo).forEach(System.out::println);
    7. }
    8. @Test
    9. public void list7() {
    10. BookVO vo = new BookVO();
    11. vo.setMin(44);
    12. vo.setMin(28);
    13. bookBiz.list7(vo).forEach(System.out::println);
    14. }

    结果:

    list6:

    list7:

     

     当我们修改符号测试,会报错 

    会报sql语句有错

     

    所以我们在比较的时候不要使用< 、>不然会报错,因为< 、>会与标签的前括号冲突

    使用<、>


    今天的内容就到这里结束了,如有错误,请多指教 !

  • 相关阅读:
    CF比赛1610D. Not Quite Lee(Codeforces Global Round 17)(数学)(计数)
    MySQL 的 C 语言接口
    【多思路附源码】2023高教社杯 国赛数学建模C题思路 - 蔬菜类商品的自动定价与补货决策
    毕业设计:基于Springboot+Vue+ElementUI实现疫情社区管理系统
    京东平台数据分析:2023年9月京东空气净化器行业品牌销售排行榜
    Mathtype插入word,以及mathtype在word上的卸载
    【React】Sigma.js框架网络图-入门篇
    MyBatis动态SQL多表操作
    Java入门第一季
    滚珠螺母的清洁方式
  • 原文地址:https://blog.csdn.net/qq_65345936/article/details/126291992