mybatis的缓存和注解开发(4)

第四天:mybatis的缓存和注解开发
 mybatis中的加载时机(查询的时机)
 mybatis中的一级缓存和二级缓存
 mybatis的注解开发
  单表CRUD
  多表查询



一、今日内容概要

1、Mybatis中的延迟加载
 问题:在一对多中,当我们有一个用户,它有100个账户。
       在查询用户的时候,要不要把关联的账户查出来?
       在查询账户的时候,要不要把关联的用户查出来?
  
       在查询用户时,用户下的账户信息应该是,什么时候使用,什么时候查询的。
       在查询账户时,账户的所属用户信息应该是随着账户查询时一起查询出来。

什么是延迟加载
  在真正使用数据时才发起查询,不用的时候不查询。按需加载(懒加载)
 什么是立即加载
  不管用不用,只要一调用方法,马上发起查询。
 
 在对应的四种表关系中:一对多,多对一,一对一,多对多
  一对多,多对多:通常情况下我们都是采用延迟加载。
  多对一,一对一:通常情况下我们都是采用立即加载。

2、Mybatis中的缓存
 什么是缓存
  存在于内存中的临时数据。
 为什么使用缓存
  减少和数据库的交互次数,提高执行效率。
 什么样的数据能使用缓存,什么样的数据不能使用
  适用于缓存:
   经常查询并且不经常改变的。
   数据的正确与否对最终结果影响不大的。
  不适用于缓存:
   经常改变的数据
   数据的正确与否对最终结果影响很大的。
   例如:商品的库存,银行的汇率,股市的牌价。
 Mybatis中的一级缓存和二级缓存
  一级缓存:
   它指的是Mybatis中SqlSession对象的缓存。
   当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供一块区域中。
   该区域的结构是一个Map。当我们再次查询同样的数据,mybatis会先去sqlsession中
   查询是否有,有的话直接拿出来用。
   当SqlSession对象消失时,mybatis的一级缓存也就消失了。
  
  二级缓存:
   它指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。
   二级缓存的使用步骤:
    第一步:让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
    第二步:让当前的映射文件支持二级缓存(在IUserDao.xml中配置)
    第三步:让当前的操作支持二级缓存(在select标签中配置)
3、Mybatis中的注解开发  


二、Mybatis中的延迟加载

1.一对一实现延迟加载

IAccountDao.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.itheima.dao.IAccountDao">

    <!-- 定义封装account和user的resultMap -->
    <resultMap id="accountUserMap" type="account">
        <id property="id" column="id"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
        <!-- 一对一的关系映射:配置封装user的内容
        select属性指定的内容:查询用户的唯一标识:
        column属性指定的内容:用户根据id查询时,所需要的参数的值
        -->
        <association property="user" column="uid" javaType="user" select="com.itheima.dao.IUserDao.findById"></association>
    </resultMap>

    <!-- 查询所有 -->
    <select id="findAll" resultMap="accountUserMap">
        select * from account
    </select>

    <!-- 根据用户id查询账户列表 -->
    <select id="findAccountByUid" resultType="account">
        select * from account where uid = #{uid}
    </select>

</mapper>

SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 配置properties-->
    <properties resource="jdbcConfig.properties"></properties>

    <!--配置参数-->
    <settings>
        <!--开启Mybatis支持延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"></setting>
    </settings>

    <!--使用typeAliases配置别名,它只能配置domain中类的别名 -->
    <typeAliases>
        <package name="com.itheima.domain"></package>
    </typeAliases>

    <!--配置环境-->
    <environments default="mysql">
        <!-- 配置mysql的环境-->
        <environment id="mysql">
            <!-- 配置事务 -->
            <transactionManager type="JDBC"></transactionManager>

            <!--配置连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"></property>
                <property name="url" value="${jdbc.url}"></property>
                <property name="username" value="${jdbc.username}"></property>
                <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>
    </environments>
    <!-- 配置映射文件的位置 -->
    <mappers>
        <package name="com.itheima.dao"></package>
    </mappers>
</configuration>

2.多对多实现延迟加载

IUserDao.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.itheima.dao.IUserDao">

    <!-- 定义User的resultMap-->
    <resultMap id="userAccountMap" type="user">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="address" column="address"></result>
        <result property="sex" column="sex"></result>
        <result property="birthday" column="birthday"></result>
        <!-- 配置user对象中accounts集合的映射 -->      (批注:在映射配置文件中 调用相关联的一方的根据id查询的方法)
        <collection property="accounts" ofType="account" select="com.itheima.dao.IAccountDao.findAccountByUid" column="id"></collection>
    </resultMap>

    <!-- 查询所有 -->
    <select id="findAll" resultMap="userAccountMap">
        select * from user
    </select>

    <!-- 根据id查询用户 -->
    <select id="findById" parameterType="INT" resultType="user">
        select * from user where id = #{uid}
    </select>

