• Mybatis - XML


    关系查询

    一对一

    1. public class Student {
    2.    private Integer sId;
    3.    private String sName;
    4.    // 通过对象表示一对一(对象不能自动映射)
    5.    private Teacher tId;
    6. }

    例题

    查询每个学生的老师

    关联查询

    1. <!-- id:对应方法名 -->
    2. <!-- resultMap:调用resultMap -->
    3. <select id="selStu" resultMap="stuAndTea">
    4.   SELECT * FROM student s
    5.   left join
    6.   teacher t
    7.   on s.t_id = t.t_id
    8. </select>
    1. <!-- id:自定义resultMap -->
    2. <!-- type:指定实体类对象 -->
    3. <resultMap id="stuAndTea" type="Student">
    4.    <!--id:指定主键映射规则-->
    5.    <!--column:指定(数据库)字段列-->
    6.    <!--property:指定(实体类)属性对象-->
    7.    <id column="s_id" property="sId"/>
    8.    <!--result:指定非主键映射规则-->
    9.    <!--column:指定(数据库)字段列-->
    10.    <!--property:指定(实体类)属性对象-->
    11.    <result column="s_name" property="sName"/>
    12.    <!-- teacher是student的对象 -->
    13.    <!-- association:给对象赋值 -->
    14.    <!-- property:属性名 -->
    15.    <!-- javaType:指定(实体类)对象 -->
    16.    <association property="tId" javaType="teacher">
    17.        <id column="t_id" property="tId"/>
    18.        <result column="t_name" property="tName"/>
    19.    </association>
    20. </resultMap>

    分步查询

    1. <!-- 思路分析:查出所有的学生,根据每个学生的老师id去查询对应的老师信息 -->
    2. <select id="selStu" resultMap="stuAndTea">
    3.   SELECT * FROM student;
    4. </select>
    5. <resultMap type="student" id="stuAndTea">
    6.    <id column="s_id" property="sId"/>
    7.    <result column="s_name" property="sName"/>
    8.    <!-- column:提取字段参数交给调用的查询方法 -->
    9.    <!-- select:调用查询方法 -->
    10.    <association property="tId" javaType="teacher" column="t_id" select="getTeacherById"></association>
    11. </resultMap>
    12. <select id="getTeacherById" resultType="teacher">
    13.   select * from teacher where t_id = #{tid}
    14. </select>

    一对多

    一个对象关联多个对象

    数据层面:通过外键

    1. public class Teacher {
    2.    private Integer tId;
    3.    private String tName;
    4.    // 通过集合表示一对多(集合不能自动映射)
    5.    List<Student> stus;
    6. }

    例题

    查询老师的所有学生

    关联查询

    1. <select id="selTea" resultMap="teaAndAllStu">
    2.   SELECT * FROM teacher t
    3.   LEFT JOIN
    4.   student s
    5.   ON t.t_id = s.t_id
    6. </select>
    7. <resultMap type="teacher" id="teaAndAllStu" autoMapping="true">
    8.    <id column="t_id" property="tId"/>
    9.    <!-- collection:集合赋值 -->
    10.    <!-- ofType:集合所属类型 -->
    11.    <collection property="stus" ofType="student" autoMapping="true">
    12.        <id column="s_id" property="sId"/>
    13.        <result column="s_name" property="sName"/>
    14.    </collection>
    15. </resultMap>

    分步查询

    1. <select id="selTea" resultMap="teaAndStu">
    2.   SELECT * FROM teacher;
    3. </select>
    4. <resultMap type="teacher" id="teaAndStu" autoMapping="true">
    5.    <id column="t_id" property="tId"/>
    6.    <collection property="stus" ofType="student" column="t_id" select="getStudentByTid"></collection>
    7. </resultMap>
    8. <select id="getStudentByTid" resultType="student">
    9.   SELECT * FROM student WHERE t_id = #{t_id}
    10. </select>

    多对多

    数据库层面:必须引入中间表(用于记录表之间的关系)

    实体类层面:本质是一对多

    1. @Data
    2. public class Student {
    3. private int sid;
    4. private String sname;
    5. //多对多--最终处理时转为1对多
    6. List<Course> allCou;
    7. }

    关联查询

    1. <select id="getStudentAndCouese" resultMap="stuAndCou">
    2.   SELECT * FROM student s
    3.   LEFT JOIN
    4.   stu_cou sc
    5.   ON s.s_id = sc.s_id
    6.   LEFT JOIN
    7.   course c
    8.   ON sc.c_id = c.c_id
    9. </select>
    10. <resultMap type="student" id="stuAndCou" autoMapping="true">
    11.    <id column="s_id" property="sId"/>
    12.    <result column="s_name" property="sName"/>
    13.    <collection property="courses" ofType="course" autoMapping="true">
    14.        <id column="cid" property="cid"/>
    15.        <result column="c_name" property="cName"/>
    16.    </collection>
    17. </resultMap>

    分布查询

    1. <select id="getStudentAndCouese" resultMap="stuAndCou">
    2.   SELECT * FROM student;
    3. </select>
    4. <resultMap type="student" id="stuAndCou" autoMapping="true">
    5.    <id column="s_id" property="sId"/>
    6.    <result column="s_name" property="sName"/>
    7.    <collection property="courses" ofType="course" column="s_id" select="getCourseBySid"></collection>
    8. </resultMap>
    9. <select id="getCourseBySid" resultType="course">
    10.   SELECT * FROM stu_cou sc
    11.   JOIN
    12.   course c
    13.   ON sc.c_id = c.c_id AND sc.s_id = #{s_id}
    14. </select>

    延时加载(按需加载)

    作用

    1. 提升数据查询效率

    2. 减少计算机压力

    解决方案

    1. 使用关联查询,不使用分步查询

    2. 开启延迟加载(按需加载)

    全局开启

    1. <settings>
    2.    <!-- 全局打开延迟加载 -->
    3.    <setting name="lazyLoadingEnabled" value="true"/>
    4. </settings>

    局部开启

    局部配置会覆盖全局配置

    1. <!-- 对象或集合的标签上添加fetchType属性 -->
    2. <!-- fetchType:lazy = 开启、eager = 关闭 -->
    3. <collection fetchType="lazy"></collection>

    缓存

    加快运行速度

    查询时,第一次将查询出的数据在缓存中放一份。以后遇到同样的操作,直接从缓存读取

    开启缓存

    一级缓存

    sqlSession级别缓存:在同一个sqlSession中做同样的数据查询,第二次查询会走缓存

    开启方式:默认打开的

    1. SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    2. StudentMapper mapper1 = sqlSession.getMapper(StudentMapper.class);
    3. List<Student> students1 = mapper1.getStudentAndCouese();
    4. // 走缓存
    5. StudentMapper mapper2 = sqlSession.getMapper(StudentMapper.class);
    6. List<Student> students2 = mapper2.getStudentAndCouese();
    7. sqlSession.close();

    二级缓存

    mapper级别缓存 :同个mapper同个接口,第二次调用相同接口时走缓存

    开启方式

    全局配置文件中打开缓存开关

    1. <settings>
    2.    <!-- 开启二级缓存 -->
    3.    <setting name="cacheEnabled" value="true"/>
    4. </settings>

    开启缓存接口对应mapper中声明一个cache标签

    1. <!-- 当前接口开启二级缓存 -->
    2. <cache></cache>

    二级缓存底层实现基于对象序列化与反序列化实现

    public class Student implements Serializable

    参数传递

    @Param

    1. 接口(删除指定用户)

      1. // @Param:对参数取别名
      2. Integer deleteUser(@Param("id")Integer id);

    2. 接口对应的xml配置

      1. <delete id="deleteUser">
      2.    <!-- XML配置通过#{"别名"}在SQL语句上取值 -->
      3.   DELETE FROM user WHERE uid = #{id}
      4. </delete>

    传递Map

    1. XML中声明参数类型 —— map

      1. <!-- parameterType:传递参数类型,使用Map的键取值 -->
      2. <select id="getStuToName" resultType="student" parameterType="map">
      3.   SELECT * FROM student where s_name = #{name};
      4. </select>

    2. Dao层内传递Map类型值

      Products getProByMap(Map map);

    3. test层使用Map值传递参数

      1. SqlSession sqlSession = SqlSessionUtil.getSqlSession();
      2. TestDao Test = sqlSession.getMapper(TestDao.class);
      3. // 创建HashMap
      4. Map map = new HashMap();
      5. // 写入键值对
      6. map.put("name","a");
      7. // 传递map作为参数
      8. List<Student> couese = Test.getStuToName(map);
      9. for (Student student : couese) {
      10. System.out.println(student);
      11. }
      12. sqlSession.close();

    SQL片段

    • sql片段,记录一段公共sql片段,用include标签引入

    • 声明sql片段:<sql>标签

    <sql id="information">eid,emp_name,age,sex,email</sql>
    • 引用sql片段:<include>标签

    1. <!--List<Emp> getEmpByCondition(Emp emp);-->
    2. <select id="getUser" resultType="User">
    3. select <include refid="information"></include> from user
    4. </select>

    模糊查询

    模糊查询的模糊条件通过参数形式传递

    1. <select id="getLikeStu" resultType="products">
    2.   SELECT * FROM products WHERE name LIKE "%"#{name}"%";
    3. </select>

    使用时在service层根据不同的业务场景生成不同的模糊条件

    List<Products> proByLike = mapper.getProByLike("name");

    分页查询

    方式一

    limit关键字分页

    SELECT * FROM 表名 LIMIT 从哪查,查几条

    前段传参数:pagenum:页数、pagesize:条数

    转换:SELECT * FROM 表名 LIMIT (pagenum-1)*pagesize,pagesize

    注意:service层完成转换工作

    dao层接口:

    1. //分页查询
    2. List<Products> getProPage(@Param("startIndex")int startIndex,@Param("pageSize")int pageSize);

    xml文件:

    1. <select id="getPage" resultType="student">
    2.   SELECT * FROM student LIMIT #{startIndex},#{pageSize};
    3. </select>

    service层做转换

    1. int pageNum = 2;
    2. int pageSize = 2;
    3. SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    4. TestDao Test = sqlSession.getMapper(TestDao.class);
    5. List<Student> page = Test.getPage((pageNum - 1) * pageSize, pageSize);
    6. for (Student student : page) {
    7.    System.out.println(student);
    8. }
    9. sqlSession.close();

    方式二

    PageHelper

    1. 导入依赖:pageHelper核心包、jsql转换包

    2. 在全局配置中配置插件

      1. <plugins>
      2.    <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
      3. </plugins>

    3. 使用PageHelper

    1. // (0++)
    2. int pageNum = 0;
    3. int pageSize = 2;
    4. // 配置分页插件
    5. PageHelper.startPage(pageNum, pageSize);
    6. // 调用DAO层查询数据(所有信息)
    7. SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    8. TestDao mapper = sqlSession.getMapper(TestDao.class);
    9. // 将Dao数据放入PageHelper进行分页
    10. PageInfo<Student> pageInfo = new PageInfo<>(mapper.getPage());
    11. // 获取分页后数据
    12. List<Student> list = pageInfo.getList();
    13. for (Student student : list) {
    14.    System.out.println(student);
    15. }
    16. // 获取总页数
    17. System.out.println(pageInfo.getPages());
    18. sqlSession.close();

    动态SQL

    根据不同的条件拼接不同的SQL语句

    if

    test(条件语句)值为真,拼接SQL,否则不进行拼接

    1. <select id="selStu" resultType="student">
    2.    <!-- 添加1=1恒成立语句,防止条件不成立引发sql语句异常 -->
    3.   SELECT * FROM student where 1=1
    4.    <if test="stu.sName != null and stu.sName != ''">
    5.   and s_name = #{stu.sName}
    6.    </if>
    7. </select>

    where

    常与<if>标签结合使用,<if>语句发生拼接,自动加where关键字 ,删除第一个拼接语句连接词(and、or)

    1. <select id="selStu" resultType="student">
    2.   SELECT * FROM student
    3.    <where>
    4.        <if test="stu.sName != null and stu.sName != ''">
    5.           and s_name = #{stu.sName}
    6.        </if>
    7.        <if test="stu.sAge != null and stu.sAge != ''">
    8.           or s_age = #{stu.sAge}
    9.        </if>
    10.    </where>
    11. </select>

    set

    常与<if>标签结合使用,<if>语句发生拼接,之前添加一个set关键字,在最后一次拼接的地方去除逗号

    1. <update id="selStu">
    2.   update student
    3.    <set>
    4.        <if test="stu.sName != null and stu.sName != ''">
    5.           s_name = #{stu.sName},
    6.        </if>
    7.        <if test="stu.sAge != null and stu.sAge != ''">
    8.           s_age = #{stu.sAge},
    9.        </if>
    10.    </set>
    11.   where s_id = 1
    12. </update>

    trim

    1. <select id="getProByCondtion" resultType="products">
    2.   SELECT * FROM products  
    3.    <!-- prefix:拼接最前面添加XX -->
    4.    <!-- prefixOverrides:拼接在前面去除XX -->
    5.    <!-- suffix:拼接最后面添加XX -->
    6.    <!-- suffixOverrides:拼接在后面去除XX -->
    7.    <trim prefix="WHERE" prefixOverrides="OR">
    8.        <if test="name!=null and name !='' ">
    9.           OR name = #{name}
    10.        </if>
    11.        <if test="location!=null and location !='' ">
    12.           OR location = #{location}
    13.        </if>
    14.    </trim>
    15. </select>

    choose、when、otherwise

    • 相当于if..else

    • when至少有一个,otherwise至多有一个

    • when只执行一个

    1. <select id="selStu" resultType="student">
    2.   select * from student
    3.    <where>
    4.        <choose>
    5.            <!-- 只执行一个,查询无果直接结束 -->
    6.            <when test="stu.sName != null and stu.sName != ''">
    7.               s_name = #{stu.sName}
    8.            </when>
    9.            <when test="stu.sAge != null and stu.sAge != ''">
    10.               s_age = #{stu.sAge}
    11.            </when>
    12.            <!-- 所有when都不成立时执行 -->
    13.            <otherwise>
    14.               s_id = 1
    15.            </otherwise>
    16.        </choose>
    17.    </where>
    18. </select>

    foreach

    • 属性:

      • collection:循环的数组或集合

      • item:遍历元素(i)

      • separator:分隔符

      • open:foreach标签开始符

      • close:foreach标签结束符

    • 批量删除

      1. <!-- Integer selStu(@Param("id") Integer[] id); -->
      2. <delete id="selStu">
      3.   delete from student where s_id in
      4.    <foreach collection="id" item="i" separator="," open="(" close=")">
      5.       #{i}
      6.    </foreach>
      7. </delete>
      1. SqlSession sqlSession = SqlSessionUtil.getSqlSession();
      2. TestDao mapper = sqlSession.getMapper(TestDao.class);
      3. int result = mapper.selStu(new Integer[]{10, 11, 12, 9});
      4. System.out.println(result);
      5. sqlSession.commit();
      6. sqlSession.close();
    • 批量添加

    1. <!-- Integer selStu(@Param("stu") List<Student> stu); -->
    2. <insert id="selStu">
    3.   insert into student values
    4.    <foreach collection="stu" item="i" separator="," >
    5.        <!-- 使用时注意使用遍历元素点属性 -->
    6.       (default ,#{i.sName},#{i.sAge},#{i.sGrade})
    7.    </foreach>
    8. </insert>
    1. SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    2. TestDao mapper = sqlSession.getMapper(TestDao.class);
    3. Student stu1 = new Student(null,"a",18,12.2);
    4. Student stu2 = new Student(null,"b",28,35.0);
    5. Student stu3 = new Student(null,"c",38,22.5);
    6. Integer integer = mapper.selStu(Arrays.asList(stu1, stu2, stu3));
    7. System.out.println(integer);
    8. sqlSession.commit();
    9. sqlSession.close();
  • 相关阅读:
    051_末晨曦Vue技术_处理边界情况之provide和inject依赖注入
    机器学习周报第三十九周 DSAMDL
    elementui表单的验证问题
    杀毒软件的原理
    【有问必答】搭建uniapp项目流程手把手教学
    《视觉SLAM十四讲》-- 相机与图像
    室温离子液体1-丁基-3-甲基咪唑四氟硼酸盐([BMIM]BF4)偶联牛血清蛋白(BSA)合成路线
    (标签-机器学习|关键词-set)
    【JDK 8-函数式编程】4.3 Consumer
    Android NDK初识
  • 原文地址:https://blog.csdn.net/Xstruggle/article/details/125483388