spring的高级

1.mybatis的延迟加载与缓存:
什么是延迟加载:
举个例子:如果查询订单并且关联查询用户信息。如果先查询订单信息即可满足要求,当我们需要查询用户信息时再查询用户信息。把对用户信息的按需去查询就是延迟加载。 所以延迟加载即先从单表查询、需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。

使用association实现延迟加载:
这里我就拿association来说明,collection和association使用的方法都是一样的。需求就是上面提到的,查询订单并且关联查询用户,查询用户使用延迟加载。
  由上面的分析可知,延迟加载要查询两次,第二次是按需查询,之前一对一关联查询的时候只需要查一次,把订单和用户信息都查出来了,所以只要写一个mapper即可,但是延迟加载查两次,所以理所当然要有两个mapper。

一、两个mapper.xml配置:
1.RoleMapper.xml配置:

<select id="selectByIdRole" parameterType="int" resultType="Role" flushCache="true">
    select * from smbms_role where id=#{id}
</select>

2.UserMapper.xml文件:

<resultMap id="resultByIdMap" type="User">
    <id property="id" column="id"></id>
    <result property="userName" column="userName"></result>
    <result property="userRole" column="userRole"></result>
    <!--配置一对一的关系-->
    <!--由于是另一个Mapper文件引入过来,select子查询的完整的包名+类名+方法名,column两张表的关联字段-->
    <!--如果不在同一个mapper-->
    
    <association property="role" javaType="Role"
                 select="com.offcn.dao.RoleMapper.selectByIdRole" column="userRole">
    </association>
</resultMap>

<select id="selectById" parameterType="int" resultMap="resultByIdMap">

    select * from smbms_user where id=#{id}
</select>

二、 延迟加载的配置
mybatis默认没有开启延迟加载,需要在SqlMapConfig.xml中setting配置。前面一篇博文中提到SqlMapConfig.xml中的一些配置,有一个,当时没说,这里就派上用场了,可以通过这个标签来配置一下延迟加载
mybatis.xml核心配置文件:

1.定义接口类UserMapper :
package com.offcn.dao;

import com.offcn.entity.User;

import java.util.List;
import java.util.Map;

