mybatis下

本文详细介绍了Mybatis中处理多对一、一对一关系的级联和association方式,如何启用和控制延迟加载,以及一对多关系的collection处理。此外,涵盖了动态SQL的使用、分页插件PageHelper的配置和应用实例。
摘要由CSDN通过智能技术生成
(12).处理多对一映射关系
  1. 级联的方式

    <resultMap id="empAndDept" type="Emp">
         <id column="emp_id" property="empId"></id>
            <result column="emp_name" property="empName"></result>
            <result column="emp_gender" property="empGender"></result>
            <result column="emp_age" property="empAge"></result>
            <result column="dept_id" property="dept.deptId"></result>
            <result column="dept_name" property="dept.deptName"></result>
        </resultMap>
    
        <select id="getEmp" resultMap="empAndDept">
            select * from emp e left join dept d on e.dept_id = d.dept_id where e.emp_id = #{id}
        </select>
    
  2. association的方式:处理多对一和一对一(处理实体类类型的属性)

    <resultMap id="empAndDept" type="Emp">
         <id column="emp_id" property="empId"></id>
            <result column="emp_name" property="empName"></result>
            <result column="emp_gender" property="empGender"></result>
            <result column="emp_age" property="empAge"></result>
           <association property="dept" javaType="Dept">
               <id column="dept_id" property="deptId"></id>
               <result column="dept_Name" property="deptName"></result>
           </association>
        </resultMap>
    
    
        <select id="getEmp" resultMap="empAndDept">
            select * from emp e left join dept d on e.dept_id = d.dept_id where e.emp_id = #{id}
        </select>
    
  3. 使用分步查询的方式

    <resultMap id="empAndDeptStep" type="Emp">
        <id column="emp_id" property="empId"></id>
        <result column="emp_name" property="empName"></result>
        <result column="emp_gender" property="empGender"></result>
        <result column="emp_age" property="empAge"></result>
        <association property="dept" select="com.xs.mybatis.mapper.DeptMapper.getDeptStepTow" column="dept_id">
        </association>
    </resultMap>

<!--    Emp getEmpStepOne(@Param("id") int id);-->
    <select id="getEmpStepOne" resultMap="empAndDeptStep">
        select *from emp where emp_id = #{id}
    </select>
<!--        Dept getDeptStepTow(@Param("id") int id);-->
    <select id="getDeptStepTow" resultType="Dept">
        select * from dept where dept_id = #{id}
    </select>
(13).延迟加载

Mybatis -config.xml文件中全局配置

		<!--开启延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--开启按需加载-->
        <setting name="aggressiveLazyLoading" value="false"/>
<!--
	fetchType:在开启了延迟加载的环境中,设置是否启用延迟家长
	fetchType="eager(立即加载) | lazy(延迟加载) "
-->
<association property="dept" fetchType="eager" select="com.xs.mybatis.mapper.DeptMapper.getDeptStepTow" column="dept_id"
association>
(14).处理一对多的映射关系
  1. 通过collection处理

        <resultMap id="deptAndEmp" type="Dept">
            <id column="dept_id" property="deptId"></id>
            <result column="dept_name" property="deptName"></result>
            <!--
            ofType:定义集合数据的类型
             -->
            <collection property="emps" ofType="Emp">
                <id column="emp_id" property="empId"></id>
                <result column="emp_name" property="empName"></result>
                <result column="emp_gender" property="empGender"></result>
                <result column="emp_age" property="empAge"></result>
            </collection>
        </resultMap>
    
    <!--    Dept getDepAndEmp(@Param("id") int id);-->
        <select id="getDepAndEmp" resultMap="deptAndEmp">
            select * from dept d left join emp e on d.dept_id = e.dept_id where d.dept_id = #{id}
        </select>
    
    (15).动态SQL
    1. if

      <!--        List<Emp> getEmpByCondition(Emp emp);-->
          <select id="getEmpByCondition" resultType="Emp">
                select *from emp where
                <if test="empName != null and empName != ''">
                    emp_name =#{empName}
                </if>
              <if test="empAge != null and empAge != ''">
                  and emp_age =#{empAge}
              </if>
              <if test="empGender != null and empGender != ''">
                  and emp_gender =#{empGender}
              </if>
          </select>
      
    2. where

      	<!--
      		where和if一般结合使用:
      
      		a>==若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字==
      
      		*b>若where标签中的if条件满足,**则where标签会自动添加where关键字,==并将条件最前方多余的==**
      
      		==***and去掉***==
      
      		注意:***where标签不能去掉条件最后多余的and***
      	-->
      <select id="getEmpByCondition" resultType="Emp">
                select *from emp
              <where>
                  <if test="empName != null and empName != ''">
                      emp_name =#{empName}
                  </if>
                  <if test="empAge != null and empAge != ''">
                      and emp_age =#{empAge}
                  </if>
                  <if test="empGender != null and empGender != ''">
                      and emp_gender =#{empGender}
                  </if>
              </where>
      
      </select>
      
    3. trim

      <!--
      常用属性:
      
      prefix:在**trim标签**中的内容的前面==添加==某些内容
      
      prefixOverrides:在**trim标签**中的内容的前面==去掉==某些内容
      
      suffix:在**trim标签**中的内容的后面==添加==某些内容
      
      suffixOverrides:在**trim标签**中的内容的后面==去掉==某些内容
      -->    
      
      <select id="getEmpByCondition" resultType="Emp">
                select *from emp
              <trim prefix="where" suffixOverrides="and">
                  <if test="empName != null and empName != ''">
                      emp_name =#{empName} and
                  </if>
                  <if test="empAge != null and empAge != ''">
                       emp_age =#{empAge} and
                  </if>
                  <if test="empGender != null and empGender != ''">
                       emp_gender =#{empGender}
                  </if>
              </trim>
          </select>
      
    4. choose when otherwise 相当于 if else if

      <!--List<Emp> getEmpListByChoose(Emp emp);-->
      <select id="getEmpListByChoose" resultType="Emp">
      	select <include refid="empColumns"></include> from t_emp
      	<where>
      		<choose>
      			<when test="ename != '' and ename != null">
      				ename = #{ename}
      			</when>
      			<when test="age != '' and age != null">
      				age = #{age}
      			</when>
      			<when test="sex != '' and sex != null">
      				sex = #{sex}
      			</when>
      			<when test="email != '' and email != null">
      				email = #{email}
      			</when>
                  <otherwise>  
                      uname=#{name}
                  </otherwise>
      		</choose>
      	</where>
      </select>
      
    5. foreach