</mapper>


三、Mybatis中的缓存

1.测试一级缓存

    /**
     * 测试一级缓存
     */
    @Test
    public void testFirstLevelCache(){
        User user1 = userDao.findById(41);
        System.out.println(user1);

//        sqlSession.close();
        //再次获取SqlSession对象
//        sqlSession = factory.openSession();

        sqlSession.clearCache();//此方法也可以清空缓存

   userDao = sqlSession.getMapper(IUserDao.class);

        User user2 = userDao.findById(41);
        System.out.println(user2);

        System.out.println(user1 == user2);
    }

一级缓存是SqlSession范围的缓存,当调用SqlSession的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存。

2.测试二级缓存

第一步:让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 配置properties-->
    <properties resource="jdbcConfig.properties"></properties>

    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>

    <!--使用typeAliases配置别名,它只能配置domain中类的别名 -->
    <typeAliases>
        <package name="com.itheima.domain"></package>
    </typeAliases>

    <!--配置环境-->
    <environments default="mysql">
        <!-- 配置mysql的环境-->
        <environment id="mysql">
            <!-- 配置事务 -->
            <transactionManager type="JDBC"></transactionManager>

            <!--配置连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"></property>
                <property name="url" value="${jdbc.url}"></property>
                <property name="username" value="${jdbc.username}"></property>
                <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>
    </environments>
    <!-- 配置映射文件的位置 -->
    <mappers>
        <package name="com.itheima.dao"></package>
    </mappers>
</configuration>

第二步:让当前的映射文件支持二级缓存(在IUserDao.xml中配置)

第三步:让当前的操作支持二级缓存(在select标签中配置)

<?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.itheima.dao.IUserDao">
    <!--开启user支持二级缓存 默认为true-->
    <cache/>  

    <!-- 查询所有 -->
    <select id="findAll" resultType="user">
        select * from user
    </select>

    <!-- 根据id查询用户 -->
    <select id="findById" parameterType="INT" resultType="user" useCache="true">
        select * from user where id = #{uid}
    </select>

    <!-- 更新用户信息-->
    <update id="updateUser" parameterType="user">
        update user set username=#{username},address=#{address} where id=#{id}
    </update>
</mapper>



四、Mybatis中的注解开发

1.环境搭建

2.单表CRUD操作(代理Dao方式)

sqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 引入外部配置文件-->
    <properties resource="jdbcConfig.properties"></properties>
    <!--配置别名-->
    <typeAliases>
        <package name="com.itheima.domain"></package>
    </typeAliases>
    <!-- 配置环境-->
    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"></property>
                <property name="url" value="${jdbc.url}"></property>
                <property name="username" value="${jdbc.username}"></property>
                <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>
    </environments>
    <!-- 指定带有注解的dao接口所在位置 -->
    <mappers>
        <mapper class="com.itheima.dao.IUserDao"></mapper>      或者    <package name="com.itheima.dao"></package>
    </mappers>
</configuration>

IUserDao

package com.itheima.dao;

import com.itheima.domain.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

/**

 * 在mybatis中针对,CRUD一共有四个注解
 *  @Select @Insert @Update @Delete
 */
public interface IUserDao {

    /**
     * 查询所有用户
     * @return
     */
    @Select("select * from user")
    List<User> findAll();

    /**
     * 保存用户
     * @param user
     */
    @Insert("insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday})")
    void saveUser(User user);

    /**
     * 更新用户
     * @param user
     */
    @Update("update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address} where id=#{id}")
    void updateUser(User user);

    /**
     * 删除用户
     * @param userId
     */
    @Delete("delete from user where id=#{id} ")
    void deleteUser(Integer userId);

    /**
     * 根据id查询用户
     * @param userId
     * @return
     */
    @Select("select * from user  where id=#{id} ")
    User findById(Integer userId);

    /**
     * 根据用户名称模糊查询
     * @param username
     * @return
     */
//    @Select("select * from user where username like #{username} ")
    @Select("select * from user where username like ‘%${value}%‘ ")
    List<User> findUserByName(String username);

    /**
     * 查询总用户数量
     * @return
     */
    @Select("select count(*) from user ")
    int findTotalUser();
}

3.多表查询操作

