延迟加载、缓存、spring与声明式事务

什么是延迟加载

  • 延迟加载又称(懒加载)
  • resultMap中的 associationcollection 标签就具有延迟加载的功能(一对一,一对多的关系自带延迟加载,在开发里面最常用的)
    - 作用是:什么时候用什么时候加载

设置延迟加载

		<!--开启延迟加载-->
		<setting name="lazyLoadingEnabled" value="true"/>
		<!--关闭积极加载-->
		<setting name="aggressiveLazyLoading" value="false"/>
		<setting name="lazyLoadTriggerMethods" value=""/>(调用toString无效时加载)
  • 查询主表的信息(根据id来进行查询,子查询在resultMap(select="")如果是另一个包引入进来要加上完整的包名和类名,关联的字段)
    调用其方法时,会走子查询;
没有加载延迟的时候控制台显示
  • 会输出两句 查询
    在这里插入图片描述
加载延迟的时候控制台显示
  • 获取谁,就输出谁的查询
    在这里插入图片描述

缓存

  • 好处:提高加载的速度,同样的数据,不用一直查询数据库
  • 缺点;可能查询出脏数据;
一级缓存:(一级缓存的作用域是针对于我们的sqlsession(出了sqlsession 就没有一级缓存);默认一级缓存自动开启;
  • 如果是要关闭一级缓存,需要调用其commit()方法;
public class Test {
    public static void main(String[] args) {
        String path = "mybatis-config.xml";
        try {
        InputStream is = Resources.getResourceAsStream(path);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        //得到sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
        Role role = roleMapper.selectByIdRole(2);
        System.out.println(role.getRoleName());
        //sqlSession.commit();  未调用commit()
        System.out.println("-------分割线--------");
        RoleMapper roleMapper1= sqlSession.getMapper(RoleMapper.class);
        Role role1= roleMapper1.selectByIdRole(2);
        System.out.println(role1.getRoleName());
未调用 commit()发布方法代码显示

第二个经理就是在缓存中获取
在这里插入图片描述

调用 commit()发布方法代码显示

在这里插入图片描述

二级缓存:(是针对于整个mapper(namespace=“com.offcn.dao.UserMapper”))只要在同一个mapper中,缓存都有效果;
  • 配置二级缓存要注意(settings 里面配置两句话(开启缓存配置的按钮,第二个是要把你的对象序列化,
  • 第三个就是要把你的namespace 配置
    标签,这样就配置了二级缓存(用二级缓存的时候,一定要sqlsession.commit()(关闭一级缓存,加载二级缓存)),
  • 步骤:在nameSpace 加上 cache;刷新二级缓存的方法:sqlSession.clearCache();禁用:
需要添加 cache
<mapper namespace="com.offcn.dao.RoleMapper">
    <cache />
    <select id="selectByIdRole" parameterType="int" resultType="Role">
        select * from smbms_role where id=#{id}
    </select>
</mapper>

在这里插入图片描述

自定义缓存
  • 第一步 导入jar包
    • 导入一个mybatis-spring-1.2.0.jar
  • 第二步 所有的都是由spring来进行管理 ,写spring 的核心配置文件
    • applicationContext.xml(第一个bean 获取连接数据源,
    • 第二个bean 获取获取sqlSessionFactroy(引入数据库资源(dataSource) 第二个引入myBatis 核心配置文件)
    • 第三个bean (配置dao层 第一个是通过这个对象.MapperFactoryBean(引入你的接口的类,第二个是你的sqlSessionFactroy)"(第二种方式是MapperScannerConfigurer )))

spring 与 声明式事务()

  • 第一步: 引入数据库的配置信息(dataSource)
  • 第二步 :配置dao 层 配置服务层
  • 第三步: 配置事物管理器DataSourceTransactionManager (引入数据源资源,也就是dataSource)
  • 第四步 :定义事务通知(一种不用注解)(用注解)
    • ( 代表对应的方法名 第二个代表是事物的传播行为,事物失效的时间,事物的隔离级别–> <!– 指定异常进行回滚 这个代表参数的意思 )
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <!-- <property name="url">
            <value><![CDATA[jdbc:mysql://127.0.0.1:3306/smbms?
                    useUnicode=true&characterEncoding=utf-8]]></value>
        </property> -->
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/smbms?
                        useUnicode=true&amp;characterEncoding=utf-8" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>
     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
         <!--引入数据库资源-->
         <property name="dataSource" ref="dataSource"></property>
         <!--加载mybatis核心配置文件-->
         <property name="configLocation" value="classpath:mybatis-config.xml"></property>
     </bean>

    <!--配置userDao-->
     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
         <property name="basePackage" value="com.offcn.mapper"></property>
     </bean>
<!--定义一个事物管理器-->
     <bean id="transactionManger" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
         <!--引入数据源-->
         <property name="dataSource" ref="dataSource"></property>
     </bean>

    <!--定义事物通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManger">
        <tx:attributes>
            <!--name代表对应的方法名 第二个代表是事物的传播行为,事物失效的时间,事物的隔离级别--> <!--指定异常进行回滚-->
            <tx:method name="find" propagation="SUPPORTS" timeout="-1" isolation="DEFAULT" />
            <tx:method name="add" propagation="REQUIRED"></tx:method>
            <tx:method name="*" propagation="REQUIRED"></tx:method>
        </tx:attributes>
    </tx:advice>

    <!--定义切面-->
    <aop:config>
        <aop:pointcut id="serviceMethod" expression="execution(* com.offcn.service.UserService.*(..))"></aop:pointcut>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"></aop:advisor>
    </aop:config>

public class UserServiceImpl implements UserService {
    private UserMapper userMapper;

    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Override
    public void addUser(List<User> userList) {
        for (User user: userList) {
            userMapper.addUser(user);
        }
    }
}
第二种方式用的关键的注解 ()
   <!--自动扫描包-->
   <context:component-scan base-package="com.offcn.service"/>
   <!--开启注解驱动-->
   <tx:annotation-driven/>
  • 在 类前面 也就是你的service 的类上 @Transactional
  • 再到你的方法上配置具体的 @Transactional(propagation = Propagation.REQUIRED) 等同于 <tx:method name="*" propagation=“REQUIRED” />
  • 前面学过的注解 dao层的注解 @Repository service 层的@service @Autowired 按照类型
@Service("userSerbice")
/*事务的注解*/
@Transactional
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper userMapper;

    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    /*REQUIRED默认的,除了查询都用这个*/
    public void addUser(List<User> userList) {
        for (User user: userList) {
            userMapper.addUser(user);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值