Mybatis入门------(2)

八、Mybatis中查询结果映射

1、使用resultMap结果集映射

 <!--
        1、专门定义一个结果映射,在这个结果映射当中指定数据库表的字段名和java实体类的属性名相对应
        2、type属性用来指定实体类的类名
        3、id属性:用来指定resultMap的唯一标识,这个id将来要在select标签中使用
    -->
    <resultMap id="carResultMap" type="com.powernode.mybatis.pojo.Car">
        <!--如果数据库表中有主键,建议设置一个id标签-->
        <id property="id" column="id"></id>
        <!--property后面填写pojo类的属性名-->
        <!--column后面填写数据库表的字段名-->


        <result property="carNum" column="car_num"/>
        <!--如果pojo类和数据库的属性名一样的话可以省略-->
        <!--<result property="brand" column="brand"/>-->
        <result property="guidePrice" column="guide_price"/>
        <result property="produceTime" column="produce_time"/>
        <result property="carType" column="car_type"/>
    </resultMap>

    <!--select标签的resultMap用来指定使用哪个结果映射。resultMap的值是resultMap的id-->
    <select id="selectAllByResultMap" resultMap="carResultMap">
        select * from t_car;
    </select>

2、驼峰命名结果集映射

前提:java中的pojo类属性,首字母小写,后面每个单词首字母大写,数据库中字段,全小写,单词之间用_链接_

在mybatis-config.xml文件中使用

<!--mybatis中的全局设置-->
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>


九、Mybatis中的动态SQL

1、if标签

CarMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.powernode.mybatis.mapper.CarMapper">
    <select id="selectByMultiCondition" resultType="com.powernode.mybatis.pojo.Car">
        select * from t_car where 1=1
        <!--
            1.if中test属性必须有
            2.if中test属性值是false或者true
            3.true:if中的sql语句会拼接
              false:if中sql语句不会拼接
            4.test属性中可以使用的是:
               当使用了@Param注解,那么test中要出现是Param中指定的参数名
               例:@Param("brand"),test中只能使用brand
               当没有使用@Param注解,那么test出现的是:param1,param2,arg0,arg1····
               当使用了pojo,test中出现了pojo类的属性
            5.在mybatis中的动态sql中,&&要用and替换


        -->

        <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>
</mapper>

CarMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.CarMapper;
import com.powernode.mybatis.pojo.Car;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class CarMapperTest {
    @Test
    public void testSelectByMultiCondition(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        //三个条件都不是空
        //List<Car> cars = mapper.selectByMultiCondition("劳斯莱斯",4.3,"新能源");

        //三个条件都是空
        //List<Car> cars = mapper.selectByMultiCondition("",null,"");

        //后两个不为空,第一个为空
        //List<Car> cars = mapper.selectByMultiCondition("",4.6,"新能源");

        //假设第一个条件不是空,后两个为空
        List<Car> cars = mapper.selectByMultiCondition("比亚迪",null,"");
        cars.forEach(car -> System.out.println(car));
        sqlSession.close();
    }
}

CarMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface CarMapper {
    /**
     * 多条件查询
     * @param brand 品牌
     * @param guidePrice 指导价
     * @param carType 车类型
     * @return
     */
    List<Car> selectByMultiCondition(@Param("brand") String brand,@Param("guidePrice") Double guidePrice, @Param("carType") String carType);
}

2、where标签

  • 所有条件都为空时,where标签保证不会生成where子句
  • 自动除去某些条件前面多余的and和or

Demo:

CarMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.powernode.mybatis.mapper.CarMapper">
    <select id="selectByMultiConditionWithWhere" resultType="com.powernode.mybatis.pojo.Car">
        select * from t_car
        <!--where标签是专门负责where子句动态生成的-->
        <where>
            <if test="brand != null and brand != ''">
                 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>
</mapper>

CarMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.CarMapper;
import com.powernode.mybatis.pojo.Car;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class CarMapperTest {
     @Test
    public void testSelectByMultiConditionWithWhere(){
         SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        //三个条件都不是空
        //List<Car> cars = mapper.selectByMultiConditionWithWhere("比亚迪",2.0,"新能源");

        //三个条件都是空
        //List<Car> cars = mapper.selectByMultiConditionWithWhere("",null,"");

        //后两个不为空,第一个为空
        List<Car> cars = mapper.selectByMultiConditionWithWhere("",2.0,"新能源");
        cars.forEach(car -> System.out.println(car));
        sqlSession.close();
    }
}

CarMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface CarMapper {
   /**
     * 使用where标签,让where子句更加的智能
     * @param brand 品牌
     * @param guidePrice 指导价
     * @param carType 车类型
     * @return
     */
    List<Car> selectByMultiConditionWithWhere(@Param("brand") String brand,@Param("guidePrice") Double guidePrice, @Param("carType") String carType);
}

3、trim标签

Demo:

CarMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.powernode.mybatis.mapper.CarMapper">
    <select id="selectByMultiConditionWithTrim" resultType="com.powernode.mybatis.pojo.Car">
        select * from t_car
        <!--
            prefix:加前缀
            suffix:加后缀
            prefixOverrides:去掉前缀
            suffixOverrides:去掉后缀
        -->
        <!--prefix="where"是在trim标签所有内容的前面添加 where  -->
        <!--suffixOverrides="and | or" 把trim标签中内容的后缀and或者or去掉 -->
        <trim prefix="where" suffixOverrides="and | or">
            <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>
</mapper>

CarMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.CarMapper;
import com.powernode.mybatis.pojo.Car;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class CarMapperTest {
    @Test
    public void testSelectByMultiConditionWithTrim(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        List<Car> cars = mapper.selectByMultiConditionWithTrim("",2.4,"");
        cars.forEach(car -> System.out.println(car));
        sqlSession.close();
    }
}

CarMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface CarMapper {
   /**
     * 使用trim标签
     * @param brand 品牌
     * @param guidePrice 指导价
     * @param carType 车类型
     * @return
     */
    List<Car> selectByMultiConditionWithTrim(@Param("brand") String brand,@Param("guidePrice") Double guidePrice, @Param("carType") String carType);
}

4、set标签

主要使用在update语句中,用来生成set关键字,同时去掉最后多余的“,”

比如只更新提交的不为空的字段,如果提交的数据是空或者“ ”,那么这个字段将不会更新

Demo:

CarMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.powernode.mybatis.mapper.CarMapper">
    <update id="updateBySet">
        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>
</mapper>

CarMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.CarMapper;
import com.powernode.mybatis.pojo.Car;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class CarMapperTest {
   @Test
    public void testUpdateBySet(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        Car car = new Car(23L,null,"一汽大众",null,null,"燃油车");
        int count = mapper.updateBySet(car);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();

    }
}

CarMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface CarMapper {
   /**
     * 使用set标签更新
     * @param car
     * @return
     */
    int updateBySet(Car car);
}

5、choose when otherwise标签

语法格式

<choose>
	<when></when>
	<when></when>
	<when></when>
	<otherwise></otherwise>
</choose>

类似于
if(){

}else if(){

}else if(){

}else if(){

}else{
 
}

Demo:

CarMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.powernode.mybatis.mapper.CarMapper">
    <select id="selectByChoose" resultType="com.powernode.mybatis.pojo.Car">
        select * from t_car
        <where>
            <choose>
                <when test="brand != null and brand != ''">
                    brand like "%"#{brand}"%"
                </when>
                <when test="guidePrice != null and guidePrice != ''">
                    guide_price > #{guidePrice}
                </when>
                <otherwise>
                    car_type = #{carType}
                </otherwise>
            </choose>
        </where>
    </select>
</mapper>

CarMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.CarMapper;
import com.powernode.mybatis.pojo.Car;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class CarMapperTest {
  @Test
    public void testSelectByChoose(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        List<Car> cars = mapper.selectByChoose("比亚迪宋",null,null);
        cars.forEach(car -> System.out.println(car));
        sqlSession.close();
    }
}

CarMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface CarMapper {
   /**
     * 使用choose when overwise标签查询
     * @param brand
     * @param guidePrice
     * @param carType
     * @return
     */
    List<Car> selectByChoose(@Param("brand") String brand,@Param("guidePrice") Double guidePrice,@Param("carType") String carType);
}

6、foreach标签

Demo(批量删除):

CarMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.powernode.mybatis.mapper.CarMapper">
    <delete id="deleteByIds">
        <!--
            foreach标签的属性:
                collection:指定数组或者集合
                item:代表数组或者集合中的元素
                separator:循环之间的分隔符
        -->
        delete from t_car where id in(
        <foreach collection="ids" item="id" separator=",">
            #{id}
        </foreach>
        )
    </delete>
</mapper>

CarMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.CarMapper;
import com.powernode.mybatis.pojo.Car;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class CarMapperTest {
  @Test
    public void testDeleteByIds(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        Long[] ids = {5l,22l};
        int count = mapper.deleteByIds(ids);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    }
}

CarMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface CarMapper {
   /**
     * 批量删除
     * @param ids
     * @return
     */
    int deleteByIds(@Param("ids") Long[] ids);
}


Demo(批量插入):

CarMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.powernode.mybatis.mapper.CarMapper">
    <insert id="insertBatch">
        insert into t_car values
        <foreach collection="cars" item="car" separator=",">
            (null,#{car.carNum},#{car.brand},#{car.guidePrice},#{car.produceTime},#{car.carType})
        </foreach>
    </insert>
</mapper>

CarMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.CarMapper;
import com.powernode.mybatis.pojo.Car;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class CarMapperTest {
 @Test
    public void testInsertBatch(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        Car car1 = new Car(null,"1200","萨切特",30.0,"2002-04-09","油车");
        Car car2 = new Car(null,"1300","凯迪拉克",20.0,"2003-03-23","新能源车");
        List<Car> cars = new ArrayList<>();
        cars.add(car1);
        cars.add(car2);
        int count = mapper.insertBatch(cars);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();

    }
}

CarMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface CarMapper {
   /**
     *  批量插入,一次性插入多条记录
     * @param cars
     * @return
     */
    int insertBatch(@Param("cars") List<Car> cars);
}

7、sql标签和include标签

sql标签用来声明sql片段

include标签用来将声明的sql片段包含到某个sql语句当中

作用:代码复用,易维护


十、mybatis的高级映射及延迟加载

之前都是对一个表进行增删查改,而高级映射就是对几个表进行增删查改

1、多对一

①级联属性映射

Demo:

StudentMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.powernode.mybatis.mapper.StudentMapper">

    <!--多对一映射的第一种方式,一条sql语句,级联属性映射-->
    <resultMap id="studentResultMap" type="com.powernode.mybatis.pojo.Student">
        <id property="sid" column="sid"/>
        <result property="sname" column="sname"></result>
        <result property="clazz.cid" column="cid"></result>
        <result property="clazz.cname" column="cname"></result>
    </resultMap>

    <select id="selectById" resultMap="studentResultMap">
        select
            s.sid,s.sname,c.cid,c.cname
        from
            t_student s left join t_class c on s.cid = c.cid
        where
             s.sid = #{sid}
    </select>
</mapper>

StudentMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Student;

public interface StudentMapper {
    /**
     * 根据id获取学生信息,同时获取学生关联的班级信息
     * @param id 学生id
     * @return 返回学生对象,但是学生对象中含有班级对象
     */
    Student selectById(Integer id);
}

StudentMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.StudentMapper;
import com.powernode.mybatis.pojo.Student;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

public class StudentMapperTest {
    @Test
    public void testSelectById(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        Student student = mapper.selectById(1);
        System.out.println(student.getSid());
        System.out.println(student.getSname());
        System.out.println(student.getClazz().getCid());
        System.out.println(student.getClazz().getCname());
        sqlSession.close();
    }
}
②一条sql语句,采用association方式

Demo:

StudentMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.powernode.mybatis.mapper.StudentMapper">

     <resultMap id="studentResultMapAssociation" type="com.powernode.mybatis.pojo.Student">
        <id property="sid" column="sid"/>
        <result property="sname" column="sname"></result>
        <!--
            association: 意为关联,一个student对象关联一个class对象
                       property:提供要映射的pojo类的属性名,
                       javaType:用来指定要映射的java类型
        -->
        <association property="clazz" javaType="com.powernode.mybatis.pojo.Class">
            <id property="cid" column="cid"></id>
            <result property="cname" column="cname"></result>
        </association>
    </resultMap>

    <select id="selectByIdAssociation" resultMap="studentResultMapAssociation">
        select
            s.sid,s.sname,c.cid,c.cname
        from
            t_student s left join t_class c on s.cid = c.cid
        where
            s.sid = #{sid}
    </select>
</mapper>

StudentMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Student;

public interface StudentMapper {
    /**
     * 一条sql语句,association
     * @param id
     * @return
     */
    Student selectByIdAssociation(Integer id);
}

StudentMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.StudentMapper;
import com.powernode.mybatis.pojo.Student;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

public class StudentMapperTest {
   @Test
    public void testSelectByIdAssociation(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        Student student = mapper.selectByIdAssociation(4);
        System.out.println(student);
        sqlSession.close();
    }
}
③两条sql语句,分布查询(优点:可以复用,支持懒加载)

Demo:

StudentMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.powernode.mybatis.mapper.StudentMapper">

     <!--
        两条sql语句,完成多对一的分布查询
    -->
    <!--根据学生的id查询的结果,结果中有班级的id-->
    <resultMap id="studentResultMapByStep" type="com.powernode.mybatis.pojo.Student">
        <id property="sid" column="sid"></id>
        <result property="sname" column="sname"></result>
        <association property="clazz" select="com.powernode.mybatis.mapper.ClassMapper.selectByIdStep2" column="cid">

        </association>
    </resultMap>
    <select id="selectByIdStep1" resultMap="studentResultMapByStep">
        select s.sid,s.sname,cid from t_student s
        where sid = #{sid}
    </select>
</mapper>

StudentMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Student;

public interface StudentMapper {
    /**
     * 分步查询第一步:先根据学生的sid查询学生的信息
     * @param id
     * @return
     */
    Student selectByIdStep1(Integer id);
}

StudentMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.StudentMapper;
import com.powernode.mybatis.pojo.Student;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

public class StudentMapperTest {
  @Test
    public void testSelectByIdStep1(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        Student student = mapper.selectByIdStep1(5);
        System.out.println(student);
        sqlSession.close();
    }
}

classMapper.java

package com.powernode.mybatis.mapper;

public interface ClassMapper {
    /**
     * 分布查询第二步,根据cid获取班级信息
     * @param cid
     * @return
     */
    Class selectByIdStep2(Integer cid);
}

ClassMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.powernode.mybatis.mapper.ClassMapper">
    <!--分步查询第二步:根据cid获取班级信息-->
    <select id="selectByIdStep2" resultType="com.powernode.mybatis.pojo.Class">
        select cid,cname from t_class where cid = #{cid}
    </select>
</mapper>

2、一对多

①使用collection集合方法

ClassMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Class;

public interface ClassMapper {
    /**
     * 分布查询第二步,根据cid获取班级信息
     * @param cid
     * @return
     */
    Class selectByIdStep2(Integer cid);


    /**
     * 根据班级编号查询班级信息
     * @param cid
     * @return
     */
    Class selectByCollection(Integer cid);
}

ClassMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.ClassMapper;
import com.powernode.mybatis.pojo.Class;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

public class ClassMapperTest {
    @Test
    public void testSelectByCollection(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        ClassMapper mapper = sqlSession.getMapper(ClassMapper.class);
        Class aClass = mapper.selectByCollection(1000);
        System.out.println(aClass);
        sqlSession.close();
    }
}

ClassMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.powernode.mybatis.mapper.ClassMapper">


    <resultMap id="classResultMap" type="com.powernode.mybatis.pojo.Class">
        <id property="cid" column="cid"></id>
        <result property="cname" column="cname"></result>
        <!--
            一对多这里是collection,意为集合的意思
            ofType用来指定集合中元素的类型
        -->
        <collection property="stus" ofType="com.powernode.mybatis.pojo.Student">
            <id property="sid" column="sid"></id>
            <result property="sname" column="sname"></result>
        </collection>
    </resultMap>
    <select id="selectByCollection" resultMap="classResultMap">
        select c.cid,c.cname,s.sid,s.sname from t_class c left join t_student s on c.cid = s.cid where c.cid = #{cid}
    </select>
</mapper>
②使用分步查询的方式

Demo:

StudentMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.powernode.mybatis.mapper.StudentMapper">

     <select id="selectByCidStep2" resultType="com.powernode.mybatis.pojo.Student">
        select sid,sname,cid from t_student where cid = #{cid}
    </select>
</mapper>

StudentMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Student;

public interface StudentMapper {
    /**
     * 分步查询第二步:根据班级编号查询学生信息
     * @param cid
     * @return
     */
    List<Student> selectByCidStep2(Integer cid);
}

ClassMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.StudentMapper;
import com.powernode.mybatis.pojo.Student;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

public class StudentMapperTest {
  @Test
    public void testSelectByStep1(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        ClassMapper mapper = sqlSession.getMapper(ClassMapper.class);
        Class aClass = mapper.selectByStep1(1000);
        System.out.println(aClass);
        sqlSession.close();
    }
}

classMapper.java

package com.powernode.mybatis.mapper;

public interface ClassMapper {
    /**
     * 分步查询 第一步:根据班级编号获取班级信息
     * @param cid 班级编号
     * @return
     */
    Class selectByStep1(Integer cid);
}

ClassMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.powernode.mybatis.mapper.ClassMapper">
    <!--分步查询第一步:根据班级的cid获取班级信息-->
    <resultMap id="classResultMapStep" type="com.powernode.mybatis.pojo.Class">
        <id property="cid" column="cid"></id>
        <result property="cname" column="cname"></result>
        <collection property="stus" select="com.powernode.mybatis.mapper.StudentMapper.selectByCidStep2" column="cid"></collection>
    </resultMap>
    <select id="selectByStep1" resultMap="classResultMapStep">
        select cid,cname from t_class where cid = #{cid}
    </select>
</mapper>

十一、Mybatis中的缓存

mybatis中的缓存:将select语句的结果放到缓存中,下一次还是执行这条select语句的话,直接从缓存中取,不再查询数据库

1、类型

  • 一级缓存:将查询的数据存储到Sqlsession中
  • 二级缓存:将查询的数据存储到SqlSessionFactory中
  • 集成第三方的缓存:EhCache等

注意:缓存只针对select语句

2、一级缓存

一级缓存是默认开启,不需要任何的配置

Demo:

CarMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Car;

public interface CarMapper {
    /**
     * 根据id查询汽车信息
     * @param id
     * @return
     */
    Car selectById(Long id);
}

CarMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.CarMapper;
import com.powernode.mybatis.pojo.Car;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;

public class CarMapperTest {
    @Test
    public void testSelectById() throws IOException {
//        SqlSession sqlSession = SqlSessionUtil.openSession();
//        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
//        Car car1 = mapper.selectById(11l);
//        System.out.println(car1);
//
//        Car car2 = mapper.selectById(11l);
//        System.out.println(car2);
//        sqlSession.close();

        //测试一级缓存是否是将查询的数据存在SqlSession当中
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        //第一个sqlSession对象
        SqlSession sqlSession1 = sqlSessionFactory.openSession();
        CarMapper mapper1 = sqlSession1.getMapper(CarMapper.class);
        Car car1 = mapper1.selectById(11l);
        System.out.println(car1);


        //第二个sqlSession对象
        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        CarMapper mapper2 = sqlSession2.getMapper(CarMapper.class);
        Car car2 = mapper2.selectById(11l);
        System.out.println(car2);

        sqlSession1.close();
        sqlSession2.close();

    }
}

CarMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.powernode.mybatis.mapper.CarMapper">
    <select id="selectById" resultType="com.powernode.mybatis.pojo.Car">
        select * from t_car where id = #{id}
    </select>
</mapper>
①什么时候不走一级缓存?
  • SqlSession对象不是同一个,肯定不走缓存
  • 查询条件不一样
②什么时候一级缓存失效?
  • 在第一次DQL语句和第二次DQL语句之间,以下两件事都会让一级缓存清空
    • 1、执行了sqlSession的clearCache方法,这个是手动清空
    • 2、执行了insert或者update或者delete语句,不管是不是当前的表,都会清空一级缓存

2、二级缓存

二级缓存的范围是SqlSessionFactory

使用二级缓存必须具备以下的配置:

  • 全局性地开启或者关闭所有映射配置文件中已配置的任何缓存,默认就是true,所以不用配置
  • 在需要使用二级缓存的SqlMapper.xml文件中添加配置:
  • 使用二级缓存的实体类对象必须是可序列化的,也就是说必须实现java.io.Serializable接口
  • SqlSession对象关闭或者提交之后,一级缓存中的数据才会被写入到二级缓存中,此时二级缓存才可以使用

Demo:

CarMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Car;

public interface CarMapper {
    /**
     * 测试二级缓存
     * @param id
     * @return
     */
    Car selectById2(Long id);
}

CarMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.CarMapper;
import com.powernode.mybatis.pojo.Car;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;

public class CarMapperTest {
    @Test
    public void testSelectById2() throws IOException {

        //这里只有一个SqlSessionFactory对象,二级缓存对应的就是SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        SqlSession sqlSession1 = sqlSessionFactory.openSession();
        SqlSession sqlSession2 = sqlSessionFactory.openSession();

        CarMapper mapper1 = sqlSession1.getMapper(CarMapper.class);
        CarMapper mapper2 = sqlSession2.getMapper(CarMapper.class);

        //这行代码结束之后,实际上数据是缓存到一级缓存当中了
        Car car1 = mapper1.selectById2(10l);
        System.out.println(car1);

        //这里不关闭SqlSession1对象的话,二级缓存中还是没有数据的

        //这行代码执行完毕,实际上数据会缓存到一级缓存中
        Car car2 = mapper2.selectById2(10l);
        System.out.println(car2);

        //程序执行到这里的时候,会将sqlSession1这个一级缓存中的数据写入到二级缓存中
        sqlSession1.close();
        //程序执行到这里的时候,会将sqlSession2这个一级缓存中的数据写入到二级缓存中
        sqlSession2.close();
    }
}

CarMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.powernode.mybatis.mapper.CarMapper">
    <cache/>
    
    <select id="selectById2" resultType="com.powernode.mybatis.pojo.Car">
        select * from t_car where id = #{id}
    </select>
</mapper>

Car.java

public class Car implements Serializable {
    //数据库中的字段和属性相同

    //建议使用包装类,防止null
    private Long id;

    private String carNum;
    private String brand;
    private Double guidePrice;
    private String produceTime;
    private String carType;

    public Car(Long id, String carNum, String brand, Double guidePrice, String produceTime, String carType) {
        this.id = id;
        this.carNum = carNum;
        this.brand = brand;
        this.guidePrice = guidePrice;
        this.produceTime = produceTime;
        this.carType = carType;
    }
    public Car(){}

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getCarNum() {
        return carNum;
    }

    public void setCarNum(String carNum) {
        this.carNum = carNum;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Double getGuidePrice() {
        return guidePrice;
    }

    public void setGuidePrice(Double guidePrice) {
        this.guidePrice = guidePrice;
    }

    public String getProduceTime() {
        return produceTime;
    }

    public void setProduceTime(String produceTime) {
        this.produceTime = produceTime;
    }

    public String getCarType() {
        return carType;
    }

    public void setCarType(String carType) {
        this.carType = carType;
    }

    @Override
    public String toString() {
        return "Car{" +
                "id=" + id +
                ", carNum='" + carNum + '\'' +
                ", brand='" + brand + '\'' +
                ", guidePrice=" + guidePrice +
                ", produceTime='" + produceTime + '\'' +
                ", carType='" + carType + '\'' +
                '}';
    }
}

①二级缓存失效
  • 只要两次查询之间出现了增删查改,二级缓存就会失效(一级缓存也会失效)

十二、Mybatis的逆向工程

使用这个插件,需要给这个插件配置哪些信息?

  • pojo类、包名已经生成位置
  • SqlMapper.xml文件名以及生成的位置
  • Mapper接口名以及生成的位置
  • 连接数据库的信息
  • 指定哪些表参加逆向工程
①在pom.xml文件添加逆向工程插件
<!--配置mybatis逆向工程的插件-->
    <build>
        <plugins>
            <!--mybatis-generator的Maven插件-->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.4.1</version>
                <!--允许覆盖-->
                <configuration>
                    <!--<verbose>true</verbose>-->
                    <overwrite>true</overwrite>
                </configuration>
                <!-- 插件需要的依赖环境 -->
                <dependencies>
                    <!--
                    这个是 在插件 org.mybatis.generator 需要配置这信息,
                    所以需要再次这个依赖数据库驱动放在org.mybatis.generator的 plugin中依赖
                    与项目中引入的区别不重复
                    -->
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>8.0.30</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
②配置generatorConfig.xml

注意:

  • 文件名必须叫做generatorConfig.xml
  • 该文件必须放在类的根路径下

十三、Mybatis分页-PageHelper插件

①引入依赖
<!--mybatis的插件pagehelper-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.3.1</version>
        </dependency>
②在mybatis-conflg.xml文件中配置插件
<!--mybatis分页的拦截器-->
   <plugins>
       <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
   </plugins>

十四、Mybatis的注解式开发

注意:简单的sql语句,比如单表的crud可以使用注解开发,但是像多表的联合使用,最好还是使用xml配置文件开发

①insert注解

CarMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;

public interface CarMapper {

    @Insert("insert into t_car values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})")
    int insert(Car car);

    @Delete("delete from t_car where id = #{id}")
    int deleteById(Long id);
}

CarMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.CarMapper;
import com.powernode.mybatis.pojo.Car;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

public class CarMapperTest {
    @Test
    public void testInsert(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        Car car = new Car(null,"4545","小米SU7",25.0,"2023-12-12","新能源");
        int count = mapper.insert(car);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void testDeleteById(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        int i = mapper.deleteById(27l);
        System.out.println(i);
        sqlSession.commit();
        sqlSession.close();

    }
}
②delete注解

CarMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;

public interface CarMapper {


    @Delete("delete from t_car where id = #{id}")
    int deleteById(Long id);
}

CarMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.CarMapper;
import com.powernode.mybatis.pojo.Car;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

public class CarMapperTest {
  

    @Test
    public void testDeleteById(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        int i = mapper.deleteById(27l);
        System.out.println(i);
        sqlSession.commit();
        sqlSession.close();

    }
}
③update注解

CarMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;

public interface CarMapper {

    @Update("update t_car set car_num=#{carNum},brand=#{brand},guide_price=#{guidePrice},produce_time=#{produceTime},car_type=#{carType} where id = #{id}")
    int update(Car car);
}

CarMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.CarMapper;
import com.powernode.mybatis.pojo.Car;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

public class CarMapperTest {
   @Test
    public void testUpdate(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        Car car = new Car(20l,"6666","特斯拉",30.0,"2020-09-08","新能源");
        int count = mapper.update(car);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    }
}
④select注解

CarMapper.java

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;

public interface CarMapper {

     @Select("select * from t_car where id = #{id};")
    Car selectById(Long id);
}

CarMapperTest.java

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.CarMapper;
import com.powernode.mybatis.pojo.Car;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

public class CarMapperTest {
   @Test
    public void testSelectById(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        Car car = mapper.selectById(21l);
        System.out.println(car);

        sqlSession.close();
    }
}
  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

要努力点

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值