动态sql和分页

目录

一、mybatis动态sql

二、模糊查询

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

四、分页查询

          1、为什么要重新使用分页?

          2、使用分页的步骤:

五、特殊字符处理


一、mybatis动态sql

          mybatis实现动态sql有两种方式,一种是if,另一种是foreach,if一般在增加的时候实现,而foreach在进行查询的时候进行实现

if方式:

<insert id="insertSelective" parameterType="com.zj.www.model.Book" >
    insert into t_mvc_book
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="bid != null" >
        bid,
      </if>
      <if test="bname != null" >
        bname,
      </if>
      <if test="price != null" >
        price,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="bid != null" >
        #{bid,jdbcType=INTEGER},
      </if>
      <if test="bname != null" >
        #{bname,jdbcType=VARCHAR},
      </if>
      <if test="price != null" >
        #{price,jdbcType=REAL},
      </if>
    </trim>
  </insert>

foreach方式:

  <select id="selectBooksIn" resultType="com.zj.www.model.Book" parameterType="java.util.List">
    select * from t_mvc_book where bid in
    <foreach collection="bookIds" open="(" close=")" separator="," item="bid">
      #{bid}
    </foreach>
  </select>

在接口BookMapper中的需要写的地方:

List<Book> selectBooksIn(@Param("bookIds") List bookIds);

关于foreach中的几个属性:

collection: 集合的变量,

open:自动补充前缀

close:自动补充后缀

separator:分隔符

item:集合变量当前元素的引用

foreach运行结果:

           

二、模糊查询

          mybatis中有三种方式进行查询,分别是#、&以及concat,三种方式写法上有不同,但是运行结果是一样的,

1.#:

<select id="selectBooksLike1" resultType="com.javaxl.model.Book" parameterType="java.lang.String">
  select * from t_mvc_book where bname like #{bname}
</select>

2.&:

<select id="selectBooksLike2" resultType="com.javaxl.model.Book" parameterType="java.lang.String">
  select * from t_mvc_book where bname like '${bname}'
</select>

3.concat:

<select id="selectBooksLike3" resultType="com.javaxl.model.Book" parameterType="java.lang.String">
  select * from t_mvc_book where bname like concat(concat('%',#{bname}),'%')
</select>

在BookMapper接口中的代码:

List<Book> selectBooksLike1(@Param("bname") String bname);
List<Book> selectBooksLike2(@Param("bname") String bname);
List<Book> selectBooksLike3(@Param("bname") String bname);

运行结果:

1.#:

 2.&:

3.concat: 

三种方式查询结果完全一样 !

三种方式区别:

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

2、写法不同:

select * from t_mvc_book where bname like #{bname}

 select * from t_mvc_book where bname like '${bname}'

  select * from t_mvc_book where bname like concat(concat('%',#{bname}),'%')

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

          1、查询返回结果集的处理有五种大的类型,其中两中大的类型下有五个小的类型,

           1、resultMap:适合使用返回值是自定义实体类的情况

           2、resultType:适合使用返回值的数据类型是非自定义的,即jdk的提供的类型

                              3.1 使用resultMap返回自定义类型集合

                              3.2 使用resultType返回List<T>

                              3.3 使用resultType返回单个对象

                              3.4 使用resultType返回List<Map>,适用于多表查询返回结果集

                              3.5 使用resultType返回Map<String,Object>,适用于多表查询返回单个结果集

           

在bookMapper.xml中的代码:

 3.1 使用resultMap返回自定义类型集合
<select id="list1" resultMap="BaseResultMap">
  select * from t_mvc_book
</select>


3.2 使用resultType返回List<T>
<select id="list2" resultType="com.javaxl.model.Book">
  select * from t_mvc_book
</select>



3.3 使用resultType返回单个对象
<select id="list3" resultType="com.javaxl.model.Book" parameterType="com.javaxl.model.BookVo">
  select * from t_mvc_book where bid in
  <foreach collection="bookIds" open="(" close=")" separator="," item="bid">
    #{bid}
  </foreach>
</select>


3.4 使用resultType返回List<Map>,适用于多表查询返回结果集
<select id="list4" resultType="java.util.Map">
  select * from t_mvc_book
</select>



3.5 使用resultType返回Map<String,Object>,适用于多表查询返回单个结果集
<select id="list5" resultType="java.util.Map" parameterType="java.util.Map">
  select * from t_mvc_book where bid = #{bid}
</select>



在bookMapper中的代码:

/**
 * 使用resultMap返回自定义类型集合
 * @return
 */
List<Book> list1();

/**
 * 使用resultType返回List<T>
 * @return
 */
List<Book> list2();

/**
 * 使用resultType返回单个对象
 * @return
 */
Book list3(BookVo bookVo);

/**
 * 使用resultType返回List<Map>,适用于多表查询返回结果集
 * @return
 */
List<Map> list4();

/**
 * 使用resultType返回Map<String,Object>,适用于多表查询返回单个结果集
 * @return
 */
Map list5(Map book);

在测试类中的代码:

public void testlist1() {
        System.out.println("mybatis五中配置");
        List<Book> books = this.bookService.list1();
        books.forEach(System.out::println);
    }

    public void testlist2() {
        System.out.println("mybatis五中配置");
        List<Book> books = this.bookService.list2();
        books.forEach(System.out::println);
    }


    public void testlist3() {
        System.out.println("mybatis五中配置");
        BookVo bookVo = new BookVo();
        bookVo.setBookIds(Arrays.asList(new Integer[]{29}));
        System.out.println(this.bookService.list3(bookVo));

    }

    public void testlist4() {
        System.out.println("mybatis五中配置");
        List<Map> books = this.bookService.list4();
        books.forEach(System.out::println);
    }


    public void testlist5() {
        System.out.println("mybatis五中配置");
        Map map = new HashMap();
        map.put("bid", 29);
        Map map1 = this.bookService.list5(map);
        System.out.println(map1);
    }

    public void testlist6() {
        System.out.println("mybatis五中配置");
        BookVo vo=new BookVo();
        vo.setMin(20f);
        vo.setMax(40f);
        List<Book> books1 = this.bookService.list6(vo);
        books1.forEach(System.out::println);
    }

运行代码:


在测试的时候出现一个错误,原因是其中一个baseresult重复了:

报错代码重现:

java.lang.ExceptionInInitializerError
    at com.zj.www.service.impl.BookServiceImplTest.setUp(BookServiceImplTest.java:21)
    at junit.framework.TestCase.runBare(TestCase.java:139)
    at junit.framework.TestResult$1.protect(TestResult.java:122)
    at junit.framework.TestResult.runProtected(TestResult.java:142)
    at junit.framework.TestResult.run(TestResult.java:125)
    at junit.framework.TestCase.run(TestCase.java:129)
    at junit.framework.TestSuite.runTest(TestSuite.java:252)
    at junit.framework.TestSuite.run(TestSuite.java:247)
    at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
    at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: org.apache.ibatis.exceptions.PersistenceException: 
### Error building SqlSession.
### The error may exist in com/zj/www/mapper/BookMapper.xml
### The error occurred while processing mapper_resultMap[BaseResultMap]
### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. Cause: java.lang.IllegalArgumentException: Result Maps collection already contains value for com.zj.www.mapper.BookMapper.BaseResultMap
    at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
    at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:80)
    at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:64)
    at com.zj.www.util.SessionUtil.<clinit>(SessionUtil.java:11)
    ... 16 more
Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. Cause: java.lang.IllegalArgumentException: Result Maps collection already contains value for com.zj.www.mapper.BookMapper.BaseResultMap
    at
org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:121)
    at org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(XMLConfigBuilder.java:99)
    at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:78)
    ... 18 more
Caused by: org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. Cause: java.lang.IllegalArgumentException: Result Maps collection already contains value for com.zj.www.mapper.BookMapper.BaseResultMap
    at org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:120)
    at org.apache.ibatis.builder.xml.XMLMapperBuilder.parse(XMLMapperBuilder.java:92)
    at org.apache.ibatis.builder.xml.XMLConfigBuilder.mapperElement(XMLConfigBuilder.java:373)
    at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:119)
    ... 20 more