批量添加

<insert id="inserMoreEmp">
    insert into emp values
    <foreach collection="emps" item="emp" separator=",">
        (null,#{emp.empName},#{emp.empGender},#{emp.empAge},null)
    </foreach>
</insert>

批量删除

<!--    int deleteMoreEmp(@Param("emps")Emp[] emps);-->
    <delete id="deleteMoreEmp">
        delete from emp where emp_id in
            <foreach collection="emps" item="item" separator="," open="(" close=")">
                #{item}
            </foreach>
    </delete>

​ 6.SQL

<sql id="empColumns">
	eid,ename,age,sex,did
</sql>
select <include refid="empColumns"></include> from t_emp

(16).Mybatis缓存

16.1一级缓存(默认开启):

​ 一级缓存是***SqlSession级别的***,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问,默认开启着的

使一级缓存失效的四种情况

  1. 不同的SqlSession对应不同的一级缓存
  2. 同一个SqlSession但是查询条件不同
  3. 同一个SqlSession两次查询期间执行了任何一次增删改操作(不管是不是针对你缓存的表)
  4. 同一个SqlSession两次查询期间手动清空了缓存****:sqlSession.clearCache(); //手动清空了缓存*****

16.2二级缓存:

*二级缓存是**SqlSessionFactory级别,***通过同一个SqlSessionFactory创建的SqlSession查询的结果会被

缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取**

二级缓存开启的条件:

a>在核心配置文件中,设置全局配置属性cacheEnabled=“true”,默认为true,不需要设置

b>在映射文件中设置标签

c>二级缓存必须在SqlSession关闭或提交(手动提交)之后有效(才能真正进入缓存)

d>查询的数据所转换的实体类类型必须实现序列化的接口

使二级缓存失效的情况:

两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效

(17).分页

limit index,pageSize

pageSize:每页显示的条数

pageNum:当前页的页码

index:当前页的起始索引,index=(pageNum-1)*pageSize

count:总记录数

totalPage:总页数

totalPage = count / pageSize;

if(count % pageSize != 0){

totalPage += 1;

}

pageSize=4,pageNum=1,index=0 limit 0,4

pageSize=4,pageNum=3,index=8 limit 8,4

pageSize=4,pageNum=6,index=20 limit 8,4

首页 上一页 2 3 4 5 6 下一页 末页

①添加依赖

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.2.0</version>
</dependency>

②配置分页插件

在MyBatis的核心配置文件中配置插件

<plugins>
    <!--设置分页插件-->
    <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>	

分页插件的使用

a>在查询功能之前使用PageHelper.startPage(int pageNum, int pageSize)开启分页功能

pageNum:当前页的页码

pageSize:每页显示的条数

b>在查询获取list集合之后,使用PageInfo pageInfo = new PageInfo<>(List list, int

navigatePages)获取分页相关数据,更深层次获取分页属性

list:分页之后的数据

navigatePages:导航分页的页码数

c>分页相关数据

PageInfo{

pageNum=8, pageSize=4, size=2, startRow=29, endRow=30, total=30, pages=8,

list=Page{count=true, pageNum=8, pageSize=4, startRow=28, endRow=32, total=30,

pages=8, reasonable=false, pageSizeZero=false},

prePage=7, nextPage=0, isFirstPage=false, isLastPage=true, hasPreviousPage=true,

hasNextPage=false, navigatePages=5, navigateFirstPage4, navigateLastPage8,

navigatepageNums=[4, 5, 6, 7, 8]

}

pageNum:当前页的页码

pageSize:每页显示的条数

size:当前页显示的真实条数

total:总记录数

pages:总页数

prePage:上一页的页码

nextPage:下一页的页码

isFirstPage/isLastPage:是否为第一页/最后一页

hasPreviousPage/hasNextPage:是否存在上一页/下一页

navigatePages:导航分页的页码数

navigatepageNums:导航分页的页码,[1,2,3,4,5]

@Test
    public void test4() throws IOException {
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        StarMapper mapper = sqlSession.getMapper(StarMapper.class);
        Page<Object> page = PageHelper.startPage(2, 3);  //page中封装了分页的信息。可以没有page返回值,PageHelper.startPage(2, 3)是开启分页的必要功能,并且要放在查询zhi'qian
        List<Star> stars = mapper.selectByExample(null);
        PageInfo<Star> pageInfo = new PageInfo<>(stars,2); //pageinfo中封装了比page更详细的分页信息,但是是查询功能之后,不是查询功能之前
        stars.forEach(System.out::println);
        System.out.println(page);
        System.out.println(pageInfo);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值