MyBatis动态sql
在接口中定义方法
然后alt加回车在xml中如图:
1.if 语句 (简单的条件判断)
2. choose (when,otherwize) ,相当于java 语言中的 switch ,与 jstl 中的choose 很类似
3. trim (对包含的内容加上 prefix,或者 suffix 等,前缀,后缀)
4. where (主要是用来简化sql语句中where条件判断的,能智能的处理 and or ,不必担心多余导致语法错误)、
5. set (主要用于更新时)
6. foreach (在实现 mybatis in 语句查询时特别有用)
测试:
@Test public void selectByIn() { List list = new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(10003); List<Book> books = this.bookService.selectByIn(list); for(Book b : books){ System.out.println(b); } }
展示:
模糊查询
这里演示3种:
接口:
List<Book> selectBylike1(@Param("bname") String bname); List<Book> selectBylike2(@Param("bname") String bname); List<Book> selectBylike3(@Param("bname") String bname);
映射文件
<select id="selectBylike1" resultType="com.cjh.model.Book" parameterType="java.lang.String"> select * from t_mvc_book where bname like #{bname} </select> <select id="selectBylike2" resultType="com.cjh.model.Book" parameterType="java.lang.String"> select * from t_mvc_book where bname like '${bname}' </select> <select id="selectBylike3" resultType="com.cjh.model.Book" parameterType="java.lang.String"> select * from t_mvc_book where bname like concat(concat('%',#{bname},'%')) </select>
注意:#{...}自带引号,${...}有sql注入的风险
测试:
@Test public void selectBylike() { // List<Book> books = this.bookService.selectBylike1(StringUtils.toLikeStr("圣墟")); // List<Book> books = this.bookService.selectBylike2("%圣墟 or bid!=1%");//这种方式存在sql攻击 List<Book> books = this.bookService.selectBylike3("圣墟"); for(Book b : books){ System.out.println(b); } }
其中StringUtils:
public class StringUtils { public static String toLikeStr(String str){ return "%"+str+"%"; } }
结果:
查询返回结果集的处理
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>,适用于多表查询返回单个结果集
接口:
// 3.1 使用resultMap返回自定义类型集合 List<Book> list1(); // 3.2 使用resultType返回List<T> List<Book> list2(); // 3.3 使用resultType返回单个对象 Book list3(BookVo bookVo); // 3.4 使用resultType返回List<Map>,适用于多表查询返回结果集 List<Map> list4(Map map); // 3.5 使用resultType返回Map<String,Object>,适用于多表查询返回单个结果集 Map list5(Map map);
BookVo类:
public class BookVo extends Book{ private List<String> bookIds; public List<String> getBookIds() { return bookIds; } public void setBookIds(List<String> bookIds) { this.bookIds = bookIds; } }
映射文件:
<select id="list1" resultMap="BaseResultMap"> select * from t_mvc_book </select> <select id="list2" resultType="com.cjh.model.Book"> select * from t_mvc_book </select> <select id="list3" resultType="com.cjh.model.Book" parameterType="com.cjh.model.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" parameterType="java.util.Map"> select * from t_mvc_book <where> <if test="null !=bname and bname !=''"> and bname like #{bname} </if> </where> </select> <select id="list5" resultType="java.util.Map" parameterType="java.util.Map"> select * from t_mvc_book <where> <if test="null !=bid and bid !=''"> and bid = #{bid} </if> </where> </select>
测试:
@Test public void list() { //返回resultMap但是使用list<T> // List<Book> books = this.bookService.list1(); //返回resulttype使用list<T>接收 // List<Book> books = this.bookService.list2(); // for(Book b : books){ // System.out.println(b); // } // //返回的是resulttype使用T接收 // BookVo bookVo = new BookVo(); // List list = new ArrayList(); // list.add(1); // bookVo.setBookIds(list); // Book book = this.bookService.list3(bookVo); // System.out.println(book); //返回的是resultTypr ,然后用list<Map>进行接收 Map map = new HashMap(); // map.put("bname", StringUtils.toLikeStr("圣墟")); // List<Map> list = this.bookService.list4(map); // for (Map m : list) { // System.out.println(m); // } //返回的是resultTypr ,然后用Map进行接收 map.put("bid",2); Map k = this.bookService.list5(map); System.out.println(k); }
分页查询
为什么要重写mybatis的分页?
Mybatis的分页功能很弱,它是基于内存的分页(查出所有记录再按偏移量offset和边界limit取结果),在大数据量的情况下这样的分页基本上是没有用的
使用分页插件步奏
1、导入pom依赖
2、Mybatis.cfg.xml配置拦截器
3、使用PageHelper进行分页
4、处理分页结果
Pom依赖:
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.2</version> </dependency>
Mybatis.cfg.xml配置拦截器
<plugins> <!-- 配置分页插件PageHelper, 4.0.0以后的版本支持自动识别使用的数据库 --> <plugin interceptor="com.github.pagehelper.PageInterceptor"> </plugin> </plugins>
然后在实现类中写方法:
@Override public List<Map> listPagers(Map map, PageBean pageBean) { if (pageBean != null && pageBean.isPagination()){ PageHelper.startPage(pageBean.getPage(),pageBean.getRows()); } List<Map> list = this.BookMapper.list4(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; }
测试:
@Test public void listPage() { Map map = new HashMap(); map.put("bname", StringUtils.toLikeStr("圣墟")); PageBean pageBean = new PageBean(); // pageBean.setPage(3); //不分页 pageBean.setPagination(false); List<Map> list = this.bookService.listPagers(map, pageBean); for (Map m : list){ System.out.println(m); } }
特殊字符处理:
方式一:
大于:>
小于:<
空格:&
方式二:<![CDATA[ <= ]]>
接口:
List<Map> list6(BookVo bookVo); List<Map> list7(BookVo bookVo);
映射文件:
<select id="list6" resultType="java.util.Map" parameterType="com.cjh.model.BookVo"> select * from t_mvc_book <where> <if test="null !=min and min !=''"> and price > #{min} </if> <if test="null !=max and max !=''"> and price < #{max} </if> </where> </select> <select id="list7" resultType="java.util.Map" parameterType="com.cjh.model.BookVo"> select * from t_mvc_book <where> <if test="null !=min and min !=''"> <![CDATA[ and price > #{min}]]> </if> <if test="null !=max and max !=''"> <![CDATA[ and price < #{max}]]> </if> </where> </select>
测试:
@Test public void sqlSpecial() { BookVo bookVo = new BookVo(); bookVo.setMax(80); bookVo.setMin(20); /* List<Map> maps = this.bookService.list6(bookVo);*/ List<Map> maps = this.bookService.list7(bookVo); for (Map map : maps) { System.out.println(map); } }