• Mybatis(动态sql和分页)


    目录

    一、IDEA使用事项

    二、Mybatis的动态sql

    1、if标签

    2、foreach标签

    三、模糊查询

    四、结果集的处理

    五、分页查询

    六、特殊字符处理


    一、IDEA使用事项

    同一个project,尽量避免多个module中取同样的类名

    二、Mybatis的动态sql

    1、if标签

    现在if可以不用在代码中拼接,在配置文件中进行配置

    图例:

    2、foreach标签

    假设将一个数组变成字符串,也就是和以下方法相同

    1. public void test3(){
    2. int [] ints ={1,2,3,4,5,6};
    3. // 将数组变成字符串 1,2,3,4,5,6
    4. StringBuffer sb=new StringBuffer();
    5. for (int i:ints) {
    6. sb.append(",").append(i);
    7. }
    8. String s=sb.toString();
    9. System.out.println(s.substring(1));
    10. }

    效果:

    可以看到效果和想要的效果相同,那如果数组为空呢? 会提示越界了,然而这个时候Mybatis提供了一个foreach标签

    先在BookMapper.xml中将sql语句写出来

    1. <select id="selectByIn" resultMap="BaseResultMap" parameterType="java.util.List" >
    2. select
    3. <include refid="Base_Column_List" />
    4. from t_mvc_book
    5. where bid in
    6. <foreach collection="bookIds" open="("close=")" separator="," item="bid">
    7. #{bid}
    8. foreach>
    9. select>

    l 再去BookMapper接口中将方法写出 

    1. // 通过in关键字进行查询,讲解 foreach标签的使用
    2. // 如果是参数 是非实体类(book,Order,....),那么记得加上注解 @param,bookIds是对应collection属性的
    3. List selectByIn(@Param("bookIds") List bookIds);

     

     加入到BookBiz和实现类中,然后进行测试

    BookBiz:

    List selectByIn(List bookIds);

     

    BookBizImpl:

    1. @Override
    2. public List selectByIn(List bookIds) {
    3. return bookMapper.selectByIn(bookIds);
    4. }

     测试类中:

    1. @Test
    2. public void selectByIn() {
    3. List bookIds = Arrays.asList(new Integer[]{31,32,33,34});
    4. bookBiz.selectByIn(bookIds).forEach(System.out::println);
    5. }

     效果:

    三、模糊查询

    注意:#{...}自带引号,${...}有sql注入的风险

    将以下代码段加入到BookMapper.xml中

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

    再将以下方法加入到BookMapper接口中

    1. List selectBooksLike1(@Param("bname") String bname);
    2. List selectBooksLike2(@Param("bname") String bname);
    3. List selectBooksLike3(@Param("bname") String bname);

    将以下方法加入到BookBiz:

    1. List selectBooksLike1(String bname);
    2. List selectBooksLike2(String bname);
    3. List selectBooksLike3(String bname);

    实现类:

    1. public List selectBooksLike1(String bname){
    2. return bookMapper.selectBooksLike1(bname);
    3. }
    4. public List selectBooksLike2(String bname){
    5. return bookMapper.selectBooksLike2(bname);
    6. }
    7. public List selectBooksLike3(String bname){
    8. return bookMapper.selectBooksLike3(bname);
    9. }

     测试类:

    1. @Test
    2. public void selectBooksLike1() {
    3. bookBiz.selectBooksLike1("%圣墟%").forEach(System.out::println);
    4. }
    5. @Test
    6. public void selectBooksLike2() {
    7. bookBiz.selectBooksLike2("%圣墟%").forEach(System.out::println);
    8. }
    9. @Test
    10. public void selectBooksLike3() {
    11. bookBiz.selectBooksLike2("圣墟").forEach(System.out::println);
    12. }

    selectctBooksLike1方法的效果:

     

     selectctBooksLike2方法的效果:

     selectctBooksLike3方法的效果:

     方法三才是模糊查询的代码块,而方法一和方法二是为了做一个对比。

    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. 一般能用#的就别用$. 

    四、结果集的处理

    将以下方法加入到BookMapper.xml中

    1. <select id="list1" resultMap="BaseResultMap">
    2. select * from t_mvc_book
    3. select>
    4. <select id="list2" resultType="com.mgy.model.Book">
    5. select * from t_mvc_book
    6. select>
    7. <select id="list3" resultType="com.mgy.model.Book" parameterType="com.mgy.model.BookVo">
    8. select * from t_mvc_book where bid in
    9. <foreach collection="bookIds" open="(" close=")" separator="," item="bid">
    10. #{bid}
    11. foreach>
    12. select>
    13. <select id="list4" resultType="java.util.Map">
    14. select * from t_mvc_book
    15. select>
    16. <select id="list5" resultType="java.util.Map" parameterType="java.util.Map">
    17. select * from t_mvc_book where bid = #{bid}
    18. select>

    自定义mvc中的

    baseDao

            executeQuery-->List-->单表查询--->Mybaits中的ResultType

            executeQuery-->List -->多表查询-->Mybaits中的ResultMap

    如果是单表的情况下,ResultType和ResultMap都可以用

    而list4和list5说明了不管是返回一条数据,还是多条数据,都应该用java.util.Map进行接受,如果是一条数据,那么返回值是Map,如果是多条数据,那么返回值是List

     BookMapper中加入以下代码块:

    1. // list1 list2的结论是:对于单表查询而言,可以用它Resultmap/resultType接受,但是多表必须用Resultmap接受
    2. List list1();
    3. List list2();
    4. // 如果要传入多个查询参数,必须以对象的方式进行传递
    5. // 举例:select * from t_mvc_book where
    6. // bid in(1,2,3,4,5,6) and banme in("圣墟","不死不灭");
    7. List list3(BookVo vo);
    8. // 说明了不管是返回一条数据,还是多条数据,都应该用java.util.Map进行接受,
    9. // 如果是一条数据,那么返回值是Map,如果是多条数据,那么返回值是List
    10. List list4();
    11. Map list5(Map map);

    加入到BookBiz中:

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

    BookVo:

    1. package com.mgy.model;
    2. import java.util.List;
    3. /**
    4. * @author 云鹤衫
    5. * @site www.yunheshan.com
    6. * @company xxx公司
    7. * @create  2022-08-11 22:30
    8. */
    9. public class BookVo extends Book{
    10. private List bookIds;
    11. public List getBookIds() {
    12. return bookIds;
    13. }
    14. public void setBookId(List bookIds) {
    15. this.bookIds = bookIds;
    16. }
    17. }

     加入到实现类中:

    1. @Override
    2. public List list1() {
    3. return bookMapper.list1();
    4. }
    5. @Override
    6. public List list2() {
    7. return bookMapper.list2();
    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. }

    生成到测试类中

    1. @Test
    2. public void list1() {
    3. bookBiz.list1().forEach(System.out::println);
    4. }
    5. @Test
    6. public void list2() {
    7. bookBiz.list2().forEach(System.out::println);
    8. }
    9. @Test
    10. public void list3() {
    11. BookVo vo=new BookVo();
    12. vo.setBookId(Arrays.asList(new Integer[]{31,32,33,34}));
    13. bookBiz.list3(vo).forEach(System.out::print);
    14. }
    15. @Test
    16. public void list4() {
    17. bookBiz.list4().forEach(System.out::println);
    18. }
    19. @Test
    20. public void list5() {
    21. Map map=new HashMap();
    22. map.put("bid",32);
    23. System.out.println(bookBiz.list5(map));
    24. }

    list1的效果:

     list2的效果:

    根据list1和list2的效果对比可以知道list1和list2的结论是为正确的

    list3的效果:

    可以看到list3的效果和之前写的selectByIn该方法的效果一样,如果要传多个参数,只要BookVo中添加属性即可

    list4的效果:

    list5的效果:

     

     总结:

    结论1:对于单表查询而言,Resultmap和ResultType是没有区别的,但是对于多表而言是有区别的

    结论2:如果要传递多个参数到后台,就把这些参数封装到一个对象中

    结论3:不管返回集合还是单条数据,xml文件配置的都是java.util.map而不是Java.util.list

    五、分页查询

    将以下依赖加入pom.xml中

    1. <dependency>
    2. <groupId>com.github.pagehelpergroupId>
    3. <artifactId>pagehelperartifactId>
    4. <version>5.1.2version>
    5. dependency>

     

    配置 Mybatis.cfg.xml配置拦截器

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

    切记一定要加入到typeAliases标签之后

     BookMapper.xml:

    1. <select id="listPager" resultType="java.util.Map" parameterType="java.util.Map">
    2. select * from t_mvc_book where bname like concat(concat('%',#{bname}),'%')
    3. select>

    将以上代码加入其中,然后给个方法加入到BookMapper中

    1. // 利用第三方插件进行分页
    2. List listPager(Map map);

    PageBean:

    1. package com.mgy.util;
    2. import java.io.Serializable;
    3. import java.util.Map;
    4. import javax.servlet.http.HttpServletRequest;
    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. }

     BookBiz:

    1. // 利用第三方插件进行分页
    2. List listPager(Map map, PageBean pageBean);

     实现类:

    1. @Override
    2. public List<Map> listPager(Map map, PageBean pageBean) {
    3. // pageHelper分页插件相关代码
    4. if(pageBean !=null && pageBean.isPagination()){
    5. PageHelper.startPage(pageBean.getPage(),pageBean.getRows());
    6. }
    7. List<Map> maps = bookMapper.listPager(map);
    8. if (pageBean!=null && pageBean.isPagination()){
    9. // 处理查询结果的前提,是想要分页
    10. PageInfo info=new PageInfo(maps);
    11. pageBean.setTotal(info.getTotal()+"");
    12. }
    13. return maps;
    14. }

    测试类:

    1. @Test
    2. public void listPager() {
    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.listPager(map,pageBean).forEach(System.out::println);
    10. }

    效果:

    六、特殊字符处理

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

    BookMapper.xml:

    1. <select id="list6" resultType="com.javaxl.model.Book" parameterType="com.javaxl.model.BookVo">
    2. select * from t_mvc_book
    3. <where>
    4. <if test="null != min and min != ''">
    5. if>
    6. <if test="null != max and max != ''">
    7. price ]]>
    8. if>
    9. where>
    10. select>
    11. <select id="list7" resultType="com.javaxl.model.Book" parameterType="com.javaxl.model.BookVo">
    12. select * from t_mvc_book
    13. <where>
    14. <if test="null != min and min != ''">
    15. and #{min} < price
    16. if>
    17. <if test="null != max and max != ''">
    18. and #{max} > price
    19. if>
    20. where>
    21. select>

     BookMapper:

    1. /**
    2. * 处理特殊字符
    3. * @param bookVo
    4. * @return
    5. */
    6. List list6(BookVo bookVo);
    7. /**
    8. * 处理特殊字符
    9. * @param bookVo
    10. * @return
    11. */
    12. List list7(BookVo bookVo);

    BookVo

    1. package com.mgy.model;
    2. import java.util.List;
    3. /**
    4. * @author 云鹤衫
    5. * @site www.yunheshan.com
    6. * @company xxx公司
    7. * @create  2022-08-11 22:30
    8. */
    9. public class BookVo extends Book{
    10. private List bookIds;
    11. private int min;
    12. private int max;
    13. public int getMax() {
    14. return max;
    15. }
    16. public void setMax(int max) {
    17. this.max = max;
    18. }
    19. public int getMin() {
    20. return min;
    21. }
    22. public void setMin(int min) {
    23. this.min = min;
    24. }
    25. public void setBookIds(List bookIds) {
    26. this.bookIds = bookIds;
    27. }
    28. public List getBookIds() {
    29. return bookIds;
    30. }
    31. public void setBookId(List bookIds) {
    32. this.bookIds = bookIds;
    33. }
    34. }

    BookBiz

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

    实现类:

    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. }

    测试类:

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

    list6效果:

     list7效果:

     

  • 相关阅读:
    3d可视化智慧园区设计成本
    爬虫逆向实战(29)-某蜂窝详情页(cookie、混淆、MD5、SHA)
    前端基础之《ECMAScript 6(7)—异步技术》
    中国现代文学专题形考2022
    Session攻击
    JS中使用递归的一次探索
    no such file or directory, lstat ‘C:\Users\lanzuo\AppData\Roaming\npm‘
    webpack5 css 处理(提取 Css 成单独文件)MiniCssExtractPlugin
    mysql求当月有多少天
    蓝桥杯 使用sort排序(c++)
  • 原文地址:https://blog.csdn.net/m0_62604616/article/details/126290843