public interface UserMapper {
//延迟加载:
User selectById(int id);

2.定义接口类RoleMapper :
package com.offcn.dao;
import com.offcn.entity.Role;
public interface RoleMapper {

//查询语句
Role selectByIdRole(int id);

}
测试类:
import java.io.IOException;
import java.io.InputStream;

public class Text {

public static void main(String[] args) {


    try {
        String path="mybatis-config.xml";

        InputStream is= Resources.getResourceAsStream(path);

       SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is);
        //得到sqlSession
        SqlSession sqlSession= ssf.openSession();
        /*--------延迟加载--------*/
        /*如果不执行user.getRole()的方法就不调用子查询sql语句*/

        User user = sqlSession.getMapper(UserMapper.class).selectById(2);
        Role role = user.getRole();
        } 
        catch (IOException e) {
        e.printStackTrace();
    }
}

}
控制台结果如下:
“C:\Program Files\Java\jdk1.8.0_161\bin\java.exe” “-javaagent:D:\idea\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=57398:D:\idea\IntelliJ IDEA 2018.2.4\bin” -Dfile.encoding=UTF-8 -classpath “C:\Program Files\Java\jdk1.8.0_161\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\rt.jar;C:\Users\ibm\Documents\Tencent Files\2126067902\FileRecv\springDay01\out\production\mybatis01;C:\Users\ibm\Documents\Tencent Files\2126067902\FileRecv\springDay01\mybatis01\web\WEB-INF\lib\log4j-1.2.16.jar;C:\Users\ibm\Documents\Tencent Files\2126067902\FileRecv\springDay01\mybatis01\web\WEB-INF\lib\mybatis-3.4.6.jar;C:\Users\ibm\Documents\Tencent Files\2126067902\FileRecv\springDay01\mybatis01\web\WEB-INF\lib\mysql-connector-java-5.1.0-bin.jar” com.offcn.test.Text
[DEBUG] 2018-10-15 19:37:00,123 org.apache.ibatis.logging.LogFactory - Logging initialized using ‘class org.apache.ibatis.logging.log4j.Log4jImpl’ adapter.
[DEBUG] 2018-10-15 19:37:00,278 org.apache.ibatis.logging.LogFactory - Logging initialized using ‘class org.apache.ibatis.logging.log4j.Log4jImpl’ adapter.
[DEBUG] 2018-10-15 19:37:00,295 org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[DEBUG] 2018-10-15 19:37:00,295 org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[DEBUG] 2018-10-15 19:37:00,295 org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[DEBUG] 2018-10-15 19:37:00,295 org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[DEBUG] 2018-10-15 19:37:00,457 org.apache.ibatis.transaction.jdbc.JdbcTransaction - Opening JDBC Connection
[DEBUG] 2018-10-15 19:37:00,714 org.apache.ibatis.datasource.pooled.PooledDataSource - Created connection 2006034581.
[DEBUG] 2018-10-15 19:37:00,715 org.apache.ibatis.transaction.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@7791a895]
[DEBUG] 2018-10-15 19:37:00,719 com.offcn.dao.UserMapper.selectById - ==> Preparing: select * from smbms_user where id=?
[DEBUG] 2018-10-15 19:37:00,752 com.offcn.dao.UserMapper.selectById - > Parameters: 2(Integer)
[DEBUG] 2018-10-15 19:37:00,835 com.offcn.dao.UserMapper.selectById - <
Total: 1
[DEBUG] 2018-10-15 19:37:00,836 com.offcn.dao.RoleMapper - Cache Hit Ratio [com.offcn.dao.RoleMapper]: 0.0
[DEBUG] 2018-10-15 19:37:00,836 com.offcn.dao.RoleMapper.selectByIdRole - ==> Preparing: select * from smbms_role where id=?
[DEBUG] 2018-10-15 19:37:00,837 com.offcn.dao.RoleMapper.selectByIdRole - > Parameters: 2(Integer)
[DEBUG] 2018-10-15 19:37:00,838 com.offcn.dao.RoleMapper.selectByIdRole - <
Total: 1

二、查询缓存:
Mybatis提供查询缓存,用于减轻数据压力,提高数据库压力。
  Mybatis提供一级缓存和二级缓存。
在这里插入图片描述

在操作数据库时需要构造SqlSession对象,在对象中有一个数据结构(HashMap)用于缓存数据。

不同的SqlSession之间的缓存数据区域是互相不影响的。

Mybatis一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。

Mybatis二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。

如果SqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存。目的是为了让缓存中存储的是最新的信息,避免脏读。
Mybatis默认支持一级缓存,不需要在配置文件中配置。
  Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象。
  
  一级缓存–test类:
  package com.offcn.test;

import com.offcn.dao.RoleMapper;
import com.offcn.dao.UserMapper;
import com.offcn.entity.Role;
import com.offcn.entity.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;

public class Text {

public static void main(String[] args) {


    try {
       String path="mybatis-config.xml";

        InputStream is= Resources.getResourceAsStream(path);

       SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is);
        //得到sqlSession
        SqlSession sqlSession= ssf.openSession();
       RoleMapper roleMapper= sqlSession.getMapper(RoleMapper.class);
        
        System.out.println(roleMapper.selectByIdRole(3).getRoleName());
    
       System.out.println("---------分割线-------");

        Role role1= sqlSession.getMapper(RoleMapper.class).selectByIdRole(3);
        System.out.println(role1.getRoleName());
        sqlSession.close();
         } catch (IOException e) {
        e.printStackTrace();
    }
}

}

二级缓存:
需要在RoleMapper.xml文件设置**

<?xml version="1.0" encoding="UTF-8" ?>
<select id="selectByIdRole" parameterType="int" resultType="Role" flushCache="true">
    select * from smbms_role where id=#{id}
</select>

在mybtais.xml核心文件设置:

<?xml version="1.0" encoding="UTF-8" ?>

