目录
在自定义MVC时,像我们写修改的sql语句,比如:
update t_student set sid =?,sname=?,sex=?,sage=?.. where sid=?
如下图,在IDEA中Maven项目中逆向生成的修改语句则大大不同,它添加了if判断
自定义MVC的sql语句的弊端:
假如一个学生编辑界面 student.jsp
我们传了两个值进去,意味着后台student实体类
只有sname,sex属性值没有为空,其他为空,进一步的我们的sql语句会演成如下:
update t_student set sname=张三,sex=男,sage=null.. where sid=?
其他的全为null空值
如果是下面这种sql语句,它能将前台的没有的值直接剔除掉,这就是if标签的作用
update t_student sname = 张三 sex= 男where bid = #{bid,jdbcType=INTEGER}
比如:Integer[ ] ints = {1,2,3,4,5,6}-->1,2,3,4,5,6
将上面的数组变成一个字符串
我们通常是foreach遍历
StringBuffer sb = new StringBuffer();
for(int i:ints){
sb.append(i).apped(",");
}
System.out.println(sb);
像这样的话结果最后会多出一个逗号:
1,2,3,4,5,6,
我们用substring去截掉最后一个逗号,如下结果
1,2,3,4,5,6
mybatis提供了foreach标签,只需要我们提供数组就可以了
在IDEAMaven项目自动生成的增删改查代码BookMapper.xml中在写一个查询语句
-
- select
-
"Base_Column_List" /> - from t_mvc_book
- where bid in
-
"bookIds" open="(" close=")" separator="," item="bid"> - #{bid}
-
-
在我们 BookMapper中添加该方法

在bookBiz添加
- package com.zwc.biz;
-
- import com.zwc.model.Book;
-
- import java.util.List;
-
- /**
- * @authorzwc
- * @site www.javazwc.com
- * @company xxx公司
- * @create 2022-08-10 21:22
- */
- public interface BookBiz {
- int deleteByPrimaryKey(Integer bid);
-
- Book selectByPrimaryKey(Integer bid);
-
- List
selectByIn(List bookIds); - }
Alt+enter在BookBizImpl添加

BookBizImpl:

在BookBizImpl光标放在方法上,ALt+enter键添加在test类

Test测试类:

三种模糊查询方式 :#、$、concat
- <select id="selectBooksLike1" resultType="com.zwc.model.Book" parameterType="java.lang.String">
- select * from t_mvc_book where bname like #{bname}
- </select>
- <select id="selectBooksLike2" resultType="com.zwc.model.Book" parameterType="java.lang.String">
- select * from t_mvc_book where bname like '${bname}'
- </select>
- <select id="selectBooksLike3" resultType="com.zwc.model.Book" parameterType="java.lang.String">
- select * from t_mvc_book where bname like concat(concat('%',#{bname}),'%')
- </select>
在Bookmapper.xml中加入下面三中模糊查询方法

在BookMapper.java中加入方法

在BookBiz中加入方法

在实现类BookBizimpl中加入
@Override public ListselectBooksLike1(String bname) { return bookMapper.selectBooksLike1(bname); } @Override public List selectBooksLike2(String bname) { return bookMapper.selectBooksLike2(bname); } @Override public List selectBooksLike3(String bname) { return bookMapper.selectBooksLike3(bname); }
测试:
第一种模糊查询:

Sql语句:

第二个方法控制台查询结果和sql语句

总结:
我们可以看出第一种模糊查询的sql语句条件后是占位符
第二中是参数传入
可以得出:
MyBatis中#和$的区别
1. # 将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。
如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by '111',
如果传入的值是id,则解析成的sql为order by "id".
2. $ 将传入的数据直接显示生成在sql中。
如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,
如果传入的值是id,则解析成的sql为order by id.
3. #方式能够很大程度防止sql注入。
4. $方式无法防止Sql注入。
5. $方式一般用于传入数据库对象,例如传入表名.
6. 一般能用#的就别用$.
第三种
与第一、二不同的是第三不需要加百分号

将下面方法中加入BookMapper
对比一下list1和list2自定义MVC中的baseDao
executeQuery-——>list
——>单表查询——>Mybatis中的ResultType executeQuery-——>list
将下面的resultMap改成resultType


测试:

可以看到方法同样测试成功,说明如果是单表的情况下,resultMap与resultType都可以使用
传了一个对象BookVo

BookVo:
- package com.zwc.model;
-
- import java.util.List;
-
- /**
- * @authorzwc
- * @site www.javazwc.com
- * @company xxx公司
- * @create 2022-08-12 9:01
- */
- public class BookVO extends Book{
- private List bookIds;
-
- public List getBookIds() {
- return bookIds;
- }
-
- public void setBookIds(List bookIds) {
- this.bookIds = bookIds;
- }
- }
BookBiz:
- List
list1() ; - List
list2() ; -
- List
list3(BookVO vo) ; -
- List;
- Map list5(Map map);
BookBizImpl:
- @Override
- public List
list1() { - return bookMapper.list1();
- }
-
- @Override
- public List
list2() { - return bookMapper.list1();
- }
-
- @Override
- public List
list3(BookVO vo) { - return bookMapper.list3(vo);
- }
-
- @Override
- public List
- return bookMapper.list4();
- }
-
- @Override
- public Map list5(Map map) {
- return bookMapper.list5(map);
- }
list1:

list2:

从list1和list2可以得出结论:
list1和list2的结论是:对于单表查询而言,可以用ResultMap/ResultType接受,但是多表必须使用Resultmap接受
list3:
如果相传多个参数,在bookvo中加入即可

list4:

list5 :

结论:
在上述的list4和list5两个方法中说明了不管返回一条数据,还是多条数据,都应该用java.util.Map进行接收,如果是一条数剧,那么返回值是Map,如果是多条,那么返回值是list
将下面的分页插接件代码放入pom.xml
org.apache.logging.log4j log4j-web 2.9.1
在将分页拦截器以下放入Mybatis.cfg.xml
| <plugins>
|
要放在在配置环境前
util工具类:
- package com.zwc.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
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
getMap() { - return map;
- }
-
- public void setMap(Map
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
- + "]";
- }
- }
BookMapper写入方法:

