Mybatis单表操作之普通操作、模糊查询、分页查询、动态SQL 您所在的位置:网站首页 mybatis一对多分页查询不能用collection Mybatis单表操作之普通操作、模糊查询、分页查询、动态SQL

Mybatis单表操作之普通操作、模糊查询、分页查询、动态SQL

#Mybatis单表操作之普通操作、模糊查询、分页查询、动态SQL| 来源: 网络整理| 查看: 265

目录

前言

1、构建数据库

2、 普通操作

3、模糊查询

4、分页查询

​5、动态SQL

前言

最近有点学累了,很久没有学习新东西了,花了一个晚上的时间归纳和整理了Mybatis对表的操作,主要是对单表进行操作,包括基本的单表操作CRUD,以及模糊查询、分页查询及动态SQL等 。后面会陆续把一对多,多对一查询及多表查询整理一下。

1、构建数据库

在学习之前,你首先要先建一个数据库,本文用Navicat建了一个数据库ssmbuild,里面放了一张books表。然后,把核心配置文件、实体类、工具类等等先写好,该部分可以参考博主以往的博客

CREATE DATABASE `ssmbuild`; USE `ssmbuild`; DROP TABLE IF EXISTS `books`; CREATE TABLE `books` ( `bookID` INT(10) NOT NULL COMMENT '书id', `bookName` VARCHAR(100) NOT NULL COMMENT '书名', `bookCounts` INT(11) NOT NULL COMMENT '数量', `detail` VARCHAR(200) NOT NULL COMMENT '描述', PRIMARY KEY `bookID` (`bookID`) ) ENGINE=INNODB DEFAULT CHARSET=utf8 INSERT INTO `books`(`bookID`,`bookName`,`bookCounts`,`detail`)VALUES (1,'Java',1,'从入门到放弃'), (2,'MySQL',10,'从删库到跑路'), (3,'Linux',5,'从进门到进牢'), (4,'Java',15,'Java修仙手册'), (5,'C++',25,'C++致命宝典');

2、 普通操作

(1) 查询书籍

查询书籍,既可以查询全部书籍,也可以根据id去查询,当然后面会用到动态查询(可以根据某个字段进行模糊查询)。由于SQL语句较简单,所以这里用注解的方式实现 ,因为查询所有书籍会返回若干条记录,所以用集合来保存,最后用增强for去打印集合

//查询所有的书籍 @Select("select *from ssmbuild.books") List queryAllBooks(); //根据BookId查询相应的书籍 @Select("select *from ssmbuild.books where bookID=#{id}") Books queryBooksById(@Param("id") int BookID); @Test public void test1() { SqlSession sqlSession = MybatisUtils.getSqlSession(); BookMapper mapper = sqlSession.getMapper(BookMapper.class); List allBooks = mapper.queryAllBooks(); for (Books books : allBooks) { System.out.println(books); } sqlSession.close(); } @Test public void test5(){ SqlSession sqlSession=MybatisUtils.getSqlSession(); BookMapper mapper = sqlSession.getMapper(BookMapper.class); Books books = mapper.queryBooksById(5); System.out.println(books); sqlSession.close(); }

(2) 增加书籍

可以用带参构造方法和map键值对来增加书籍,返回类型void和int均可,注意实体类的成员变量属性要与数据库字段名一致,否者用resultmap将column与properties对应起来也是可以滴

//用带参构造方法增加书籍 int addBooks(Books books); //用map键值对增加书籍 int addBooks2(Map map); insert into ssmbuild.books (bookID, bookName, bookCounts, detail) VALUES (#{bookID}, #{bookName}, #{bookCounts}, #{detail}) insert into ssmbuild.books (bookID, bookName, bookCounts, detail) VALUES (#{bookID}, #{bookName}, #{bookCounts}, #{detail}) @Test public void test6(){ SqlSession sqlSession=MybatisUtils.getSqlSession(); BookMapper mapper = sqlSession.getMapper(BookMapper.class); int res = mapper.addBooks(new Books(8, "kali", 1000, "kali学的好,号子蹲的早")); if (res>0){ System.out.println("增加书籍成功!"); } sqlSession.commit(); sqlSession.close(); } @Test public void test7(){ SqlSession sqlSession=MybatisUtils.getSqlSession(); BookMapper mapper = sqlSession.getMapper(BookMapper.class); Map map=new HashMap(); map.put("bookID",9); map.put("bookName","一支红杏出墙来"); map.put("bookCounts",300); map.put("detail","小王老师又一巨作"); int res = mapper.addBooks2(map); if (res>0){ System.out.println("插入成功!"); } sqlSession.commit(); sqlSession.close(); }

注:增删改, 均变动了数据库记录,需要提交事务,有两种方式:上面代码commit方式是一种,还有一种一劳永逸的方式,即将工具类里调用openSession的方法改为true。

(3) 删除书籍

这里是根据id去删除书籍,后面可以用动态sql之foreach去批量删除书籍 

int deleteBooks(@Param("id") int BookID); delete from ssmbuild.books where bookID = #{id}

 (4)更新书籍

普通的更新,除了主键外,所有的字段都需要进行更新,后面可以用动态更新,哪里想更,更哪里,妈妈再也不要担心我的学习了。 

int updateBooks(Books books); update ssmbuild.books set bookName = #{bookName}, bookCounts=#{bookCounts}, detail=#{detail} where bookID = #{bookID} @Test public void test10(){ SqlSession sqlSession=MybatisUtils.getSqlSession(); BookMapper mapper = sqlSession.getMapper(BookMapper.class); int res = mapper.updateBooks(new Books(7, "数据库", 1000, "从入库到跑路")); if (res>0){ System.out.println("更新成功!"); } sqlSession.commit(); sqlSession.close(); }  3、模糊查询

