Mybatis之动态sql、模糊查询、查询返回结果集的处理、分页查询与特殊字符处理

目录

一、Mybatis 动态sql

Foreach标签

二、模糊查询(3种方式)

参数中直接加入%%(#{...})

使用${...}代替#{...}(不建议使用该方式,有SQL注入风险)

#{...}与${...}区别?

SQL字符串拼接CONCAT

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

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

使用resultType返回List 

使用resultType返回单个对象

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

 使用resultType返回Map,适用于多表查询返回单个结果集 ,object>

四、分页查询

为什么要重写mybatis的分页?

使用分页插件步奏

导入分页相关的pom依赖

 Mybatis.cfg.xml配置拦截器

使用分页插件

五、特殊字符处理 


一、Mybatis 动态sql

Foreach标签

创建一个数组,再用Foreach遍历

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

 可以看到,我们此时代码没问题,可如果我们把数组里的值删掉呢?

 @Test
    public void Test() {
        int [] ints={};
        //将数据变成字符串
        StringBuffer sb=new StringBuffer();
        for (int i:ints){
            sb.append(",").append(i);
        }
        String s=sb.toString();
        System.out.println(s.substring(1));
    }

 报下标越界异常了,可以发现,代码写到这里还有点小复杂。这时Mybatis提供了一个foreach标签,我们只管传值就完了

PermissionMapper.xml

  <!--PermissionIds 就是{1,2,3,4,5,6}-->
  <select id="selectByIn" resultMap="BaseResultMap" parameterType="java.util.List" >
    select
    <include refid="Base_Column_List"/>
    from t_easyui_permission
    where id in
    <foreach collection="permissionIds" open="(" close=")" separator="," item="id">
      #{id}
    </foreach>
  </select>
PermissionBiz
 List<Permission> selectByIn(List permissionIds);
PermissionMapper
 //通过in关键字进行查询,讲解foreach  标签的使用
    //如果说参数 是 非实体类(Permission,Meeting,...) 那么记得加上注解 @param,permissionIds是对应collection属性的
    List<Permission> selectByIn(@Param("permissionIds") List permissionIds);
PermissionBizImpl
   @Override
    public List<Permission> selectByIn(List permissionIds) {
        return permission.selectByIn(permissionIds);
    }
PermissionBizImplTest
  @Test
    public void selectByIn() {
        /*permissionIds*/
        permissionBiz.selectByIn(Arrays.asList(new Long[]{1L, 2L, 3L, 4L})).forEach(System.out::println);
     }

二、模糊查询(3种方式)

参数中直接加入%%(#{...})

PermissionMapper.xml


  <select id="selectPermissoonLike1" resultType="com.oyang.model.Permission" parameterType="java.lang.String">
  select * from t_easyui_permission where name like #{name}
</select>

PermissionMapper

    List<Permission> selectPermissoonLike1(@Param("name") String name);

PermissionBiz

    public List<Permission> selectPermissoonLike1(String name);
PermissionBizImpl
 @Override
    public List<Permission> selectPermissoonLike1(String name) {
        return permission.selectPermissoonLike1(name);
    }

 测试

    @Test
    public void selectPermissoonLike1() {
        permissionBiz.selectPermissoonLike1("%架%").forEach(System.out::println);
    }

 

使用${...}代替#{...}(不建议使用该方式,有SQL注入风险)

 PermissionMapper.xml

  <select id="selectPermissoonLike2" resultType="com.oyang.model.Permission" parameterType="java.lang.String">
  select * from t_easyui_permission where name like '${name}'
</select>

PermissionMapper

    List<Permission> selectPermissoonLike2(@Param("name") String name);

PermissionBiz

public List<Permission> selectPermissoonLike2(String name);

PermissionBizImpl

 @Override
    public List<Permission> selectPermissoonLike2(String name) {
        return permission.selectPermissoonLike2(name);
    }

 测试

    @Test
    public void selectPermissoonLike2() {
        permissionBiz.selectPermissoonLike2("%架%").forEach(System.out::println);
    }

 

#{...}与${...}区别?

参数类型为字符串,#会在前后加单引号['],$则直接插入值

1) mybatis中使用OGNL表达式传递参数
2) 优先使用#{...}
3) ${...}方式存在SQL注入风险 

SQL字符串拼接CONCAT