BookBiz:
BookBizimpl :
- @Override
- public List
- // 分页插件相关代码,固定代码
- // 判断是否分页
- if(pageBean!=null&&pageBean.isPagination()){
- // 拿到页数和行数
- PageHelper.startPage(pageBean.getPage(),pageBean.getRows());
- }
- //核心部分 结果
- List
-
- if(pageBean!=null&& pageBean.isPagination()){
- // 处理结果的前提,是需要分页的
- // maps经过第三方插件进行处理 分页
- PageInfo info = new PageInfo(maps);
- pageBean.setTotal(info.getTotal()+"");
- }
-
- return maps;
- }
测试类:
- @Test
- public void listPage() {
- Map map = new HashMap();
- map.put("bname","圣墟");
- // 查询出第二页20条数据
- PageBean pageBean = new PageBean();
- pageBean.setPage(2);
- pageBean.setRows(20);
-
- bookBiz.listPage(map,pageBean).forEach(System.out::println);
-
- }
结果:


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

BookMapper:
- select * from t_mvc_book
-
- <if test="null != min and min != ''">
-
- if>
- <if test="null != max and max != ''">
- price ]]>
- if>
-
-
-
-
- select * from t_mvc_book
-
- <if test="null != min and min != ''">
- and #{min} < price
- if>
- <if test="null != max and max != ''">
- and #{max} > price
- if>
-
-
Bookbiz:
-
- List
list6(BookVO bookVo); -
-
- List
list7(BookVO bookVo);
BookBizimpl:
- @Override
- public List
list6(BookVO bookVo) { - return bookMapper.list6(bookVo);
- }
-
- @Override
- public List
list7(BookVO bookVo) { - return bookMapper.list7(bookVo);
- }
Test:
- @Test
- public void list6() {
- BookVO vo = new BookVO();
- vo.setMin(44);
- vo.setMin(28);
- bookBiz.list6(vo).forEach(System.out::println);
- }
-
- @Test
- public void list7() {
- BookVO vo = new BookVO();
- vo.setMin(44);
- vo.setMin(28);
- bookBiz.list7(vo).forEach(System.out::println);
- }
结果:
list6:

list7:

当我们修改符号测试,会报错

会报sql语句有错
所以我们在比较的时候不要使用< 、>不然会报错,因为< 、>会与标签的前括号冲突
使用<、>