基于mybatis入门基础上代码操作

数据库数据
mybatis之动态sql和分页_Mybatis框架

mybatis动态sql
  1. if
  2. trim
  3. foreach
    遍历集合,批量查询、通常用于in关键字
  4. 其他
    choose/set/where

BookMapper

 List<Book> selectBooksIn(List bookIds);

Alt+Enter自动生成代码

BookMapper.xml

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

BookServlet

List<Book> selectBooksIn(List bookIds);

BookServletImpl

  @Override
    public List<Book> selectBooksIn(List bookIds) {
        return bookMapper.selectBooksIn(bookIds);
    }

BookServletImplTest测试

 @Test
    public void selectBooksIn() {
        List bookIds = new ArrayList();
        bookIds.add(12);
        bookIds.add(13);
        bookIds.add(16);
        for (Book book : this.bookServlet.selectBooksIn(bookIds)) {
            System.out.println(book);
        }
    }

运行结果mybatis之动态sql和分页_Mybatis教程_02

注意@Param()
mybatis之动态sql和分页_Mybatis教程_03

模糊查询
#{...}
${...}
Concat
select concat('%','圣墟‘,'%') from dual;
coucat函数具有拼接的作用
注意:#{...}自带引号,${...}有sql注入的风险

BookMapper

    List<Book> selectBookLike1(@Param("bname") String banme);
    List<Book> selectBookLike2(@Param("bname") String banme);
    List<Book> selectBookLike3(@Param("bname") String banme);

BookMapper.xml

 <!--模糊查询-->
  <select id="selectBookLike1" resultType="com.myy.model.Book" parameterType="java.lang.String">
     select * from t_mvc_book
     <where>
       bname like #{bname}
     </where>
  </select>

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

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

BookServlet

    List<Book> selectBookLike1(String bname);
    List<Book> selectBookLike2(String bname);
    List<Book> selectBookLike3(String bname);

BookServletImpl

  @Override
    public List<Book> selectBookLike1(String bname) {
        return bookMapper.selectBookLike1(bname);
    }

    @Override
    public List<Book> selectBookLike2(String bname) {
        return bookMapper.selectBookLike2(bname);
    }

    @Override
    public List<Book> selectBookLike3(String bname) {
        return bookMapper.selectBookLike3(bname);
    }

BookServletImplTest

 @Test
    public void selectBookLike() {
//        for (Book book : this.bookServlet.selectBookLike1("%圣墟%")) {
//            System.out.println(book);
//        }

//        for (Book book : this.bookServlet.selectBookLike2("%圣墟%")) {
//            System.out.println(book);
//        }

        for (Book book : this.bookServlet.selectBookLike3("%圣墟%")) {
            System.out.println(book);
        }

    }

分别运行测试:
mybatis之动态sql和分页_Mybatis教程_04

查询返回结果集的处理
  • resultMap:适合使用返回值是自定义实体类的情况
  • resultType:适合使用返回值的数据类型是非自定义的,即jdk的提供的类型
  1. 使用resultMap返回自定义类型集合
  2. 使用resultType返回List<T>
  3. 使用resultType返回单个对象
  4. 使用resultType返回List<Map>,适用于多表查询返回结果集
  5. 使用resultType返回Map<String,Object>,适用于多表查询返回单个结果集

在做实际开发过程中,在一个列表下要做连表查询展示到页面上,比如要在同一个页面下显示订单的信息还要显示订单项的信息。一个实体类对应一张表,查询的一个实体类的信息不包含一个页面所有要展示的信息(订单项)。一个实体类不满足我们的需求,需要借助vo类。

BookVo

package com.myy.model;

import java.util.List;

/**
 * @author 熊贝贝
 * @site www.myy.com
 * @company
 * @create  2019-11-16 11:36
 * <p>
 * vo类专门用来封装多表联查信息用于展示
 * 封装查询条件(某个订单项属于哪个订单,属于多表联查)
 */
public class BookVo extends Book {
    private List<Integer> bookIds;

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

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

BookMapper BookServlet

    List<Book> list1();
    List<Book> list2();
    List<Book> list3(BookVo bookVo);
    List<Map> list4();
    Map list5(Map map);

BookMapper.xml

   <!--使用resultMap返回自定义类型集合-->
    <select id="list1" resultMap="BaseResultMap">
       select * from t_mvc_book
    </select>
    <!--使用resultType返回List<T>-->
    <select id="list2" resultType="com.myy.model.Book">
       select * from t_mvc_book
     </select>
    <!--使用resultType返回单个对象-->
    <select id="list3" resultType="com.myy.model.Book" parameterType="com.myy.model.BookVo">
       select * from t_mvc_book where bid in
       <foreach collection="bookIds" item="bid" open="(" close=")" separator=",">
           #{bid}
       </foreach>
     </select>
    <!--使用resultType返回List<Map>,适用于多表查询返回结果集-->
    <select id="list4" resultType="java.util.Map">
       select * from t_mvc_book
     </select>
    <!--使用resultType返回Map<String,Object>,适用于多表查询返回单个结果集-->
    <select id="list5" resultType="java.util.Map" parameterType="java.util.Map">
       select * from t_mvc_book where bid = #{bid}
     </select>

BookServletImpl

    @Override
    public List<Book> list1() {
        return bookMapper.list1();
    }

    @Override
    public List<Book> list2() {
        return bookMapper.list2();
    }

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

    @Override
    public List<Map> list4() {
        return bookMapper.list4();
    }

    @Override
    public Map list5(Map map) {
        return bookMapper.list5(map);
    }

BoookServletImplTest测试

  @Test
    public void list1() {
        for (Book book : this.bookServlet.list1()) {
            System.out.println(book);
        }
    }

    @Test
    public void list2() {
        for (Book book : this.bookServlet.list2()) {
            System.out.println(book);
        }
    }
    @Test
    public void list3() {
        BookVo bookVo = new BookVo();
        List bookIds = new ArrayList();
        bookIds.add(12);
        bookIds.add(13);
        bookIds.add(16);
        bookVo.setBookIds(bookIds);
        for (Book book : this.bookServlet.list3(bookVo)) {
            System.out.println(book);
        }

    }
    @Test
    public void list4() {
        for (Map map : this.bookServlet.list4()) {
            System.out.println(map);
        }
    }
    @Test
    public void list5() {
       Map map = new HashMap();
       map.put("bid",12);
        Map book = this.bookServlet.list5(map);
        System.out.println(book);
    }

运行分别测试
list1:
mybatis之动态sql和分页_Mybatis_05
list2:
mybatis之动态sql和分页_Mybatis_06
list3:
mybatis之动态sql和分页_Mybatis教程_07
list4:
mybatis之动态sql和分页_Mybatis_08
list5:
mybatis之动态sql和分页_Mybatis框架_09

分页查询

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

使用分页插件步骤
1、导入pom依赖
pom.xml

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

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

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

3、使用PageHelper进行分页
PageBean

package com.myy.utils;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;


/**
 * 分页工具类
 *
 */
public class PageBean {

	private int page = 1;// 页码

	private int rows = 10;// 页大小

	private int total = 0;// 总记录数

	//	保留上一次的请求地址
	private String url;
	//	保留上一次请求所携带的参数
	private Map<String, String[]> paMap = new HashMap<>();

	/**
	 * pageBean初始化
	 * @param req
	 */
	public void setRequest(HttpServletRequest req) {
		//改变它第几页的数据
		this.setPage(req.getParameter("page"));
		//改变它每页展示的数据
		this.setRows(req.getParameter("rows"));
		//控制页面是否分页
		this.setPagination(req.getParameter("pagination"));

		this.setUrl(req.getRequestURL().toString());
		this.setPaMap(req.getParameterMap());
	}

	public void setPagination(String parameter) {
//		当你填false就不分页
		if("false".equals(pagination)) {
			this.setPagination(false);
		}
	}

	public void setRows(String rows) {
		if(StringUtils.isNotBlank(rows)) {
			this.setRows(Integer.valueOf(rows));
		}
	}

	public void setPage(String page) {
//		如果不为空的时候
		if(StringUtils.isNotBlank(page)){
			this.setPage(Integer.valueOf(page));
		}
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}


	public Map<String, String[]> getPaMap() {
		return paMap;
	}

	public void setPaMap(Map<String, String[]> paMap) {
		this.paMap = paMap;
	}


	private boolean pagination = true;// 是否分页

	public PageBean() {
		super();
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		this.page = page;
	}

	public int getRows() {
		return rows;
	}

	public void setRows(int rows) {
		this.rows = rows;
	}

	public int getTotal() {
		return total;
	}

	public void setTotal(int total) {
		this.total = total;
	}

	public void setTotal(String total) {
		this.total = Integer.parseInt(total);
	}

	public boolean isPagination() {
		return pagination;
	}

	public void setPagination(boolean pagination) {
		this.pagination = pagination;
	}

	/**
	 * 获得起始记录的下标
	 *
	 * @return
	 */
	public int getStartIndex() {
		return (this.page - 1) * this.rows;
	}

	@Override
	public String toString() {
		return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination + "]";
	}

	/**
	 * 最大页码
	 * @return
	 */
	public int getMaxPage() {
		return this.total % this.rows == 0 ? this.total/this.rows : this.total/this.rows + 1;
	}


	/**
	 * 获取下一页
	 * @return
	 */
	public int getNextPage() {
		return this.page < this.getMaxPage() ? this.page+1 : this.page;
	}

	/**
	 * 上一页
	 * @return
	 */
	public int getPreviousPage() {

		return this.page > 1 ? this.page-1 : this.page;
	}

}

StringUtils

package com.myy.utils;

public class StringUtils {
	// 私有的构造方法,保护此类不能在外部实例化
	private StringUtils() {
	}

	/**
	 * 如果字符串等于null或去空格后等于"",则返回true,否则返回false
	 *
	 * @param s
	 * @return
	 */
	public static boolean isBlank(String s) {
		boolean b = false;
		if (null == s || s.trim().equals("")) {
			b = true;
		}
		return b;
	}

	/**
	 * 如果字符串不等于null或去空格后不等于"",则返回true,否则返回false
	 *
	 * @param s
	 * @return
	 */
	public static boolean isNotBlank(String s) {
		return !isBlank(s);
	}

}


BookMapper

//    select * from t_mvc_book where bname like '%圣墟%' limit 20,10
    List<Map> listPager(Map map);
}

BookServlet

List<Map> listPager(Map map, PageBean pageBean);

BookMapper

<!--分页-->
    <select id="listPager" resultType="java.util.Map" parameterType="java.util.Map">
        select * from t_mvc_book
        <where>
            <if test="bname !=null and bname !=''">
            bname like #{bname}
            </if>
        </where>
    </select>

4、处理分页结果
BookServletImpl

    @Override
    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 pageInfo = new PageInfo(list);
            System.out.println("当前页:" + pageInfo.getPageNum());
            System.out.println("显示当前数量" + pageInfo.getPageSize());
            System.out.println("符合条件的总记录数:" + pageInfo.getTotal());
            //用于下一次分页
            System.out.println(pageBean.getTotal() + "");
        }
        return list;
    }

