MyBatis基础知识(一)

文章详细介绍了MyBatis中获取参数值的两种方式,XML映射文件的常用标签,Dao接口的操作方式,以及动态SQL的使用。同时,阐述了MyBatis如何实现分页功能,映射形式,包括多对一和一对多的映射关系处理,并讨论了延迟加载的概念和实现。此外,还提到了分步查询的优势和应用场景。
摘要由CSDN通过智能技术生成

目录

1. mybatis获取参数值的两种方式

2.xml映射文件的常用标签

3.Dao接口是如何操作数据库的?

4.Dao接口的方法能够重载吗

5.MyBatis动态sql

6.MyBatis中实现分页功能

7.MyBatis的映射形式

8.MyBatis实现多对一的映射关系

9.MyBatis实现一对多的映射关系

1.表关系映射到实体类中时,实体类如何处理对应的复杂的表的关系呢?

2.处理一对多的映射关系的方法

10.分步查询的好处

1. 可以实现延迟加载

2.实现延迟加载

3.在延迟加载时如何查询所有结果


1. mybatis获取参数值的两种方式

1.${}:字符串拼接;在为字符串类型/日期类型赋值时需要手动加单引号

    * 在底层解析时被视为一个字段

2.#{}:占位符赋值;在底层被解析时自动添加单引号

    * 在底层解析时被视为一个问号❓
 

2.xml映射文件的常用标签

1.数据库操作标签

        select、insert、update、delete

2.自定义映射处理标签:resultMap

3.sql片段标签:sql、include

4.自增主键标签:selectKey

5.动态sql标签:

        if、where、trim、foreach,choose、when、otherwise

3.Dao接口是如何操作数据库的?

1.创建方式:MyBatis中,Dao接口中会写Mapper接口xxxMapper,对应在相同的文件路径下创建一个同名的xxxMapper.xml

2.关联方式:mapper接口xxxMapper和映射文件xxxMapper.xml要保证两个一致

    1. mapper接口的全类名和映射文件的namespace一致

    2. mapper接口中的方法的方法名要和映射文件中的SQL的ID保持一致

3.定位方式:调用mapper接口方法时,会根据 全类名.方法名 作为key,定位一个MappedStatement

4.代码示例:如调用UserMapper的insertUser()方法,会根据com.gz.java.mybatis.mapper.UserMapper.insertUser()定位到xml文件中namespace=com.gz.java.mybatis.mapper.UserMapper,id=insertUser的MappedStatement

public interface UserMapper {

    int insertUser();
}
    <mapper namespace="com.gz.java.mybatis.mapper.UserMapper">
    <!--int insertUser();-->
    <insert id="insertUser">
         insert into t_user values(null,'admin','123456',23,'男','12345@qq.com')
    </insert>

4.Dao接口的方法能够重载吗

        可以;但是接口方法对应的映射文件中的id必须是唯一的

5.MyBatis动态sql

1.作用:根据特定条件动态拼装SQL语句的功能,存在的意义是为了解决拼接SQL语句字符串时的问题

2.动态sql使用的标签:

* 第一个标签:if:通过test属性中的表达式判断标签中的内容是否有效(是否会拼接到SQL中)

* 第二个标签:where:(与if结合使用)

    * 第一个功能:若where标签中有表达式成立,则自动生成where

    * 第二个功能:能将内容中前面多余的and去掉,但是内容后面的and无法去掉

    * 第三个功能:若where标签中的表达式都不成立,则where标签没有任何功能

* 第三个标签:trim:用来截取条件中的内容;具有四个标签

    * prefix,suffix:在标签中内容的前面或后面添加指定内容

    * prefixOverrides,suffixOverrides:在标签中内容前面或后面去掉指定内容

* 第四组标签:foreach(极其重要,掌握);可以实现批量添加和批量删除(三种方法),共有五个属性

    * collection:设置要循环的数组或集合

    * item:用一个字符串表示数组或集合中的每一个数据

    * separator:设置每次循环的数据之间的分隔符

    * open:循环的所有内容以什么开始

    * close:循环的所有内容以什么结束

* 第五个标签:choose,when,otherwise:相当于:if-else if-else(用的不多)

    * when至少设置一个;otherwise至多设置一个