使用注解来解决实体类属性与数据库表列名对应不上的问题

    /**
     * 查询所有用户
     * @return
     */
    @Select("select * from user")
    @Results(id="userMap",value={
            @Result(id=true,column = "id",property = "userId"),
            @Result(column = "username",property = "userName"),
            @Result(column = "address",property = "userAddress"),
            @Result(column = "sex",property = "userSex"),
            @Result(column = "birthday",property = "userBirthday"),

    })
    List<User> findAll();

mybatis注解开发一对一的查询配置

public interface IAccountDao {

    /**
     * 查询所有账户,并且获取每个账户所属的用户信息
     * @return
     */
    @Select("select * from account")
    @Results(id="accountMap",value = {
            @Result(id=true,column = "id",property = "id"),
            @Result(column = "uid",property = "uid"),
            @Result(column = "money",property = "money"),
            @Result(property = "user",column = "uid",one=@One(select="com.itheima.dao.IUserDao.findById",fetchType= FetchType.EAGER))
    })
    List<Account> findAll();

    /**
     * 根据用户id查询账户信息
     * @param userId
     * @return
     */
    @Select("select * from account where uid = #{userId}")
    List<Account> findAccountByUid(Integer userId);
}

mybatis注解开发一对多的查询配置

package com.itheima.dao;

import com.itheima.domain.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;

import java.util.List;

@CacheNamespace(blocking = true)
public interface IUserDao {

    /**
     * 查询所有用户
     * @return
     */
    @Select("select * from user")
    @Results(id="userMap",value={
            @Result(id=true,column = "id",property = "userId"),
            @Result(column = "username",property = "userName"),
            @Result(column = "address",property = "userAddress"),
            @Result(column = "sex",property = "userSex"),
            @Result(column = "birthday",property = "userBirthday"),
            @Result(property = "accounts",column = "id",
                    many = @Many(select = "com.itheima.dao.IAccountDao.findAccountByUid",
                                fetchType = FetchType.LAZY))
    })
    List<User> findAll();

    /**
     * 根据id查询用户
     * @param userId
     * @return
     */
    @Select("select * from user  where id=#{id} ")
    @ResultMap("userMap")
    User findById(Integer userId);

    /**
     * 根据用户名称模糊查询
     * @param username
     * @return
     */
    @Select("select * from user where username like #{username} ")
    @ResultMap("userMap")
    List<User> findUserByName(String username);

}

4. 缓存的配置

第一步:让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 引入外部配置文件-->
    <properties resource="jdbcConfig.properties"></properties>
    <!--配置开启二级缓存-->
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>

    <!--配置别名-->
    <typeAliases>
        <package name="com.itheima.domain"></package>
    </typeAliases>
    <!-- 配置环境-->
    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"></property>
                <property name="url" value="${jdbc.url}"></property>
                <property name="username" value="${jdbc.username}"></property>
                <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>
    </environments>
    <!-- 指定带有注解的dao接口所在位置 -->
    <mappers>
       <package name="com.itheima.dao"></package>
    </mappers>
</configuration>

第二步:让当前的操作支持二级缓存(在select标签中配置)

@CacheNamespace(blocking = true)
public interface IUserDao {

    /**
     * 查询所有用户
     * @return
     */
    @Select("select * from user")
    @Results(id="userMap",value={
            @Result(id=true,column = "id",property = "userId"),
            @Result(column = "username",property = "userName"),
            @Result(column = "address",property = "userAddress"),
            @Result(column = "sex",property = "userSex"),
            @Result(column = "birthday",property = "userBirthday"),
            @Result(property = "accounts",column = "id",
                    many = @Many(select = "com.itheima.dao.IAccountDao.findAccountByUid",
                                fetchType = FetchType.LAZY))
    })
    List<User> findAll();

测试方法