BookServletImplTest测试

 @Test
    public void listPager() {
        Map map = new HashMap();
        map.put("bname","%圣墟%");
        PageBean pageBean = new PageBean();
//        查第三页的数据
        pageBean.setPage(3);
        for (Map m : this.bookServlet.listPager(map, pageBean)) {
            System.out.println(m);
        }
    }

运行结果:
mybatis之动态sql和分页_Mybatis_10

特殊字符处理
    >(&gt;)   
    <(&lt;)  
    &(&amp;) 
 空格(&nbsp;)
 <![CDATA[ <= ]]> 

BookVo

package com.myy.model;

import java.util.List;

/**
 * @author 熊贝贝
 * @site www.myy.com
 * @company
 * @create  2019-11-16 11:36
 * <p>
 * vo类专门用来封装多表联查信息用于展示
 * 封装查询条件(某个订单项属于哪个订单,属于多表联查)
 */
public class BookVo extends Book {
    private List<Integer> bookIds;
    private Float min;
    private Float max;

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

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

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

BookMapper BookServlet

  List<Book> list6(BookVo bookVo);

BookMapper.xml

    <!--处理特殊字符-->
    <select id="list6" resultType="com.myy.model.Book" parameterType="com.myy.model.BookVo">
        select * from t_mvc_book where <![CDATA[ price > #{min} and price < #{max} ]]>
    </select>

另外一种:

 select * from t_mvc_book where price &gt; #{min} and price &lt; #{max}

BookServletImpl

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

BookServletImplTest

    @Test
    public void list6() {
        BookVo bookVo = new BookVo();
        bookVo.setMin(10f);
        bookVo.setMax(20f);
        for (Book book : this.bookServlet.list6(bookVo)) {
            System.out.println(book);
        }
    }

运行结果:
mybatis之动态sql和分页_Mybatis教程_11