目录
mapper接口:
- //if 标签 多条件查询
- List
selectByMultiConditional(@Param("brand") String brand,@Param("guidePrice") Double guidePrice,@Param("carType") String carType);
mapper映射文件:
- <select id="selectByMultiConditional" resultType="Car">
- select *
- from t_car
- where 1=1
-
- <if test="brand !=null and brand!=''">
- and brand like "%"#{brand}"%"
- if>
- <if test="guidePrice !=null and guidePrice!=''">
- and guide_price > #{guidePrice}
- if>
- <if test="carType !=null and carType!=''">
- and car_type =#{carType}
- if>
- select>

测试类:
- /**
- * 使用if标签多条件查询
- */
- @Test
- public void test1(){
- SqlSession sqlSession = SqlSessionUtil.openSession();
- CarMapper mapper = sqlSession.getMapper(CarMapper.class);
- List
carList = mapper.selectByMultiConditional(null,null,null);//什么参数也没有 - carList.forEach(car -> {
- System.out.println(car);
- });
- System.out.println("--------------");
- List
carList1 = mapper.selectByMultiConditional("保时捷", 100.0, null);//两个参数 - carList1.forEach(car -> {
- System.out.println(car);
- });
- System.out.println("--------------");
- List
carList2 = mapper.selectByMultiConditional("比亚迪", 25.0, "混动"); - carList2.forEach(car -> {
- System.out.println(car);
- });
where标签的作用:让where子句更加动态智能。
mapper接口:
- //if 和 where标签一起使用
- List
selectByMultiConditionalWithWhere(@Param("brand") String brand,@Param("guidePrice") Double guidePrice,@Param("carType") String carType);
mapper映射文件:
- <select id="selectByMultiConditionalWithWhere" resultType="Car">
- select *
- from t_car
-
- <where>
- <if test="brand !=null and brand!=''">
- and brand like "%"#{brand}"%"
- if>
- <if test="guidePrice !=null and guidePrice!=''">
- and guide_price > #{guidePrice}
- if>
- <if test="carType !=null and carType!=''">
- and car_type =#{carType}
- if>
- where>
- select>
测试类:
- /**
- * 使用if 和 where 标签多条件查询
- */
- @Test
- public void test2(){
- SqlSession sqlSession = SqlSessionUtil.openSession();
- CarMapper mapper = sqlSession.getMapper(CarMapper.class);
- List
carList = mapper.selectByMultiConditionalWithWhere(null,null,null);//什么参数也没有 - carList.forEach(car -> {
- System.out.println(car);
- });
- System.out.println("--------------");
- List
carList1 = mapper.selectByMultiConditionalWithWhere("保时捷", 100.0, null);//两个参数 - carList1.forEach(car -> {
- System.out.println(car);
- });
- System.out.println("--------------");
- List
carList2 = mapper.selectByMultiConditionalWithWhere("比亚迪", 25.0, "混动"); - carList2.forEach(car -> {
- System.out.println(car);
- });
- System.out.println("--------------");
- List
carList3 = mapper.selectByMultiConditionalWithWhere(null, 100.0, null); - carList3.forEach(car -> {
- System.out.println(car);
- });
- }

