今日目标:
1,动态SQL
2,模糊查询( # 与 $ 符号的区别)
3,结果集的配置
4,分页
5,特殊字符的处理
在前一篇博客的基础上进行开发
MyBatis入门(逆向生成&&增删改查案例)_m0_58525944的博客-优快云博客 |
一,动态SQL
常用的动态SQL:If、foreach
BookMapper.java中的方法:
List<Book> selectBooksIn(List bookIds);
BookMapper.xml中的配置标签:
<!-- 动态SQL-->
<!-- collection:集合的变量 open:自动补充的前缀 close:自动补充的后缀 separator:分隔符 item:集合变量当前元素的引用-->
<select id="selectBooksIn" resultType="com.lgs.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>
加入方法到BookService.java接口类中:
List<Book> selectBooksIn(@Param("bookIds") List bookIds);
在BookServiceImpl.java实现类中实现此方法:
public List<Book> selectBooksIn(List bookIds) {
return bookMapper.selectBooksIn(bookIds);
}
在BookServiceImplTest.java测试类中测试此方法:
public void testSelectBooksIn() {
System.out.println("动态SQL--");
List<Book> books = this.bookService.selectBooksIn(Arrays.asList(new Integer[]{40,50}));
books.forEach(System.out::println);
}
测试结果:
二,模糊查询( # 与 $ 符号的区别)
语法:
第一种形式:#{…}(常用)
第二种形式:${…}(动态列需要用到,比如下拉框查询,按价格或者作者这些列字段进行查询)注意:#{…}自带引号,${…}有sql注入的风险
BookMapper.xml中的配置标签:
<!-- 模糊查询-->
<select id="selectBooksLike1" resultType="com.lgs.model.Book" parameterType="java.lang.String">
select * from t_mvc_book where bname like #{bname}
</select>
<select id="selectBooksLike2" resultType="com.lgs.model.Book" parameterType="java.lang.String">
select * from t_mvc_book where bname like '${bname}'
</select>
<select id="selectBooksLike3" resultType="com.lgs.model.Book" parameterType="java.lang.String">
select * from t_mvc_book where bname like concat(concat('%',#{bname}),'%')
</select>
BookMapper.java中的方法:
/* 测试模糊查询方法一 */
List<Book> selectBooksLike1(@Param("bname")String bname);
/*测试模糊查询方法二 */
List<Book> selectBooksLike2(@Param("bname")String bname);
/*测试模糊查询方法三 */
List<Book> selectBooksLike3(@Param("bname")String bname);
加入方法到BookService.java接口类中:
/* 测试模糊查询方法一 */
List<Book> selectBookLike1(String bname);
/*测试模糊查询方法二 */
List<Book> selectBookLike2(String bname);
/*测试模糊查询方法三 */
List<Book> selectBookLike3(String bname);
在BookServiceImpl.java实现类中实现此方法:
@Override
public List<Book> selectBookLike1(String bname) {
return bookMapper.selectBooksLike1(bname);
}
@Override
public List<Book> selectBookLike2(String bname) {
return bookMapper.selectBooksLike2(bname);
}
@Override
public List<Book> selectBookLike3(String bname) {
return bookMapper.selectBooksLike3(bname);
}
在BookServiceImplTest.java测试类中测试此方法:
public void testSelectBookLike1() {
System.out.println("模糊查询1--");
List<Book> books = this.bookService.selectBookLike1("%圣墟%");
books.forEach(System.out::println);
}
public void testSelectBookLike2() {
System.out.println("模糊查询2--");
List<Book> books = this.bookService.selectBookLike2("%圣墟%");
books.forEach(System.out::println);
}
public void testSelectBookLike3() {
System.out.println("模糊查询3--");
List<Book> books = this.bookService.selectBookLike3("圣墟");
books.forEach(System.out::println);
}
测试结果:
三,查询返回结果集的处理
语法:
resultMap:适合使用返回值是自定义实体类的情况
resultType:适合使用返回值的数据类型是非自定义的,即jdk的提供的类型
3.1 使用resultMap返回自定义类型集合
3.2 使用resultType返回List<T>
3.3 使用resultType返回单个对象
3.4 使用resultType返回List<Map>,适用于多表查询返回结果集
3.5 使用resultType返回Map<String,Object>,适用于多表查询返回单个结果集
首先建一个BooKVo实体类用于多表查询返回一个集合:
package com.lgs.vo;
import com.lgs.model.Book;
import java.util.List;
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.xml中的配置标签:
<!-- 查询返回结果集的处理-->
<select id="list1" resultMap="BaseResultMap">
select * from t_mvc_book
</select>
<select id="list2" resultType="com.lgs.model.Book">
select * from t_mvc_book
</select>
<select id="list3" resultType="com.lgs.model.Book" parameterType="com.lgs.vo.BooKVo">
select * from t_mvc_book where bid in
<foreach collection="bookIds" open="(" close=")" separator="," item="bid">
#{bid}
</foreach>
</select>
<select id="list4" resultType="java.util.Map">
select * from t_mvc_book
</select>
<select id="list5" resultType="java.util.Map" parameterType="java.util.Map">
select * from t_mvc_book where bid = #{bid}
</select>
BookMapper.java中的方法:
/* 结果集的处理 */
/*查询多条数据返回的是map自定义集合:使用resultMap返回自定义类型集合*/
List<Book> list1();
/* 使用resultType返回List<T>*/
List<Book> list2();
/*使用resultType返回Map<String,Object>,适用于多表查询返回单个结果集*/
List<Book> list3(BooKVo bookVo);
/*直接返回map集合,有多少个键都可取,常用*/
List<Map> list4();
/*查询单个结果集,常用*/
Map list5(Map map);
加入方法到BookService.java接口类中:
/* 结果集的处理 */
/*查询多条数据返回的是map自定义集合:使用resultMap返回自定义类型集合*/
List<Book> list1();
/* 使用resultType返回List<T>*/
List<Book> list2();
/*使用resultType返回Map<String,Object>,适用于多表查询返回单个结果集*/
Book list3(BooKVo bookVo);
/*直接返回map集合,有多少个键都可取,常用*/
List<Map> list4();
/*查询单个结果集,常用*/
Map list5(Map book);
在BookServiceImpl.java实现类中实现此方法:
@Override
public List<Book> list1() {
return bookMapper.list1();
}
@Override
public List<Book> list2() {
return bookMapper.list2();
}
@Override
public Book list3(BooKVo bookVo) {
return bookMapper.list3(bookVo);
}
@Override
public List<Map> list4() {
return bookMapper.list4();
}
@Override
public Map list5(Map book) {
return bookMapper.list5(book);
}
在BookServiceImplTest.java测试类中测试此方法:
public void testList1() {
System.out.println("五种返回类型--");
List<Book> books = this.bookService.list1();
books.forEach(System.out::println);
}
public void testList2() {
System.out.println("五种返回类型--");
List<Book> books = this.bookService.list2();
books.forEach(System.out::println);
}
public void testList3() {
System.out.println("五种返回类型--");
BooKVo booKVo = new BooKVo();
booKVo.setBookIds(Arrays.asList(new Integer[]{40}));
System.out.println(this.bookService.list3(booKVo));
}
public void testList4() {
System.out.println("五种返回类型--");
List<Map> books = this.bookService.list4();
books.forEach(System.out::println);
}
public void testList5() {
System.out.println("五种返回类型--");
Map map = new HashMap();
map.put("bid",40);
Map m = this.bookService.list5(map);
System.out.println(m);
}
/*
* 结论1
* resultMap:多表查询会用
* resultType:单表查询
*
* 结论2
* List<T></>:单表
* List<Map></>:多表
*
* */
测试结果:五个方法测试结果都成功了
四,分页
为什么要重写mybatis的分页?
Mybatis的分页功能很弱,它是基于内存的分页(查出所有记录再按偏移量offset和边界limit取结果),在大数据量的情况下这样的分页基本上是没有用的
使用分页插件步奏
- 导入pom依赖(mybatis是借用了拦截器引入第三方完成分页的,配置拦截器)
- Mybatis.cfg.xml配置拦截器
- 使用PageHelper进行分页
- 处理分页结果
1 导入pom依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
2 Mybatis.cfg.xml配置拦截器
<select id="listPager" resultType="java.util.Map" parameterType="java.util.Map">
select * from t_mvc_book where bname like concat(concat('%',#{bname}),'%')
</select>
注意放置的先后顺序
其中要用到来个分页的工具类
PageBean
package com.lgs.util;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
/**
* 分页工具类
*
*/
public class PageBean {
private int page = 1;// 当前页码
private int rows = 5;// 页大小
private int total = 0;//总记录数
//上一次查询的url
private String url;
//上一次查询所携带的查询条件
private Map<String, String[]> parameterMap=new HashMap<String, String[]>();
//对pagebean进行初始化
public void setRequest(HttpServletRequest req) {
//初始化jsp页面传递过来的当前页
this.setPage(req.getParameter("page"));
//初始化jsp页面传递过来的页大小
this.setRows(req.getParameter("rows"));
//初始化jsp页面 传递过来是否分页
this.setPagination(req.getParameter("pagination"));
//保留上一次的查询请求
this.setUrl(req.getRequestURL().toString());
//保留上一次的查询条件
this.setParameterMap(req.getParameterMap());
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Map<String, String[]> getParameterMap() {
return parameterMap;
}
public void setParameterMap(Map<String, String[]> parameterMap) {
this.parameterMap = parameterMap;
}
private void setPage(String page) {
if(StringUtils.isNotBlank(page)) {
this.setPage(Integer.valueOf(page));
}
}
private void setRows(String rows) {
if(StringUtils.isNotBlank(rows)) {
this.setRows(Integer.valueOf(rows));
}
}
private void setPagination(String pagination) {
//只有填了false字符串,才代表不分页
this.setPagination(!"false".equals(pagination));;
}
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 + "]";
}
//上一页
public int getPrevPage() {
return this.page>1?this.page-1:this.page;
}
//下一页
public int getNextPage() {
return this.page<this.getMaxPage()?this.page+1:this.page;
}
//最大页
public int getMaxPage() {
return this.total%this.rows==0?this.total/this.rows:(this.total/this.rows)+1;
}
}
StringUtils工具类:附属pagebean工具类
package com.lgs.util;
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.xml中的配置标签:
<!--分页-->
<select id="listPager" resultType="java.util.Map" parameterType="java.util.Map">
select * from t_mvc_book where bname like concat(concat('%',#{bname}),'%')
</select>
BookMapper.java中的方法:
/*分页*/
List<Map> listPager(Map map);
加入方法到BookService.java接口类中:
/*分页*/
List<Map> listPager(Map map, PageBean pageBean);
在BookServiceImpl.java实现类中实现此方法:
@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 = new PageInfo(list);
System.out.println("页码:"+pageInfo.getPageNum());
System.out.println("页大小:"+pageInfo.getPageSize());
System.out.println("总记录:"+pageInfo.getTotal());
pageBean.setTotal(pageInfo.getTotal()+"");
}
return list;
}
在BookServiceImplTest.java测试类中测试此方法:
public void testPager() {
System.out.println("分页--");
Map map = new HashMap();
map.put("bname","圣墟");
PageBean pageBean = new PageBean();
pageBean.setPage(4);
// 不分页
// pageBean.setPagination(false);
List<Map> m = this.bookService.listPager(map,pageBean);
System.out.println(m);
}
测试结果:
五,特殊字符的处理
语法:
<(<) >(>)<![CDATA[ <= ]]> 如:<![CDATA[ and #{min} < price ]]>
BookVo.java实体类添加两个属性: min与max
package com.lgs.vo;
import com.lgs.model.Book;
import java.util.List;
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.xml中的配置标签:
<select id="list6" resultType="com.javaxl.model.Book" parameterType="com.javaxl.model.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.javaxl.model.Book" parameterType="com.javaxl.model.BookVo">
select * from t_mvc_book
<where>
<if test="null != min and min != ''">
and #{min} < price
</if>
<if test="null != max and max != ''">
and #{max} > price
</if>
</where>
</select>
BookMapper.java中的方法:
/**
* 处理特殊字符
*/
List<Book> list6(BookVo bookVo);
/**
* 处理特殊字符
*/
List<Book> list7(BookVo bookVo);
加入方法到BookService.java接口类中:
/*特殊字符的处理*/
List<Book> list6(BooKVo bookVo);
List<Book> list7(BooKVo bookVo);
在BookServiceImpl.java实现类中实现此方法:
/*特殊字符的处理*/
@Override
public List<Book> list6(BooKVo bookVo) {
return bookMapper.list6(bookVo);
}
@Override
public List<Book> list7(BooKVo bookVo) {
return bookMapper.list7(bookVo);
}
在BookServiceImplTest.java测试类中测试此方法:
public void testlist6(){
System.out.println("特殊字符的处理--");
BooKVo booKVo = new BooKVo();
booKVo.setMin(20f);
booKVo.setMax(50f);
List<Book> books = this.bookService.list6(booKVo);
books.forEach(System.out::println);
}
public void testlist7(){
System.out.println("特殊字符的处理--");
BooKVo booKVo = new BooKVo();
booKVo.setMin(20f);
booKVo.setMax(50f);
List<Book> books = this.bookService.list7(booKVo);
books.forEach(System.out::println);
}
测试结果:
OK!到这就结束了,希望能帮到你!!!