* 第六个标签:sql片段:可以记录一段sql,在需要使用的地方使用include标签进行引用

详细使用方式请参考:

MyBatis的重点知识_perseveregz的博客-CSDN博客

6.MyBatis中实现分页功能

1.分页的实现:

        sql中使用limit实现分页功能

        使用分页插件实现分页功能

2.分页插件的实现原理

        使用MyBatis提供的插件接口,在插件的拦截方法内拦截待执行的sql语句,然后重写sql,添加对应的物理分页语句和物理分页参数

7.MyBatis的映射形式

1.将字段名设置别名

        如果别名和属性名相等就可以成功输出值,否则不一致的名字输出将为null

<!--Emp getEmpByEmpId(@Param("empId”) Integer empId);-->
<select id="getEmpByEmpId” resultType="Emp">
    select emp_id empId,emp_name empName,age,gender from t_emp where emp_id = #{empId}
</select>

2.  使用resultMap自定义映射处理

    * id:唯一标识

    * type:处理映射关系的实体类的类型

<!-- Dept getDeptAndEmpByStepOne(@Param("deptId") Integer deptId);  -->
    
    <resultMap id="getDeptAndEmpByStepOne" type="Dept">
        <id column="dept_id" property="deptId"></id>
        <result column="dept_name" property="deptName"></result>
    </resultMap>
    
    <select id="getDeptAndEmpByStepOne" resultMap="getDeptAndEmpByStepOne">
        select * from t_dept where dept_id = #{deptId}
    </select>

映射关系确定后,MyBatis通过反射创建对象,并为对象属性赋值。

8.MyBatis实现多对一的映射关系

第一种方法:级联方式处理

<!--    处理多对一映射关系的三种方法  -->
<!--        Emp getEmpAndDeptByEmpId(@Param("id")Integer id);  -->
 
<!--    第一种方法:级联方式处理    -->
    <resultMap id="getEmpAndDeptResultMap" type="Emp">
        <id column="emp_id" property="empId"></id>
        <result column="emp_name" property="empName"></result>
        <result column="age" property="age"></result>
        <result column="gender" property="gender"></result>
        <result column="dept_id" property="dept.deptId"></result>
        <result column="dept_name" property="dept.deptName"></result>
    </resultMap>
 
    <select id="getEmpAndDeptByEmpId" resultMap="getEmpAndDeptResultMap">
        SELECT *
        FROM t_emp
        LEFT JOIN t_dept
        ON t_emp.dept_id = t_dept.dept_id
        WHERE t_emp.emp_id = #{empId};
    </select>

第二种方法:association;专门用来处理多对一的映射关系(专门处理实体类类型的属性)

<!--    第二种方法:association处理     -->
    <resultMap id="getEmpAndDeptResultMap" type="Emp">
        <id column="emp_id" property="empId"></id>
        <result column="emp_name" property="empName"></result>
        <result column="age" property="age"></result>
        <result column="gender" property="gender"></result>
        <association property="dept" javaType="Dept">
            <id column="dept_id" property="deptId"></id>
            <result column="dept_name" property="deptName"></result>
        </association>
    </resultMap>
 
    <select id="getEmpAndDeptByEmpId" resultMap="getEmpAndDeptResultMap">
        SELECT *
        FROM t_emp
        LEFT JOIN t_dept
        ON t_emp.dept_id = t_dept.dept_id
        WHERE t_emp.emp_id = #{empId};
    </select>

第三种方法:分步查询

            * 注意:此时应将分步查询的不同步骤写在对应的映射文件中

            * select的唯一标识:namespace.SQL Id

    /**
     * 通过分步查询员工以及对应的部门信息的第一步
     * @param empId
     * @return
     */
    Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);

    /**
     * 通过分步查询员工以及对应的部门信息的第二步
     * @param deptId
     * @return
     */
    Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);
<!--    第三种方法:分步查询-->
 
<!--    Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);-->
 
    <resultMap id="empAndDeptByStepResultMap" type="Emp">
        <id column="emp_id" property="empId"></id>
        <result column="emp_name" property="empName"></result>
        <result column="age" property="age"></result>
        <result column="gender" property="gender"></result>
        <association property="dept" fetchType="lazy"
                     select="com.gz.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
                     column="dept_id"></association>
    </resultMap>
 
    <select id="getEmpAndDeptByStep" resultMap="empAndDeptByStepResultMap">
        select * from t_emp where emp_id = #{empId}
    </select>