总结:
使用where的标签的话可以去where语句的前面的and或者or,但是不可去除条件语句的后面的and或者or
trim标签的属性:
mapper接口:
- <select id="selectByMultiConditionalWithTrim" resultType="Car">
- select *
- from t_car
-
- <trim prefix="where" suffixOverrides="or|and">
- <if test="brand !=null and brand!=''">
- brand like "%"#{brand}"%" and
- if>
- <if test="guidePrice !=null and guidePrice!=''">
- guide_price > #{guidePrice} and
- if>
- <if test="carType !=null and carType!=''">
- car_type =#{carType}
- if>
- trim>
- select>
测试和接大差不差,就不复制粘贴啦,主要是看Trim标签怎么使用的!
主要使用在update语句当中,用来生成set关键字,同时去掉最后多余的“,”
比如我们只更新提交的不为空的字段,如果提交的数据是空或者"",那么这个字段我们将不更新。
mapper接口:
- //set 标签 通常用于更新操作
- int updateCarWithSetById(Car car);
mapper映射文件:
- <update id="updateCarWithSetById">
- update t_car
- <set>
- <if test="carNum != null and carNum != ''">car_num = #{carNum},if>
- <if test="brand != null and brand != ''">brand = #{brand},if>
- <if test="guidePrice != null and guidePrice != ''">guide_price = #{guidePrice},if>
- <if test="produceTime != null and produceTime != ''">produce_time = #{produceTime},if>
- <if test="carType != null and carType != ''">car_type = #{carType},if>
- set>
- where
- id =#{id}
- update>
测试方法:
- //测试 set标签
- @Test
- public void test5(){
- SqlSession sqlSession = SqlSessionUtil.openSession();
- CarMapper mapper = sqlSession.getMapper(CarMapper.class);
- int count = mapper.updateCarWithSetById(new Car(169L, "凯迪拉克", null, 12.5, null, "燃油"));
- System.out.println(count);
- sqlSession.commit();
- sqlSession.close();
- }
语法格式:
- <choose>
- <when>when>
- <when>when>
- <when>when>
- <otherwise>otherwise>
- choose>
相当于java中的if-else 只有一个分支会被执行!!
需求:先根据品牌查询,如果没有提供品牌,再根据指导价格查询,如果没有提供指导价格,就根据生产日期查询。
mapper接口:
- //choose when otherwise
- /*需求:先根据品牌查询,如果没有提供品牌,再根据指导价格查询,如果没有提供指导价格,就根据生产日期查询。*/
- List
selectByChoose (@Param("brand") String brand,@Param("guidePrice") Double guidePrice,@Param("produceTime") String produceTime);
mapper映射文件:
- <select id="selectByChoose" resultType="Car">
- select *
- from t_car
- <where>
- <choose>
- <when test="brand != null and brand != ''">brand = #{brand}when>
- <when test="guidePrice != null and guidePrice != ''">guide_price = #{guidePrice}when>
- <otherwise>produce_time = #{produceTime}otherwise>
- choose>
- where>
- select>
测试类:
- //测试 choose when otherwise
- @Test
- public void test6(){
- SqlSession sqlSession = SqlSessionUtil.openSession();
- CarMapper mapper = sqlSession.getMapper(CarMapper.class);
- List
carList = mapper.selectByChoose("比亚迪汉", null, "2000-01-02"); - carList.forEach(car -> {
- System.out.println(car);
- });
- System.out.println("-------------------");
- List
carList1 = mapper.selectByChoose(null, 120.0, "2000-01-02"); - carList1.forEach(car -> {
- System.out.println(car);
- });
- System.out.println("-------------------");
- List
carList2 = mapper.selectByChoose(null, null, "2000-01-02"); - carList2.forEach(car -> {
- System.out.println(car);
- });
- }
测试结果:

这里的sql语句可以很直观的看出来,这个choose的特点就是只有一个条件会被执行,即使其传递的参数也符合要求。
- 方法一:
- brand like '%${brand}%'
- 方法二:
- brand like concat('%',#{brand},'%')
- 方式三:
- brand like "%"#{brand}"%"
经常使用方式三!
mapper接口:
- //foreach 通过ids来批量删除
- int deleteByIdsUseForeach(@Param("ids") Long[] ids);
mapper映射文件:
- <delete id="deleteByIdsUseForeach">
- delete
- from t_car
-
- where id in (
- <foreach collection="ids" item="id" separator="," >
- #{id}
- foreach>
- )
- delete>
小括号也可以不写 就是 in(....)
- <delete id="deleteByIdsUseForeach">
- delete
- from t_car
-
- where id in
- <foreach collection="ids" item="id" separator="," open="(" close=")">
- #{id}
- foreach>
- delete>
上面是使用in的方式来实现的批量删除的操作,那么如果是实现的是or的关键字的话,那么sql的语句可以这样写:
- <delete id="deleteBatchByForeach2">
- delete from t_car where
- <foreach collection="ids" item="id" separator="or">
- id = #{id}
- foreach>
- delete>
测试类:
- //测试批量删除
- @Test
- public void test7(){
- SqlSession sqlSession = SqlSessionUtil.openSession();
- CarMapper mapper = sqlSession.getMapper(CarMapper.class);
- Long[] ids ={198L,199L,200L};
- int count = mapper.deleteByIdsUseForeach(ids);
- System.out.println(count);
- sqlSession.commit();
- sqlSession.close();
- }
mapper接口:
- //foreach 实现批量插入
- int insertBatchByForeach(@Param("carList") List
carList) ;
mapper映射文件:
"insertBatchByForeach"> - insert into t_car values
-
"carList" item="car" separator=","> - (null,#{car.carNum},#{car.brand},#{car.guidePrice},#{car.produceTime},#{car.carType})
-
-
测试类:
- //批量插入
- @Test
- public void test8() {
- SqlSession sqlSession = SqlSessionUtil.openSession();
- CarMapper mapper = sqlSession.getMapper(CarMapper.class);
- Car car1=new Car(null,"雷克萨斯","1334",56.0,"2015-7-25","燃油");
- Car car2=new Car(null,"阿斯顿·马丁DBS","6989",400.5,"2022-7-1","混动");
- Car car3=new Car(null,"迈凯伦GT","7997",123.2,"2019-10-25","燃油");
- List
carList=new ArrayList<>(); - Collections.addAll(carList,car1,car2,car3);
- int count = mapper.insertBatchByForeach(carList);
- System.out.println(count);
- sqlSession.commit();
- sqlSession.close();
- }
sql标签用来声明sql片段
include标签用来将声明的sql片段包含到某个sql语句当中
作用:代码复用。易维护。
- <sql id="carCols">id,car_num carNum,brand,guide_price guidePrice,produce_time produceTime,car_type carTypesql>
-
- <select id="selectAllRetMap" resultType="map">
- select <include refid="carCols"/> from t_car
- select>
-
- <select id="selectAllRetListMap" resultType="map">
- select <include refid="carCols"/> carType from t_car
- select>
-
- <select id="selectByIdRetMap" resultType="map">
- select <include refid="carCols"/> from t_car where id = #{id}
- select>
mapper接口:
- //根据sid获取去学生对象,同时获取学生关联的班级信息
- Student selectBySid(Integer sid);
mapper映射文件:
- <resultMap id="studentResultMap" type="Student">
- <id property="sid" column="sid">id>
- <result property="sname" column="sname">result>
- <result property="clazz.cid" column="cid">result>
- <result property="clazz.cname" column="cname">result>
- resultMap>
-
- <select id="selectBySid" resultMap="studentResultMap">
- select s.sid, s.sname, c.cid, c.cname
- from t_stu as s
- left join t_clazz as c on s.cid = c.cid
- where s.sid = #{sid}
- select>
测试:
- //多对一 级联属性映射
- @Test
- public void test1(){
- SqlSession sqlSession = SqlSessionUtil.openSession();
- StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
- Student student = mapper.selectBySid(100);
- System.out.println(student);
- }
mapper接口:
- //association标签
- Student selectBySidAssociation(Integer sid);
mapper映射文件:
- <resultMap id="studentResultMapAssociation" type="Student">
- <id property="sid" column="sid">id>
- <result property="sname" column="sname">result>
- <association property="clazz" javaType="Clazz">
- <id property="cid" column="cid">id>
- <result property="cname" column="cname">result>
- association>
-
- resultMap>
- <select id="selectBySidAssociation" resultMap="studentResultMapAssociation">
- select s.sid, s.sname, c.cid, c.cname
- from t_stu as s
- left join t_clazz as c on s.cid = c.cid
- where s.sid = #{sid}
- select>
测试:
- //多对一 使用association标签
- @Test
- public void test2(){
- SqlSession sqlSession = SqlSessionUtil.openSession();
- StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
- Student student = mapper.selectBySidAssociation(100);
- System.out.println(student);
- }
mapper接口 第一步 查cid
- //分步查询的第一步 通过sid查出来学生信息
- Student selectBySidOne(Integer sid);
mapper映射文件:
- <resultMap id="selectByIdOne" type="student">
- <id property="sid" column="sid">id>
- <result property="sname" column="sname">result>
-
- <association property="clazz" select="com.songzhishu.mybatis.mapper.ClazzMapper.selectByCidTwo" column="cid">
- association>
- resultMap>
- <select id="selectBySidOne" resultMap="selectByIdOne">
- select sid,sname,cid
- from t_stu
- where sid = #{sid}
- select>
mapper接口: 第二步 查信息
//分步查询 根据班级id查询班级信息 Clazz selectByCidTwo(Integer cid);
mapper映射问价:
- <select id="selectByCidTwo" resultType="Clazz">
- select *
- from t_clazz
- where cid = #{cid}
- select>
测试:
- //多对一 分步查询
- @Test
- public void test3(){
- SqlSession sqlSession = SqlSessionUtil.openSession();
- StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
- Student student = mapper.selectBySidOne(101);
- System.out.println(student);
- }
首先说一下,就是复用性好是什么意思,这里讲的是我现在的需求是根据学生的sid来出查询出来学生的班级信息,然后就编写了两个sql语句,一个是根据sid查学生的信息,然后另外一个是根据cid查询出来班级的信息,这是两个sql语句,分别摘开都可以使用的,这就是可以复用。
然后就是我们现在的需求是有限定的条件,通过sid确定学生,然后根据学生确定班级,但是我不是每一次都要想查询班级的信息呀,那怎么办,这就要提出来延迟加载。
他的核心就是用的时候使用select语句,不用的时候不使用,这样可以减少查询的条件提高性能!开启延迟加载的方式也很简单 ,再Assoication标签内部的属性中加上,fetchType属性,在默认的情况先,懒加载是关闭的
- <association property="clazz" select="com.songzhishu.mybatis.mapper.ClazzMapper.selectByCidTwo" column="cid"
- fetchType="lazy">
测试:
- @Test
- public void test3(){
- SqlSession sqlSession = SqlSessionUtil.openSession();
- StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
- Student student = mapper.selectBySidOne(101);
- System.out.println(student.getSname());//只要名字 //只执行一条sql
- System.out.println(student); //要全部的信息 //执行两个
- }
这里我将测试的语句都写出来啦,测试后的时候可以注释掉其中一个!
上面的只是针对这个一个Association标签内部的分步开启延迟加载,如果想在全局开启的话,可以在核心配置文件中设置一下字段:
- <setting name="lazyLoadingEnabled" value="true"/>
这样全局的分步都可以使用延迟加载的方式,需要的时候才使用分步,不需要的时候就采用延迟加载从而达到性能的优化,如果配置后针对某一部分的分部的操作不需要使用延迟加载的话,也就可以在Association字段中设置:
fetchType="eager"
mapper接口 Clazz
-
- //根据班级编号查询班级信息
- Clazz selectByCid(Integer cid);
mapper映射文件:
- <resultMap id="selectByCidMap" type="Clazz">
- <id property="cid" column="cid">id>
- <result property="cname" column="canme">result>
-
- <collection property="studentList" ofType="student">
- <id property="sid" column="sid">id>
- <result property="sname" column="sname">result>
- collection>
- resultMap>
-
- <select id="selectByCid" resultMap="selectByCidMap">
- select c.cid,c.cname,s.sid, s.sname
- from t_clazz as c
- left join t_stu as s on c.cid = s.cid
- where c.cid = #{cid}
- select>
测试:
- //一对多
- @Test
- public void test4(){
- SqlSession sqlSession = SqlSessionUtil.openSession();
- ClazzMapper mapper = sqlSession.getMapper(ClazzMapper.class);
- Clazz clazz = mapper.selectByCid(1000);
- System.out.println(clazz);
- }
mapper接口: cLazz 第一步
- //分步查询 跟据编号获取班级信息
- Clazz selectByCidOne(Integer cid);
mapper映射文件: 一对多
- <resultMap id="selectByCidOneMap" type="clazz">
- <id property="cid" column="cid">id>
- <result property="cname" column="cname">result>
- <collection property="studentList" ofType="student" select="com.songzhishu.mybatis.mapper.StudentMapper.selectByCidTwo" column="cid">
- collection>
- resultMap>
-
- <select id="selectByCidOne" resultMap="selectByCidOneMap">
- select cid,cname
- from t_clazz
- where cid = #{cid}
- select>
mapper接口 student
- //一对多 第二步 根据cid查询 学生信息
- List
selectByCidTwo(Integer cid);
mapper映射文件:
-
- select *
- from t_stu
- where cid=#{cid}
-
测试类
- //一对多 分步
- @Test
- public void test5(){
- SqlSession sqlSession = SqlSessionUtil.openSession();
- ClazzMapper mapper = sqlSession.getMapper(ClazzMapper.class);
- Clazz clazz = mapper.selectByCidOne(1001);
- System.out.println(clazz);
- }