PermissionMapper.xml

  <select id="selectPermissoonLike3" resultType="com.oyang.model.Permission" parameterType="java.lang.String">
  select * from t_easyui_permission where name like concat(concat('%',#{name}),'%')
</select>

PermissionMapper

List<Permission> selectPermissoonLike3(@Param("name") String name);

PermissionBiz

 public  List<Permission> selectPermissoonLike3(String name);

PermissionBizImpl

    @Override
    public List<Permission> selectPermissoonLike3(String name) {
        return permission.selectPermissoonLike3(name);
    }

 测试

    public void selectPermissoonLike3() {
        permissionBiz.selectPermissoonLike3("架").forEach(System.out::println);
    }

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

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

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

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

 PermissionMapper.xml

  <select id="list1" resultMap="BaseResultMap">
  select * from t_easyui_permission
</select>

PermissionMapper

List<Permission> list1();

PermissionBiz

List<Permission> list1();

PermissionBizImpl

  @Override
    public List<Permission> list1() {
         return permission.list1();
    }

测试

    @Test
    public void list1() {
        permissionBiz.list1().forEach(System.out::println);
    }

使用resultType返回List<T> 

 PermissionMapper.xml

  <select id="list2" resultType="com.oyang.model.Permission">
  select * from t_easyui_permission
</select>

PermissionMapper

List<Permission> list2();

PermissionBiz

List<Permission> list2();

PermissionBizImpl

@Override
    public List<Permission> list2() {
        return permission.list2();
    }

测试

    @Test
    public void list2() {
        permissionBiz.list2().forEach(System.out::println);
    }

list1()、list2()的结论是,对于单表而言,可以用ResultMap/ResultType接收,但是多表必须用ResultMap接收 

使用resultType返回单个对象

 PermissionMapper.xml

  <select id="list3" resultType="com.oyang.model.Permission" parameterType="com.oyang.model.PermissionVo">
    select * from t_easyui_permission
     where id in
    <foreach collection="permissionIds" open="(" close=")" separator="," item="id">
      #{id}
    </foreach>
  </select>

PermissionVo

package com.oyang.model;

import java.util.List;

/**
 * @author oyang
 * @site https://blog.csdn.net
 * @qq 1828190940
 * @create  2022-08-12 11:42
 */
public class PermissionVo extends Permission{
    private List permissionIds;

    public List getPermissionIds() {
        return permissionIds;
    }

    public void setPermissionIds(List permissionIds) {
        this.permissionIds = permissionIds;
    }

}

PermissionMapper

//如果要传入多个查询参数,必须以对象的方式进行传递
    List<Permission> list3(PermissionVo Vo);

PermissionBiz

 List<Permission> list3(PermissionVo Vo);

PermissionBizImpl

    @Override
    public List<Permission> list3(PermissionVo Vo) {
        return permission.list3(Vo);
    }

测试

    @Test
    public void list3() {
        PermissionVo vo=new PermissionVo();
        vo.setPermissionIds(Arrays.asList(new long[]{1L,2L,3L,4L}));
        permissionBiz.list3(vo).forEach(System.out::println);
    }

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

 PermissionMapper.xml

  <select id="list4" resultType="java.util.Map">
  select * from t_easyui_permission
</select>

PermissionMapper

    List<Map> list4();

PermissionBiz

List<Map> list4();

PermissionBizImpl

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

测试

    @Test
    public void list4() {
        permissionBiz.list4().forEach(System.out::println);
    }

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

 PermissionMapper.xml

  <select id="list5" resultType="java.util.Map" parameterType="java.util.Map">
  select * from t_easyui_permission where id = #{id}
</select>

PermissionMapper

 Map list5(Map map);

PermissionBiz

Map list5(Map map);

PermissionBizImpl

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

测试

 @Test
    public void list5() {
        Map map=new HashMap();
        map.put("id",1);
        System.out.println(permissionBiz.list5(map));
    }

说明不管返回一条数据,还是多条数据,都应该用java.util.Map进行接收--> <!--如果是一条数据,那么返回值是Map。如果是多条数据,那么返回值是ListMap

四、分页查询

为什么要重写mybatis的分页?

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

使用分页插件步奏

导入分页相关的pom依赖

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

 Mybatis.cfg.xml配置拦截器

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

 注意:拦截器要放在运行环境上面

使用分页插件

 PermissionMapper.xml

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

PageBean

package com.oyang.util;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Map;

public class PageBean implements Serializable {

	private static final long serialVersionUID = 2422581023658455731L;

	//页码
	private int page=1;
	//每页显示记录数
	private int rows=10;
	//总记录数
	private int total=0;
	//是否分页
	private boolean isPagination=true;
	//上一次的请求路径
	private String url;
	//获取所有的请求参数
	private Map<String,String[]> map;
	
	public PageBean() {
		super();
	}
	
	//设置请求参数
	public void setRequest(HttpServletRequest req) {
		String page=req.getParameter("page");
		String rows=req.getParameter("rows");
		String pagination=req.getParameter("pagination");
		this.setPage(page);
		this.setRows(rows);
		this.setPagination(pagination);
		this.url=req.getContextPath()+req.getServletPath();
		this.map=req.getParameterMap();
	}
	public String getUrl() {
		return url;
	}

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

	public Map<String, String[]> getMap() {
		return map;
	}

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

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		this.page = page;
	}
	
	public void setPage(String page) {
		if(null!=page&&!"".equals(page.trim()))
			this.page = Integer.parseInt(page);
	}

	public int getRows() {
		return rows;
	}

	public void setRows(int rows) {
		this.rows = rows;
	}
	
	public void setRows(String rows) {
		if(null!=rows&&!"".equals(rows.trim()))
			this.rows = Integer.parseInt(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 isPagination;
	}
	
	public void setPagination(boolean isPagination) {
		this.isPagination = isPagination;
	}
	
	public void setPagination(String isPagination) {
		if(null!=isPagination&&!"".equals(isPagination.trim()))
			this.isPagination = Boolean.parseBoolean(isPagination);
	}
	
	/**
	 * 获取分页起始标记位置
	 * @return
	 */
	public int getStartIndex() {
		//(当前页码-1)*显示记录数
		return (this.getPage()-1)*this.rows;
	}
	
	/**
	 * 末页
	 * @return
	 */
	public int getMaxPage() {
		int totalpage=this.total/this.rows;
		if(this.total%this.rows!=0)
			totalpage++;
		return totalpage;
	}
	
	/**
	 * 下一页
	 * @return
	 */
	public int getNextPage() {
		int nextPage=this.page+1;
		if(this.page>=this.getMaxPage())
			nextPage=this.getMaxPage();
		return nextPage;
	}
	
	/**
	 * 上一页
	 * @return
	 */
	public int getPreivousPage() {
		int previousPage=this.page-1;
		if(previousPage<1)
			previousPage=1;
		return previousPage;
	}

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

PermissionMapper

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

PermissionBiz

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

PermissionBizImpl

    @Override
    public List<Map> listPager(Map map, PageBean pageBean) {
       //分页插件相关的代码
        if(pageBean!=null&&pageBean.isPagination()){
            PageHelper.startPage(pageBean.getPage(),pageBean.getRows());
        }
        List<Map> maps = permission.listPager(map);
        if(pageBean!=null&&pageBean.isPagination()){
        //处理查询结果的前提:是需要分页的
            PageInfo info=new PageInfo(maps);
            pageBean.setTotal(info.getTotal()+"");
        }
        return maps;
    }

测试

    @Test
    public void listPager() {
        Map map=new HashMap();
        map.put("name","架");
//        permissionBiz.listPager(map).forEach(System.out::println);
        PageBean pageBean=new PageBean();
        //查询出第一个的2条数据
        pageBean.setPage(1);
        pageBean.setRows(2);
        permissionBiz.listPager(map,pageBean).forEach(System.out::println);
    }
}

五、特殊字符处理 

在配置文件里面,< > 都有特殊的含义的--标签

   >(&gt;)   
    <(&lt;)  
    &(&amp;) 
 空格(&nbsp;)
 <![CDATA[ <= ]]> 

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

    >(&gt;) ; <(&lt;);  

 PermissionMapper.xml

<select id="list6" resultType="com.oyang.model.Permission" parameterType="com.oyang.model.PermissionVo">
    select * from t_easyui_permission
    <where>
      <if test="null != min and min != ''">
        <![CDATA[  and #{min} < pid ]]>
      </if>
      <if test="null != max and max != ''">
        <![CDATA[ and #{max} > pid ]]>
      </if>
    </where>
  </select>

  <select id="list7" resultType="com.oyang.model.Permission" parameterType="com.oyang.model.PermissionVo">
    select * from t_easyui_permission
    <where>
      <if test="null != min and min != ''">
        and #{min} &lt; pid
      </if>
      <if test="null != max and max != ''">
        and #{max} &gt; pid
      </if>
    </where>
  </select>

 PermissionVo

package com.oyang.model;

import java.util.List;

/**
 * @author oyang
 * @site https://blog.csdn.net
 * @qq 1828190940
 * @create  2022-08-12 11:42
 */
public class PermissionVo extends Permission{
    private List permissionIds;
    private  int min;
    private  int max;

    public int getMin() {
        return min;
    }

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

    public int getMax() {
        return max;
    }

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

    public List getPermissionIds() {
        return permissionIds;
    }

    public void setPermissionIds(List permissionIds) {
        this.permissionIds = permissionIds;
    }

}

 PermissionMapper

     * 处理特殊字符
     * @return
     */
    List<Permission> list6(PermissionVo permissionVo);


    /**
     * 处理特殊字符
     * @return
     */
    List<Permission> list7(PermissionVo permissionVo);

 PermissionBiz

    List<Permission> list6(PermissionVo permissionVo);

    List<Permission> list7(PermissionVo permissionVo);

 PermissionBizimpl

   @Override
    public List<Permission> list6(PermissionVo permissionVo) {
        return permission.list6(permissionVo);
    }

    @Override
    public List<Permission> list7(PermissionVo permissionVo) {
        return permission.list7(permissionVo);
    }

测试

    @Test
    public void list6() {
        PermissionVo vo=new PermissionVo();
        vo.setMax(7);
        vo.setMin(0);
        permissionBiz.list6(vo).forEach(System.out::println);
    }

    @Test
    public void list7() {
        PermissionVo vo=new PermissionVo();
        vo.setMax(7);
        vo.setMin(0);
        permissionBiz.list7(vo).forEach(System.out::println);
    }


 OK,今日的学习就到此结束啦,如果对个位看官有帮助的话可以留下免费的赞哦(收藏或关注也行),如果文章中有什么问题或不足以及需要改正的地方可以私信博主,博主会做出改正的。个位看官,小陽在此跟大家说拜拜啦   

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Mybatis 是一种流行的 Java 持久化框架,它提供了许多方便的查询功能。模糊查询和分页查询都是实际开发中经常使用的功能,下面我们来介绍一下如何在 Mybatis 中进行模糊查询并分页。 对于模糊查询,我们可以使用 Mybatis动态 SQL 功能来实现。比如,我们需要查询名字中含有 "张" 的用户,可以使用以下语句: ```xml <select id="findUsersByName" resultType="User"> SELECT * FROM user WHERE name LIKE #{name} </select> ``` 在上面的语句中,#{name} 是一个占位符,后面可以传入一个字符串来代替。在实际使用中,我们可以在传入字符串的前后加上 "%",表示模糊匹配。 ```java String name = "%张%"; List<User> users = mapper.findUsersByName(name); ``` 上面的代码中,我们将 "%" 和查询条件串接在一起,并调用了一个 mapper 方法来执行查询。这样就可以实现简单的模糊查询了。 接下来,我们看看如何进行分页查询Mybatis 内置了一个 RowBounds 类来实现分页查询。RowBounds 通过两个参数来指定查询的结果集范围,分别是 offset 和 limit。其中 offset 表示查询的起始位置,limit 表示查询的条数。 ```java RowBounds rowBounds = new RowBounds(offset, limit); List<User> users = mapper.findUsers(rowBounds); ``` 在上面的代码中,我们使用了 RowBounds 来进行分页查询。offset 表示查询的起始位置,limit 表示查询的条数。mapper.findUsers() 方法会返回一个 List,表示查询结果集。 如果我们需要同时进行模糊查询和分页查询,就可以将它们结合起来,比如: ```java String name = "%张%"; int offset = 0; int limit = 10; RowBounds rowBounds = new RowBounds(offset, limit); List<User> users = mapper.findUsersByName(name, rowBounds); ``` 这样就可以同时进行模糊查询和分页查询了。在实际开发中,我们还可以将查询条件封装成一个对象,方便使用。比如: ```java public class UserQuery { private String name; private int offset; private int limit; // getters 和 setters 略 public RowBounds getRowBounds() { return new RowBounds(offset, limit); } } UserQuery query = new UserQuery(); query.setName("%张%"); query.setOffset(0); query.setLimit(10); List<User> users = mapper.findUsersByName(query.getName(), query.getRowBounds()); ``` 总之, Mybatis 提供了非常方便的动态 SQL 功能和 RowBounds 分页功能,方便我们进行灵活的查询操作。在实际开发中,需要注意查询效率和代码复杂度的平衡,避免过度复杂的查询

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

歐陽。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值