Mybatis分页查询与动态SQL
一、Mybatis的分页查询
由于第一二节较为详细讲述了Mybatis的环境搭建,文件配置,SQL编写和Java代码实现,所以接下来的讲述都将只抽取关键代码和mapper文件中的关键sql,详细的流程和案例可参见《Mybatis入门和简单Demo》和《Mybatis的CRUD案例》。
(1)无条件的分页的mapper文件配置和Java代码实现
<!-- 传入的参数类型为map,此时无需使用map.get("key")去获得实际值,只需填入key值便可 --> <select id="findByPage" parameterType="map" resultMap="studentMap"> select id,name,age,sex from student limit #{start},#{end} </select>
/* * 无条件分页查询 */ public List<Student> findByPage(int start,int end) { SqlSession sqlSession = null; try{ sqlSession = MyBatisUtil.getSqlSession(); Map<String,Object> param = new LinkedHashMap<String,Object>(); param.put("start",start); param.put("end",end); List<Student> stuList; stuList = sqlSession.selectList(Student.class.getName()+".findByPage", param); System.out.println("添加查询成功"); return stuList; }catch(Exception e){ e.printStackTrace(); throw e; }finally{ MyBatisUtil.closeSqlSession(); } }
(2)有条件的分页的mapper文件配置和Java代码实现
<select id="findByPageAndRequest" parameterType="map" resultMap="studentMap"> select id,name,age,sex from student where name like #{name} limit #{start},#{end} </select>
/* * 有条件分页查询 */ public List<Student> findByPageAndRequest(String name,int start,int end) { SqlSession sqlSession = null; try{ sqlSession = MyBatisUtil.getSqlSession(); Map<String,Object> params = new LinkedHashMap<String,Object>(); //当sql的条件有模糊匹配时,参数需前后带上% params.put("name", "%"+name+"%"); params.put("start", start); params.put("end", end); List<Student> stuList; stuList = sqlSession.selectList(Student.class.getName() +".findByPageAndRequest", params); System.out.println("添加查询成功"); return stuList; }catch(Exception e){ e.printStackTrace(); throw e; }finally{ MyBatisUtil.closeSqlSession(); } }
二、Mybatis的动态SQL
Mybatis除了支持简单的sql外,还支持多种动态sql语句,如条件判断,参数遍历,包含等等语法,下面通过一些例子简单认识下Mybatis对动态sql的支持
(1)动态条件查询:查询时编写where条件,判断传入的参数不为空才予以拼接,条件写在<if test="xx">标签中
<select id="findAll" parameterType="map" resultMap="studentMap"> select * from student <where> <if test="id!=null"> and id = #{id} </if> <if test="name!=null"> and name = #{name} </if> <if test="age!=null"> and age = #{age} </if> <if test="sex!=null"> and sex = #{sex} </if> </where> </select>
/* * 动态带条件查询 */ public List<Student> findAll(String id,String name,String age,String sex) { SqlSession sqlSession = null; try{ sqlSession = MyBatisUtil.getSqlSession(); Map<String,Object> stuMap = new HashMap<String,Object>(); stuMap.put("id", id); stuMap.put("name", name); stuMap.put("age", age); stuMap.put("sex", sex); return sqlSession.selectList(Student.class.getName()+".findAll", stuMap); }catch(Exception e){ e.printStackTrace(); throw e; }finally{ MyBatisUtil.closeSqlSession(); } }
(2)动态条件更新:查询时编写where条件,判断传入的参数不为空才予以拼接,其中判断条件中xx=#{xx}后需要带",",set标签会自动判断哪个是最后一个字段,会自动去掉最后一个","号
<!-- set标签会自动判断哪个是最后一个字段,会自动去掉最后一个","号 --> <update id="update" parameterType="map"> update student <set> <if test="name!=null"> name = #{name}, </if> <if test="age!=null"> age = #{age}, </if> <if test="sex!=null"> sex = #{sex}, </if> </set> where id = #{id} </update>
/* * 动态带条件更新 */ public List<Student> update(String id,String name,String age,String sex) { SqlSession sqlSession = null; try{ sqlSession = MyBatisUtil.getSqlSession(); Map<String,Object> updateMap = new HashMap<String,Object>(); updateMap.put("id", id); updateMap.put("name", name); updateMap.put("age", age); updateMap.put("sex", sex); sqlSession.update(Student.class.getName()+".update",updateMap); sqlSession.commit(); return null; }catch(Exception e){ e.printStackTrace(); sqlSession.rollback(); throw e; }finally{ MyBatisUtil.closeSqlSession(); } }
(3)动态条件删除:遍历传入的参数,可以为数组,也可以为list结构,判断集合或数组中的字段值与表中某字段值相匹配则删除
<!-- foreach用于遍历数组元素 open表示开始符号 close表示结束符号 separator表示中间分隔符 item表示数组参数,属性值可以任意,但提倡与方法参数相同 --> <delete id="dynamicDelete"> delete from student where id in <foreach collection="array" open="(" close=")" separator="," item="ids"> #{ids} </foreach> </delete> <delete id="dynamicDeleteList"> delete from student where id in <foreach collection="list" open="(" close=")" separator="," item="ids"> #{ids} </foreach> </delete>
/* * 动态带条件删除 */ public void dynamicDelete(String... ids) { SqlSession sqlSession = null; try{ sqlSession = MyBatisUtil.getSqlSession(); sqlSession.delete(Student.class.getName()+".dynamicDelete",ids); sqlSession.commit(); }catch(Exception e){ e.printStackTrace(); throw e; }finally{ MyBatisUtil.closeSqlSession(); } } /* * 动态带条件List批量删除 */ public void dynamicDeleteList(List<String> ids) { SqlSession sqlSession = null; try{ sqlSession = MyBatisUtil.getSqlSession(); sqlSession.delete(Student.class.getName()+".dynamicDeleteList",ids); sqlSession.commit(); }catch(Exception e){ e.printStackTrace(); throw e; }finally{ MyBatisUtil.closeSqlSession(); } }
(4)动态条件增加:在编写插入语句时,可通过<include refid="xx"/>标签来引入不同的sql片段,而sql片段可事先定义并配置好,通过refid的值来关联不同的片段从而实现对应字段插入对应的值。
<!-- 可通过<include refid="xx"/>标签来引入不同的sql片段,如<include refid="key"/>表示参数对应的表字段 <include refid="value"/> 表示字段对应的值--> <insert id="dynamicInsert" parameterType="dynamicstudent"> insert into student(<include refid="key"/>) values(<include refid="value"/>) </insert> <!-- SQL片段对应字段名 --> <sql id="key"> <if test="id!=null"> id, </if> <if test="name!=null"> name, </if> <if test="age!=null"> age, </if> <if test="sex!=null"> sex </if> </sql> <!-- SQL片段对应占位符? --> <sql id="value"> <if test="id!=null"> #{id}, </if> <if test="name!=null"> #{name}, </if> <if test="age!=null"> #{age}, </if> <if test="sex!=null"> #{sex} </if> </sql>
/* * 动态插入数据 */ public void dynamicInsert(Student stu) { SqlSession sqlSession = null; try{ sqlSession = MyBatisUtil.getSqlSession(); sqlSession.insert(Student.class.getName()+".dynamicInsert", stu); sqlSession.commit(); }catch(Exception e){ e.printStackTrace(); throw e; }finally{ MyBatisUtil.closeSqlSession(); } }