3.然后Role的类需要序列化
package com.offcn.entity;
import java.io.Serializable;
import java.util.Date;
public class Role implements Serializable {

private Integer id;   //id
private String roleCode; //角色编码
private String roleName; //角色名称
private Integer createdBy; //创建者
private Date creationDate; //创建时间
private Integer modifyBy; //更新者
private Date modifyDate;//更新时间

public Integer getId() {
    return id;
}
public void setId(Integer id) {
    this.id = id;
}
public String getRoleCode() {
    return roleCode;
}
public void setRoleCode(String roleCode) {
    this.roleCode = roleCode;
}
public String getRoleName() {
    return roleName;
}
public void setRoleName(String roleName) {
    this.roleName = roleName;
}
public Integer getCreatedBy() {
    return createdBy;
}
public void setCreatedBy(Integer createdBy) {
    this.createdBy = createdBy;
}
public Date getCreationDate() {
    return creationDate;
}
public void setCreationDate(Date creationDate) {
    this.creationDate = creationDate;
}
public Integer getModifyBy() {
    return modifyBy;
}
public void setModifyBy(Integer modifyBy) {
    this.modifyBy = modifyBy;
}
public Date getModifyDate() {
    return modifyDate;
}
public void setModifyDate(Date modifyDate) {
    this.modifyDate = modifyDate;
}}

测试类test

package com.offcn.test;

import com.offcn.dao.RoleMapper;
import com.offcn.dao.UserMapper;
import com.offcn.entity.Role;
import com.offcn.entity.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;

public class Text {

public static void main(String[] args) {

    try {
        String path="mybatis-config.xml";

        InputStream is= Resources.getResourceAsStream(path);

       SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is);
        //得到sqlSession
        SqlSession sqlSession= ssf.openSession();

/二级缓存/
RoleMapper roleMapper= sqlSession.getMapper(RoleMapper.class);
//RoleMapper roleMapper1= sqlSession1.getMapper(RoleMapper.class);

        System.out.println(roleMapper.selectByIdRole(3).getRoleName());
        sqlSession.commit();//关闭一级缓存
       System.out.println("---------分割线-------");

        System.out.println(roleMapper.selectByIdRole(3).getRoleName());
        //Role role1= sqlSession.getMapper(RoleMapper.class).selectByIdRole(3);
        //System.out.println(role1.getRoleName());
        sqlSession.close();} catch (IOException e) {
        e.printStackTrace();
    }
}

}
console的输出结果:
[DEBUG] 2018-10-16 18:16:54,802 com.offcn.dao.RoleMapper - Cache Hit Ratio [com.offcn.dao.RoleMapper]: 0.0
[DEBUG] 2018-10-16 18:16:54,809 org.apache.ibatis.transaction.jdbc.JdbcTransaction - Opening JDBC Connection
[DEBUG] 2018-10-16 18:16:55,089 org.apache.ibatis.datasource.pooled.PooledDataSource - Created connection 488044861.
[DEBUG] 2018-10-16 18:16:55,089 org.apache.ibatis.transaction.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1d16f93d]
[DEBUG] 2018-10-16 18:16:55,092 com.offcn.dao.RoleMapper.selectByIdRole - ==> Preparing: select * from smbms_role where id=?
[DEBUG] 2018-10-16 18:16:55,126 com.offcn.dao.RoleMapper.selectByIdRole - > Parameters: 3(Integer)
[DEBUG] 2018-10-16 18:16:55,161 com.offcn.dao.RoleMapper.selectByIdRole - <
Total: 1
普通员工
---------分割线-------
[DEBUG] 2018-10-16 18:16:55,245 com.offcn.dao.RoleMapper - Cache Hit Ratio [com.offcn.dao.RoleMapper]: 0.5
[DEBUG] 2018-10-16 18:16:55,245 com.offcn.dao.RoleMapper.selectByIdRole - ==> Preparing: select * from smbms_role where id=?
[DEBUG] 2018-10-16 18:16:55,246 com.offcn.dao.RoleMapper.selectByIdRole - > Parameters: 3(Integer)
[DEBUG] 2018-10-16 18:16:55,247 com.offcn.dao.RoleMapper.selectByIdRole - <
Total: 1
普通员工
其中0.5是指的是二级缓存命中率

猜你喜欢

转载自blog.csdn.net/weixin_42772943/article/details/83066242