<!--    Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);       -->
    <select id="getEmpAndDeptByStepTwo" resultType="Dept">
        select * from t_dept where dept_id = #{deptId}
    </select>

9.MyBatis实现一对多的映射关系

1.表关系映射到实体类中时,实体类如何处理对应的复杂的表的关系呢?

 * 对一,对应一个对象;对多,对应一个集合

 * 比如,员工表和部门表;一个部门对应多个员工;若在查员工时要查部门,就是多对一,此时在员工实体类对象中写上一个部门对象;

* 若是查询一个部门的多个员工,就是一对多;在部门的实体类对象中为多个员工写一个list集合

public class Dept {
 
    private Integer deptId;
 
    private String deptName;
 
    private List<Map> emps;
}

2.处理一对多的映射关系的方法

* 第一种方法:collection(也是一个模版)

<!--     
        2.处理一对多的映射关系的方法
        第一种方法:collection(也是一个模版)
-->
<!--        Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId);     --> 
    <resultMap id="getDeptIdByRestultMap" type="Dept">
        <id column="dept_id" property="deptId"></id>
        <result column="dept_name" property="deptName"></result>
        <collection property="emps" ofType="Emp">
            <id column="emp_id" property="empId"></id>
            <result column="emp_name" property="empName"></result>
            <result column="age" property="age"></result>
            <result column="gender" property="gender"></result>
        </collection>
    </resultMap>
 
    <select id="getDeptAndEmpByDeptId" resultMap="getDeptIdByRestultMap">
        select *
        from t_dept
        left join t_emp
        on t_dept.dept_id = t_emp.dept_id
        where t_dept.dept_id = #{deptId}
    </select>

* 第二种方法:分步查询

<!--    第二种方法:分步查询-->
<!--     Dept getDeptAndEmpByStepOne(@Param("deptId") Integer deptId);      -->
<!--    分步查询的第一步-->
    <resultMap id="getDeptAndEmpByStepOne" type="Dept">
        <id column="dept_id" property="deptId"></id>
        <result column="dept_name" property="deptName"></result>
        <collection property="emps"
                    select="com.gz.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"
                    column="dept_id"></collection>
    </resultMap>
    
    <select id="getDeptAndEmpByStepOne" resultMap="getDeptAndEmpByStepOne">
        select * from t_dept where dept_id = #{deptId}
    </select>
<!--    List<Emp> getDeptAndEmpByStepTwo(@Param("deptId") Integer deptId);      -->
 
    <select id="getDeptAndEmpByStepTwo" resultType="Emp">
        select * from t_emp where dept_id = #{deptId}
    </select>


10.分步查询的好处

1. 可以实现延迟加载

    * 在分步查询中,可以先给出查询的第一步结果,第二步结果如果暂时不需要可以不给出。减少内存消耗

2.实现延迟加载

        要实现延迟加载,必须先在核心配置文件中设置两个全局配置信息

        * lazyLoadingEnabled:延迟加载的全局开关。开启后,所有关联对象都会延迟加载;默认为false

        * aggressiveLazyLoading:开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载;默认为true

  <settings>
<!--          开启延迟加载      -->
        <setting name="lazyLoadingEnabled" value="true"/>
<!--          按需加载      -->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>

    * 这两个方法可以实现按需加载,要获取的数据是什么,就执行相应的SQL。

3.在延迟加载时如何查询所有结果

        此时存在一个问题,在核心配置文件中写了全局配置,会让所有分步查询都实现延迟加载。但无法根据需要一次将所有结果都查询出来

         解决方法:在association中使用fetchType:在开启了延迟加载的环境中,通过该属性设置当前的分步查询是否使用延迟加载;

若为:"eager":立即加载

           "lazy":延迟加载

<!--    fetchType = "eager"(立即加载)-->
<!--    fetchType = "lazy"(延迟加载)-->
<association property="dept" fetchType="lazy"
      select="com.gz.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
      column="dept_id"></association>
</resultMap>


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值