MyBatis注解开发

延迟加载(按需加载、懒加载)在真正使用数据时才发起查询,不用的时候不查询


MyBatis一级缓存:

指的是MyBatis中SqlSession对象的缓存,当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供一块区域中。

该区域的结构是一个Map。当我们再次查询同样的数据,mybatis会先去sqlsession中查询是否有,有的话直接拿出来用。
当SqlSession对象消失时,mybatis的一级缓存也就消失了

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

 

MyBatis二级缓存

MyBatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存
二级缓存使用步骤:

1.让MyBatis框架支持二级缓存(在sqlmapconfig.xml中配置)

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

2.让当前的映射文件支持二级缓存(在UserDao.xml中配置)

<cache/>

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

useCache="true"

二级缓存中存放的内容是数据,而不是对象

另外一种是使用注解,在Dao类上面

@CacheNamespace(blocking = true)

 

实体类

import java.io.Serializable;

public class Account implements Serializable {

    private Integer id;
    private Integer uid;
    private Double money;

    private 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;
    }

    public User getUser() {
        return user;
    }

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

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", uid=" + uid +
                ", money=" + money +
                '}';
    }
}
import java.io.Serializable;
import java.util.Date;
import java.util.List;

public class User implements Serializable {
    private Integer id;
    private String username;
    private String address;
    private String sex;
    private Date birthday;

    private List<Account> accounts;

    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 String getAddress() {
        return address;
    }

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

    public String getSex() {
        return sex;
    }

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

    public Date getBirthday() {
        return birthday;
    }

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

    public List<Account> getAccounts() {
        return accounts;
    }

    public void setAccounts(List<Account> accounts) {
        this.accounts = accounts;
    }

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

 

Dao层

import com.jinke.domain.Account;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;

import java.util.List;

public interface AccountDao {

    @Select("select * from account")
    @Results(id = "accountMap", value = {
            @Result(id = true, property = "id", column = "id"),
            @Result(property = "uid", column = "uid"),
            @Result(property = "money", column = "money"),
            @Result(property = "user", column = "uid", one = @One(select = "com.jinke.dao.UserDao.findById", fetchType = FetchType.LAZY))
    })
    List<Account> findAll();

    @Select("select * from account where uid = #{uid}")
    List<Account> findAccountByUid(Integer uid);
}
import com.jinke.domain.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;

import java.util.List;

/*开启二级缓存*/
@CacheNamespace(blocking = true)
public interface UserDao {
    @Select("select * from user")
    @Results(id = "userMap", value = {@Result(id = true, property = "id", column = "id"),
            @Result(property = "username", column = "username"),
            @Result(property = "sex", column = "sex"),
            @Result(property = "address", column = "address"),
            @Result(property = "birthday", column = "birthday"),
            @Result(property = "accounts", column = "id",
                    many = @Many(select = "com.jinke.dao.AccountDao.findAccountByUid", fetchType = FetchType.EAGER))}
    )
    List<User> findAll();

    @Select("select * from user where id = #{id}")
    @ResultMap(value = "userMap")
    User findById(Integer id);

}

 

注解开发就不需要xml配置映射关系了

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 2.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="jdbcConfig.properties"/>
    <settings>
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="true"/>
        <!--配置开启二级缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>

    <typeAliases>
        <!--用于配置别名的包,该包下实体类都会注册别名,即类名,且不区分大小写-->
        <package name="com.jinke.domain"/>
    </typeAliases>
    <!--配置环境-->
    <environments default="mysql">
        <!--配置mysql的环境-->
        <environment id="mysql">
            <!--配置事务-->
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--配置映射文件的位置-->
    <mappers>
        <package name="com.jinke.dao"/>
    </mappers>
</configuration>

 

测试类

import com.jinke.dao.AccountDao;
import com.jinke.dao.RoleDao;
import com.jinke.dao.UserDao;
import com.jinke.domain.Account;
import com.jinke.domain.Role;
import com.jinke.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 MyBatisTest {

    private InputStream in;
    private SqlSession sqlSession;
    private UserDao userDao;
    private AccountDao accountDao;
    private RoleDao roleDao;
    private SqlSessionFactory factory;

    @Before
    public void init() throws Exception {
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        factory = builder.build(in);
        sqlSession = factory.openSession();
        userDao = sqlSession.getMapper(UserDao.class);
        accountDao = sqlSession.getMapper(AccountDao.class);
        roleDao = sqlSession.getMapper(RoleDao.class);
    }

    @After
    public void destroy() throws Exception {
        sqlSession.commit();
        sqlSession.close();
        in.close();
    }

    @Test
    public void testFindAccount() {
        List<Account> accounts = accountDao.findAll();
        for (Account account : accounts) {
            System.out.println(account + " " + account.getUser());
        }
    }

    @Test
    public void testFindUser() {
        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println(user + " " + user.getAccounts());
        }
    }

    @Test
    public void testFindRole() {
        List<Role> roles = roleDao.findAll();
        for (Role role : roles) {
            System.out.println(role + " " + role.getUsers());
        }
    }

    @Test
    public void testFirstLevelCache() {
        User user = userDao.findById(1);
        System.out.println(user);
        //清除一级缓存
        sqlSession.clearCache();
        User user2 = userDao.findById(1);
        System.out.println(user2);
        System.out.println("user==user2?" + (user == user2));
    }

    @Test
    public void testClearCache() {
        //测试二级缓存
        SqlSession session1 = factory.openSession();
        UserDao userDao1 = session1.getMapper(UserDao.class);
        User user1 = userDao1.findById(1);
        System.out.println(user1);
        session1.close();


        SqlSession session2 = factory.openSession();
        UserDao userDao2 = session2.getMapper(UserDao.class);
        User user2 = userDao2.findById(1);
        System.out.println(user2);
        session1.close();

        System.out.println("user==user2?" + (user1 == user2));

    }
}

总的来说,简单的查询可以用注解,方便快速,但是太复杂的sql还是用xml

欢迎关注我的微信公众号:安卓圈

posted @ 2019-07-04 16:15  嘉禾世兴  阅读(296)  评论(0编辑  收藏  举报