Mybatis中的的延迟加载、缓存和注解开发

Mybatis中的的延迟加载、缓存和注解开发,第1张

Mybatis中的的延迟加载、缓存和注解开发 Mybatis中的的延迟加载、缓存和注解开发 1.Mybatis中的延迟加载

问题:在一对多中,当我们有一个用户,他有100个账户
查询用户的时候,要不要把关联的账户查出来?
在查询账户的时候,要不要把我关联的用户查出来

在查询用户时,用户下的账户信息应该是什么时候使用,什么时候查询的

在查询账户时,账户的所属用户信息应该是睡着查询时一起查询出来的

解决:

延迟加载:在真正使用数据时才发起查询,不用的时候不查询,按需加载立即加载:不管用不用,只要一调用方法,马上发起查询

在对应的四种表关系中:一对多,多对一,多对多

一对多,多对多:通常情况下我们都是采用延迟加载多对一,一对一:通常情况请下我们采用立即加载
我们在查询mybatis的官方文档时,lazyLoadingEnable就是延迟加载全局开关,以及aggressiveLazyLoading调用加载该对象的属性

1.一对一代码实现:

Account实现类

package com.mybatisD.domain;

import java.io.Serializable;


public class Account  implements Serializable {
    private  Integer id;
    private Integer uid;
    private double money;
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getUid() {
        return uid;
    }

    public void setUid(Integer uid) {
        this.uid = uid;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", uid=" + uid +
                ", money=" + money +
                '}';
    }
}

User实现类

package com.mybatisD.domain;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

public class User implements Serializable {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    //多对多的关系映射,一个用户可以具备多个角色
    private List roles;

    public List getRoles() {
        return roles;
    }

    public void setRoles(List roles) {
        this.roles = roles;
    }

    private List account;
//一对多关系映射,主表实体应该包含从表实体的集合引用
    public List getAccount() {

        return account;
    }

    public void setAccount(List account) {
        this.account = account;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + ''' +
                ", birthday=" + birthday +
                ", sex='" + sex + ''' +
                ", address='" + address + ''' +
                '}';
    }
}

IAccountDao接口

package com.mybatisD.dao;

import com.mybatisD.domain.Account;
import com.mybatisD.domain.AccountUser;

import java.util.List;

public interface IAccountDao {
    //查询所有账户
    List findAll();
    //查询账户,并且带有用户名称和地址信息
    List findAllAccount();
}

IUserDao接口

package com.mybatisD.dao;


import com.mybatisD.domain.QueryVo;
import com.mybatisD.domain.User;
import org.apache.ibatis.annotations.Select;

import java.util.List;


public interface IUserDao {

   // 查询所有 *** 作
   // @Select("select * from user") 这是用注解方法
    //根据查询一个用户
    User findById(Integer userId);
  
}

IAccountDao.xml配置文件




    
    
        
        
        
        
        
    
    
        select * from user where id=#{userid}
    

SqlMapConfig.xml配置文件
其中最主要的是

 
    
        
        
        
    




    
    
    
    
    
        
        
        
    
    
    
        
        
            
            
            
                
                
                
                
                
            
        
    
    
    
    
    
    
        
        
    

配置日志信息log4j.properties

log4j.rootCategory=debug,CONSOLE, LOGFILE
log4j.logger.org.apache.axis.enterprise=FATAL, ConSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x -%mn
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x -%mn

配置jdbc.properties数据库

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/newsql?characterEncoding=utf-8
jdbc.username=root
jdbc.password=

测试类

package com.mybatisJ.test;

import com.mybatisD.dao.IAccountDao;
import com.mybatisD.dao.IUserDao;
import com.mybatisD.domain.Account;
import com.mybatisD.domain.AccountUser;
import com.mybatisD.domain.QueryVo;
import com.mybatisD.domain.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 org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


public class AccountTest {
    private InputStream in;
    private SqlSession sqlSession;
    private IAccountDao  accountDao;

    @Before//用于在测试方法执行之前执行
    public void init()throws  Exception{
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        sqlSession = factory.openSession();
        //4.使用SqlSession创建Dao接口的代理对象
        accountDao = sqlSession.getMapper(IAccountDao.class);
    }
    @After//用于在测试方法之后执行
    public void destory() throws Exception{
        //添加提交事物,不添加无法提交
        sqlSession.commit();
        sqlSession.close();
        in.close();
    }
    //查询连接方法其中包括用户的一些信息
    @Test
    public  void testFindAll() throws  Exception{

        List accounts = accountDao.findAll();
        for (Account account: accounts) {
            System.out.println("-----------------------");
            System.out.println(account);
           System.out.println(account.getUser());
        }
    }
    //查询account的信息
    @Test
    public void findAllAccount(){
        List accountUsers = accountDao.findAllAccount();
        for (AccountUser au: accountUsers) {
            System.out.println(au);
        }
    }
}

没有配置延迟加载时数据都是直接加载出来的其他信息

2.一对多的方式

Account与User实现类都不变,与上面的一致
改变的为IAccountDao接口

package com.mybatisD.dao;

import com.mybatisD.domain.Account;
import com.mybatisD.domain.AccountUser;

import java.util.List;

public interface IAccountDao {
    //查询所有账户
    List findAll();
    //查询账户,并且带有用户名称和地址信息
    List findAllAccount();
    //加入
    List findAccountByUid(Integer uid);
}

IAccountDao.xml的配置




    
    
        
        
        
        
        
    
    
       select * from account where uid=#{uid}
    

IUserDao.xml配置信息




    
    
            
            
            
            
            
        
        
        
    
    
    
        select * from user where id=#{userid}
    

测试类

package com.mybatisJ.test;

import com.mybatisD.dao.IAccountDao;
import com.mybatisD.dao.IUserDao;
import com.mybatisD.domain.Account;
import com.mybatisD.domain.AccountUser;
import com.mybatisD.domain.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 org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;
import java.util.List;


public class userTest {
    private InputStream in;
    private SqlSession sqlSession;
    private IUserDao userDao;

    @Before//用于在测试方法执行之前执行
    public void init()throws  Exception{
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        sqlSession = factory.openSession();
        //4.使用SqlSession创建Dao接口的代理对象
        userDao = sqlSession.getMapper(IUserDao.class);
    }
    @After//用于在测试方法之后执行
    public void destory() throws Exception{
        //添加提交事物,不添加无法提交
        sqlSession.commit();
        sqlSession.close();
        in.close();
    }
    //查询连接方法其中包括用户的一些信息
    @Test
    public  void testFindAll() throws  Exception{
        List users = userDao.findAll();
        for (User user: users) {
            System.out.println(user);
            System.out.println(user.getAccount());
        }
        }

}

结果,延迟加载就是在用到这个信息才会加载

2.mybatis中的缓存 1.缓存的概念

什么是缓存:存在于内存中的临时数据
为什么使用缓存:减少和数据库的交互次数,提高执行效率
什么样的数据能使用缓存:经常查询并且不经常改变的、数据的正确与否对最终的结果影响不大
不能使用缓存:经常改变的数据,数据的正确与否对最终的结果影响很大如:商品的库存,银行的汇率

2.Mybatis中的一级缓存和二级缓存

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

一级缓存

它指的是Mybatis中SqlSession对象的缓存,当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供一块区域中,该区域的结构是一个Map,当我们再次查询同样的数据,Mybatis会先去SqlSession中查询是否有,有的话直接用,当SqlSession对象消失后,Mybatis的 一级缓存也就消失了

代码:
配置IUserDao.xml

在这里插入代码片`


    
    
    
       select * from user