Caused by: java.lang.IllegalArgumentException: Result Maps collection already contains value for com.zj.www.mapper.BookMapper.BaseResultMap
    at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:872)
    at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:844)
    at org.apache.ibatis.session.Configuration.addResultMap(Configuration.java:626)
    at org.apache.ibatis.builder.MapperBuilderAssistant.addResultMap(MapperBuilderAssistant.java:214)
    at org.apache.ibatis.builder.ResultMapResolver.resolve(ResultMapResolver.java:47)
    at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:285)
    at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:252)
    at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElements(XMLMapperBuilder.java:244)
    at org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:116)
    ... 23 more

在 bookmapper.xml中出现了重复的代码:

解决方式: 将以下重复的代码删除掉:

四、分页查询

          1、为什么要重新使用分页?

                Mybatis的分页功能很弱,它是基于内存的分页(查出所有记录再按偏移量offset和边界limit取结果),在大数据量的情况下这样的分页基本上是没有用的

          2、使用分页的步骤:

1、导入pom依赖

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

3、使用PageHelper进行分页

4、处理分页结果

1、导入pom依赖

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.1.2</version>
</dependency>

2、Mybatis.cfg.xml配置拦截器(注意:不是在pom.xml中进行配置,是在Mybatis.cfg.xml中进行配置)

<plugins>
    <!-- 配置分页插件PageHelper, 4.0.0以后的版本支持自动识别使用的数据库 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
    </plugin>
</plugins>

3、使用PageHelper进行分页

使用分页插件:

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

4、处理分页结果

     将代码进行测试:

4.1、BookMapper:

    /*分页*/
    List<Map> listPager(Map map);

4.2、BookMapper.xml:模糊查询的形式是concat: 

<!--分页-->
  <select id="listPager" resultType="java.util.Map" parameterType="java.util.Map">
    select * from t_mvc_book where bname like concat(concat('%',#{bname}),'%')
  </select>

4.3、BookService:(在这里需要注意的是,这里面可以注入param属性,但是在BookMapper中不能注入param属性,之后有一个问题涉及到)

    List<Map> listPager(@Param("bname") Map map, PageBean pageBean);

4.4、BookServiceimpl:在这里注意的是:这里不需要在以下代码中加入第二个参数。

List<Map> list = bookMapper.listPager(map);

  @Override
//    public List<Map> listPager(Map map, PageBean pageBean) {
//        return bookMapper.listPager(map);
//    }
    public List<Map> listPager(Map map, PageBean pageBean) {
        if (pageBean != null && pageBean.isPagination()) {
            PageHelper.startPage(pageBean.getPage(), pageBean.getRows());
        }
        List<Map> list = bookMapper.listPager(map);
        if (pageBean != null && pageBean.isPagination()) {
            PageInfo pageInfo = new PageInfo(list);
            System.out.println("页码:" + pageInfo.getPageNum());
            System.out.println("页大小:" + pageInfo.getPageSize());
            System.out.println("总记录:" + pageInfo.getTotal());
            pageBean.setTotal(pageInfo.getTotal() + "");
        }
        return list;
    }

4.5、BookServiceImplTest:

   public void testlistpager() {
        System.out.println("分页");
        Map map = new HashMap();
        map.put("bname", "圣墟");
        PageBean pageBean = new PageBean();
        pageBean.setPage(1);
//        pageBean.setPagination(false);
        List<Map> ms = this.bookService.listPager(map, pageBean);
        ms.forEach(System.out::println);
    }

最后进行测试的时候,就可以查询出来结果: 

在进行分页查询的过程中,遇到了三个问题:

一:在进行查询的时候,结果出来了,但是没有数据。如下图所示: 

解决方式:在下图方法中只要一个参数,就是map,况且只能有一个参数,这是mybatis的规定:这是一种错误的写法

解决完之后:

二:在进行Mybatis.cfg.xml配置时,出现了依赖位置插入问题:

 报错代码重现:

Caused by: org.apache.ibatis.builder.BuilderException: Error creating document instance.  Cause: org.xml.sax.SAXParseException; lineNumber: 50; columnNumber: 17; 元素类型为 "configuration" 的内容必须匹配 "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,

objectWrapperFactory?,reflectorFactory?,plugins?,environments?,

databaseIdProvider?,mappers?)"。配置依赖顺序
    at org.apache.ibatis.parsing.XPathParser.createDocument(XPathParser.java:259)
    at org.apache.ibatis.parsing.XPathParser.<init>(XPathParser.java:125)
    at org.apache.ibatis.builder.xml.XMLConfigBuilder.<init>(XMLConfigBuilder.java:82)
    at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:77)
    ... 18 more