(1)模糊查询"%",可匹配任意类型和长度的字符 

@Select("select *from ssmbuild.books where detail like '%小王老师%'") List queryLikeBooks();

查询结果:

(2)模糊查询"_",可匹配单个任意字符,它常用来限制表达式的字符长度

@Select("select *from ssmbuild.books where detail like '从_门到__'") List queryLikeBooks1();

查询结果: 

 注:模糊查询有很多种,常用的有这两种,博主偷懒,所以用的注解的方式

4、分页查询

分页查询有limit和RowBounds分页,limit分页用的较多,limit a,b,a表示起始索引,从0开始,表示第一条记录, b表示是指从第a+1条开始,取b条。

@Select("select *from ssmbuild.books limit 5,2") List queryLimitBooks();

 查询结果:上述表示从第六条记录开始,取两条记录,所以查询结果的id应该为6,7

 5、动态SQL

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过JDBC或其它类似的框架,你应该就能理解根据不同条件拼接SQL语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。上述的CRUD都比较简单,当面对复杂的业务时,就需要写一些复杂的 SQL 语句,这时候往往需要拼接,而拼接 SQL ,稍微不注意,由于引号,空格等缺失可能都会导致错误。mybatis 利用动态SQL,通过 if, choose,when,otherwise, trim,where, set,foreach等标签,可组合成非常灵活的SQL语句,从而在提高 SQL 语句的准确性的同时,也大大提高了开发人员的效率。

(1)动态SQL之IF

//动态SQL之IF选择查询 List queryIfBooks(Map map); select *from ssmbuild.books where 1=1 bookName like #{bookName} and detail like #{detail} @Test public void test11() { SqlSession sqlSession = MybatisUtils.getSqlSession(); BookMapper mapper = sqlSession.getMapper(BookMapper.class); HashMap map =new HashMap(); map.put("detail","%小王%"); //map.put("bookName","%Java%"); List allBooks = mapper.queryIfBooks(map); for (Books books : allBooks) { System.out.println(books); } sqlSession.close(); }

为啥这里要用sql注入(where1=1)的方式 ?这里“where 1”,“where true”也都可以 ,去掉1=1,你就能发现问题所在了。只要跳过bookName字段,对detail字段进行查询时,系统就拼接不起来了,正常语句where后面都要加上判断的条件。所以where1=1的方式能保证对查询条件进行拼接并保证查询能进行下去。当然这里推荐使用where标签,where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句,什么意思呢?就是说在匹配不到合适的字段条件时,where字段不加上去,就成了“select *from  ssmbuild.books”了,变成查询所有字段了。若子句的开头为 “AND” 或 “OR”,where 元素会将它们去除。像下面的错误,用上where标签,就会舍弃and,成了“select *from  ssmbuild.books where detail like 条件”,能查询出与detail标签相关的内容了。

加上where标签,用IF同时对bookName和detail进行模糊查询时,你会发现什么都查不出来,也许你会说博主这不是在胡说八道吗,但我想在这先卖个关子,这就是上面为啥要先注释掉一条了。

(2) 动态Sql之set

set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。

int updateSetBooks(Map map); update ssmbuild.books bookName=#{bookName}, bookCounts=#{bookCounts}, detail=#{detail} where bookID=#{bookID} @Test public void test12() { SqlSession sqlSession = MybatisUtils.getSqlSession(); BookMapper mapper = sqlSession.getMapper(BookMapper.class); HashMap map =new HashMap(); map.put("bookID",7); map.put("bookName","大数据"); int res = mapper.updateSetBooks(map); if (res>0){ System.out.println("更新成功!"); } sqlSession.commit(); sqlSession.close(); }

这里用set对7号书籍的书籍名称进行修改,原表是数据库,现在应该是改成大数据了。 

(3)动态SQL之Choose

动态SQL之Choose,跟if查询类似,但if需要同时满足多个查询条件,而choose满足一个就会查出,现在就解开上面卖的关子。

List queryChooseBooks(Map map); select *from ssmbuild.books bookName like #{bookName} AND bookCounts like #{bookCounts} AND detail like #{detail} AND featured = 1 @Test public void test13() { SqlSession sqlSession = MybatisUtils.getSqlSession(); BookMapper mapper = sqlSession.getMapper(BookMapper.class); HashMap map =new HashMap(); map.put("detail","%小王%"); map.put("bookName","%Java%"); List allBooks = mapper.queryChooseBooks(map); for (Books books : allBooks) { System.out.println(books); } sqlSession.close(); }

这里的junit测试单元是不是在哪见过?对的,跟if查询不要说一毛一样,简直就是双胞胎,也就方法名不同而已。那结果呢?话不多说,看图。if要条件全部满足才能查出,而choose查到一个就不会继续查了,有点类似多分支Switch语句。

(4) 动态SQL之foreach

动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值(官方文档说的很清楚)。我们这用foreach实现批量删除,当然还可以用来实现批量增加记录。

//使用foreach批量删除书籍 void deleteSomeBooks(List list);

注:尽量不要像博主一样在配置文件中加中文 ,有时会报错,具体怎么解决,参考博主以往文章

delete from ssmbuild.books where bookID in #{id}

这里是删除id=9到id=18之间的书籍记录 

@Test public void test8(){ SqlSession sqlSession=MybatisUtils.getSqlSession(); BookMapper mapper = sqlSession.getMapper(BookMapper.class); ArrayList list = new ArrayList(); for (int num=9;num0){ System.out.println("更新成功!"); } sqlSession.close(); }

 我又把大数据改为数据库了,有点强迫症,结果如下:

所有的项目文件结构如下所示:



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有