目录
使用${...}代替#{...}(不建议使用该方式,有SQL注入风险)
使用resultType返回List,适用于多表查询返回结果集
使用resultType返回Map,适用于多表查询返回单个结果集 ,object>
一、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);
}
}
五、特殊字符处理
在配置文件里面,< > 都有特殊的含义的--标签
>(>)
<(<)
&(&)
空格( )
<![CDATA[ <= ]]>
被CDATA所包裹的特殊字符,都会被转义成SQL语句中的字符
>(>) ; <(<);
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} < pid
</if>
<if test="null != max and max != ''">
and #{max} > 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,今日的学习就到此结束啦,如果对个位看官有帮助的话可以留下免费的赞哦(收藏或关注也行),如果文章中有什么问题或不足以及需要改正的地方可以私信博主,博主会做出改正的。个位看官,小陽在此跟大家说拜拜啦