发现问题所在:

解决方式:按照上述错误提示:plugins节点应该位于environments节点之前。

 

五、特殊字符处理

          1、对于特殊字符处理,就是一些平常经常遇到的字符,比如:

>(>), <(<) ,&(&),空格( ),<![CDATA[ <= ]]>

          2、测试:

BookMapper.xml:

<!--  特殊符號-->
  <select id="list6" resultType="com.zj.www.model.Book" parameterType="com.zj.www.vo.BookVo">
    select * from t_mvc_book
    <where>
      <if test="null != min and min != ''">
        <![CDATA[  and #{min} < price ]]>
      </if>
      <if test="null != max and max != ''">
        <![CDATA[ and #{max} > price ]]>
      </if>
    </where>
  </select>

  <select id="list7" resultType="com.zj.www.model.Book" parameterType="com.zj.www.vo.BookVo">
    select * from t_mvc_book
    <where>
      <if test="null != min and min != ''">
        and #{min} &lt; price
      </if>
      <if test="null != max and max != ''">
        and #{max} &gt; price
      </if>
    </where>
  </select>

BookMapper:

  /**
     * 处理特殊字符
     * @param bookVo
     * @return
     */
    List<Book> list6(BookVo bookVo);


    /**
     * 处理特殊字符
     * @param bookVo
     * @return
     */
    List<Book> list7(BookVo bookVo);

BookService:

    /**
     * 处理特殊字符
     * @param bookVo
     * @return
     */
    List<Book> list6(BookVo bookVo);


    /**
     * 处理特殊字符
     * @param bookVo
     * @return
     */
    List<Book> list7(BookVo bookVo);

BookServiceImpl:

    @Override
    public List<Book> list6(BookVo bookVo) {
        return bookMapper.list6(bookVo);
    }

    @Override
    public List<Book> list7(BookVo bookVo) {
        return bookMapper.list7(bookVo);
    }

BookServiceImplTest:以下有两个方法是在BookVo中定义了

 public void testlist6() {
        System.out.println("mybatis五种配置");
        BookVo vo=new BookVo();
        vo.setMin(20f);
        vo.setMax(40f);
        List<Book> books1 = this.bookService.list6(vo);
        books1.forEach(System.out::println);
    }


    public void testlist7() {
        System.out.println("mybatis五种配置");
        BookVo vo=new BookVo();
        vo.setMin(20f);
        vo.setMax(40f);
        List<Book> books1 = this.bookService.list7(vo);
        books1.forEach(System.out::println);
    }

BookVo:

package com.zj.www.vo;

import com.zj.www.model.Book;

import java.util.List;

public class BookVo  extends Book {

    private List<Integer> BookIds;
    private  float min;
    private  float max;


    public List<Integer> getBookIds() {
        return BookIds;
    }

    public void setBookIds(List<Integer> bookIds) {
        BookIds = bookIds;
    }

    public float getMin() {
        return min;
    }

    public void setMin(float min) {
        this.min = min;
    }

    public float getMax() {
        return max;
    }

    public void setMax(float max) {
        this.max = max;
    }

    @Override
    public String toString() {
        return "BookVo{" +
                "BookIds=" + BookIds +
                ", min=" + min +
                ", max=" + max +
                '}';
    }
}

运行结果:查询20条数据:可以将特殊字符处理

今天的知识就分享到这里,希望能够帮助到你!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值