    @Test
    public void testFindOne(){
        SqlSession session = factory.openSession();
        IUserDao userDao = session.getMapper(IUserDao.class);
        User user = userDao.findById(57);
        System.out.println(user);

        session.close();//释放一级缓存

        SqlSession session1 = factory.openSession();//再次打开session
        IUserDao userDao1 = session1.getMapper(IUserDao.class);
        User user1 = userDao1.findById(57);
        System.out.println(user1);

        session1.close();

    }
 

原文地址:https://www.cnblogs.com/lsk-130602/p/12202311.html

时间: 2024-08-02 06:38:53

mybatis的缓存和注解开发(4)的相关文章

Spring+SpringMVC+MyBatis深入学习及搭建(十六)——SpringMVC注解开发(高级篇)

转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7085268.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(十五)——SpringMVC注解开发(基础篇) 本文主要内容: (1)SpringMVC校验 (2)数据回显 (3)异常处理器 (4)图片上传 (5)Json数据交互 (6)支持RESTful 1.SpringMVC校验 1.1校验理解 项目中,通常使用较多的是前端的校验,比如页面中js校验.对于安全要求较高的

Mybatis-04 懒加载&amp;缓存&amp;注解开发

1.Mybatis延迟加载策略 1.1 什么是延迟加载(懒加载)? 简单的说,就是要用到数据时才加载,否则不加载. 好处:先单表查询,要用时才去关联查询,提高数据库性能. 坏处:大批量数据查询的时候,查询可能消耗时间,影响用户体验. 1.2 Mybatis的延迟加载 上一个文章说要,association.collection实现了一对一及一对多的映射,他们时具有延迟加载功能的. 一般一对一用立即加载,一对多用延迟加载. 1.2.1 使用assocation实现延迟加载 需求如:查询账户(Acc

从零开始学JAVA(09)-使用SpringMVC4 + Mybatis + MySql 例子(注解方式开发)

项目需要,继续学习springmvc,这里加入Mybatis对数据库的访问,并写下一个简单的例子便于以后学习,希望对看的人有帮助.上一篇被移出博客主页,这一篇努力排版整齐,更原创,希望不要再被移出主页了. 原创文章,后面附上源码,转载请注明出处http://www.cnblogs.com/lin557/p/6179618.html 一.运行环境 Eclipse Neon.1a Release (4.6.1) 官网下载 mysql-5.7.16-winx64(http://cdn.mysql.co

MyBatis框架之注解开发

MyBatis注解开发 @Insert注解注解属性value:写入SQL语句 @Options注解实现添加新数据的主键封装注解属性useGeneratedKeys:使用生成的主键,配置为truekeyProperty:主键封装的pojo对象属性 @SelectKey注解实现添加新数据的主键封装注解属性statement:要执行的SQL语句before:在添加SQL语句之前还是之后进行,配置为false keyProperty:主键封装的pojo对象属性 注解实现添加数据 UserMapper接口

MyBatis——使用注解开发

日子过得很慢,生活过得很烂,除了想你,其他我什么都做不好. 使用注解开发 1.面向接口编程 面向接口编程的根本原因:解耦,可扩展,提高复用,分层开发中.上层不用管具体的实现,大家都遵守共同的标准,使得开发变得容易,规范性好 2.使用注解开发 注解在接口上实现 @Select(value = "select * from user") List<User> getUsers(); 需要在核心配置文件中绑定接口 <!--绑定接口--> <mappers>

阶段3 1.Mybatis_12.Mybatis注解开发_1 mybatis注解开发的环境搭建

注解开发是省了IUserDao.xml这个映射文件里面的配置 环境搭建 首先是packaging标签.输入jar 需要准备一个实体类.生成getter和setter还有toString方法 创建dao接口.先写一个查询所有的接口 按照原来的要求需要在resources下创建Directory也就是文件夹 创建了com.itheima.dao这三个文件夹.为了演示用. 配置主配置文件SqlMapConfig.xmls 复制给的资料里面的config的约束 先输入configuration标签.然互

spring+springmvc+mybatis-plus 纯注解开发

最近刚完成一个项目,刚好有一点时间,来完成基于spring+springmvc+mybatis-plus 纯注解开发 一.创建工程.导入依赖 1.新建一个基于maven的web工程,使用JDK1.8 2.调整目录结构 2.1.新建java 2.2.新建resources 2.3.删除web.xml.构建基础包 2.4.工程目录构建完成展示 2.配置tomcat服务器 2.1.服务器配置 2.2.测试服务器配置 3.pom.xml文件配置 1 <properties> 2 <project

mybatis查询缓存——(十三)

1.     mybatis缓存介绍 如下图,是mybatis一级缓存和二级缓存的区别图解: mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在操作数据库时需要构造 sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据.不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的. 二级缓存是mapper级别的缓存,多个SqlSession去操作同一个

MyBatis学习笔记(四) 注解

使用MyBatis注解开发,可以省去类配置文件,简洁方便.但是比较复杂的SQL和动态SQL还是建议书写类配置文件. 注解还是不推荐使用的.只是了解了解!简单的CRUD可以使用注解.简单写写. 把之前的例子改成使用注解的. UserMapper.java 1 package com.cy.mybatis.mapper; 2 3 import java.util.List; 4 import java.util.Map; 5 6 import org.apache.ibatis.annotation