mybatis第四天

一、Mybatis中的延迟加载java

问题:在一对多中,当咱们有一个用户,它有100个帐户。
      在查询用户的时候,要不要把关联的帐户查出来?
      在查询帐户的时候,要不要把关联的用户查出来?
    
      在查询用户时,用户下的帐户信息应该是,何时使用,何时查询的。
      在查询帐户时,帐户的所属用户信息应该是随着帐户查询时一块儿查询出来。

什么是延迟加载
    在真正使用数据时才发起查询,不用的时候不查询。按需加载(懒加载)
什么是当即加载
    无论用不用,只要一调用方法,立刻发起查询。

在对应的四种表关系中:一对多,多对一,一对一,多对多
    一对多,多对多:一般状况下咱们都是采用延迟加载。
    多对一,一对一:一般状况下咱们都是采用当即加载。

二、Mybatis中的缓存sql

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

三、Mybatis中的注解开发数据库

环境搭建
单表CRUD操做(代理Dao方式)
多表查询操做
缓存的配置

1延迟加载的概念

为何要延迟加载

延迟加载:缓存

就是在须要用到数据时才进行加载,不须要用到数据时就不加载数据。延迟加载也称懒加载.session

好处:先从单表查询,须要时再从关联表去关联查询,大大提升数据库性能,由于查询单表要比关联查询多张表速mybatis

度要快。app

坏处:框架

由于只有当须要用到数据时,才会进行数据库查询,这样在大批量数据查询时,由于查询工做也要消耗ide

时间,因此可能形成用户等待时间变长,形成用户体验降低。性能

实现需求

需求:

查询帐户(Account)信息而且关联查询用户(User)信息。若是先查询帐户(Account)信息便可知足要

求,当咱们须要查询用户(User)信息时再查询用户(User)信息。把对用户(User)信息的按需去查询就是延迟加

载。

mybatis第三天实现多表操做时,咱们使用了resultMap来实现一对一,一对多,多对多关系的操做。主要

是经过 association、collection 实现一对一及一对多映射。association、collection 具有延迟加载功

能。

经过assocation实现延迟加载

1.3.1 帐户的持久层 DAO 接口

public interface IAccountDao {

/**

* 查询全部帐户,同时获取帐户的所属用户名称以及它的地址信息

* @return

*/

List<Account> findAll();

}

1.3.2 帐户的持久层映射文件

<?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">

<!-- 创建对应关系 -->

<resultMap type="account" id="accountMap">

<id column="id" property="id"/>

<result column="uid" property="uid"/>

<result column="money" property="money"/>

<!-- 它是用于指定从表方的引用实体属性的 -->

<association property="user" javaType="user"

select="com.itheima.dao.IUserDao.findById"

column="uid">

</association>

</resultMap>

<select id="findAll" resultMap="accountMap">

select * from account

</select>

</mapper>

select: 填写咱们要调用的 select 映射的 id

column : 填写咱们要传递给 select 映射的参数

1.3.3 用户的持久层接口和映射文件

* <p>Title: IUserDao</p>

* <p>Description: 用户的业务层接口</p>

* <p>Company: http://www.itheima.com/ </p>

*/

public interface IUserDao {

/**

* 根据 id 查询

* @param userId

* @return

*/

User findById(Integer userId);

}

<?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">

<!-- 根据 id 查询 -->

<select id="findById" resultType="user" parameterType="int" >

select * from user where id = #{uid}

</select>

</mapper>

1.3.4 开启 Mybatis 的延迟加载策略

image.png

1.3.5 编写测试只查帐户信息不查用户信息

/**

*

* <p>Title: MybastisCRUDTest</p>

* <p>Description: 一对多帐户的操做</p>

* <p>Company: http://www.itheima.com/ </p>

*/

public class AccountTest {

private InputStream in ;

private SqlSessionFactory factory;

private SqlSession session;

private IAccountDao accountDao;

@Test

public void testFindAll() {

//6.执行操做

List<Account> accounts = accountDao.findAll();

}

@Before//在测试方法执行以前执行

public void init()throws Exception {

//1.读取配置文件

in = Resources.getResourceAsStream("SqlMapConfig.xml");

//2.建立构建者对象

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

//3.建立 SqlSession 工厂对象

factory = builder.build(in);

//4.建立 SqlSession 对象

session = factory.openSession();

//5.建立 Dao 的代理对象

accountDao = session.getMapper(IAccountDao.class);

}

@After//在测试方法执行完成以后执行

public void destroy() throws Exception{

//7.释放资源

session.close();
in.close();

}

}

测试结果以下:

咱们发现,由于本次只是将 Account对象查询出来放入 List 集合中,并无涉及到 User对象,因此就没有
image.png
image.png
发出 SQL 语句查询帐户所关联的 User 对象的查询。

经过collection实现延迟加载

一样咱们也能够在一对多关系配置的<collection>结点中配置延迟加载策略。

<collection>结点中也有 select 属性,column 属性。

需求:

完成加载用户对象时,查询该用户所拥有的帐户信息。

1.4.1 在 User 实体类中加入 List<Account>属性

/**

*

* <p>Title: User</p>

* <p>Description: 用户的实体类</p>

* <p>Company: http://www.itheima.com/ </p>

*/

public class User implements Serializable {

private Integer id;

private String username;

private Date birthday;

private String sex;

private String address;

private List<Account> accounts;

public List<Account> getAccounts() {

return accounts;

}

public void setAccounts(List<Account> accounts) {

this.accounts = 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 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 + "]";

}

}

1.4.2 编写用户和帐户持久层接口的方法

/**

* 查询全部用户,同时获取出每一个用户下的全部帐户信息传智播客——专一于 Java、.Net 和 Php、网页平面设计工程师的培训

北京市昌平区建材城西路金燕龙办公楼一层 电话:400-618-9090

* @return

*/

List<User> findAll();

/**

* 根据用户 id 查询帐户信息

* @param uid

* @return

*/

List<Account> findByUid(Integer uid);

1.4.3 编写用户持久层映射配置

<resultMap type="user" id="userMap">

<id column="id" property="id"></id>

<result column="username" property="username"/>

<result column="address" property="address"/>

<result column="sex" property="sex"/>

<result column="birthday" property="birthday"/>

<!-- collection 是用于创建一对多中集合属性的对应关系

ofType 用于指定集合元素的数据类型

select 是用于指定查询帐户的惟一标识(帐户的 dao 全限定类名加上方法名称)

column 是用于指定使用哪一个字段的值做为条件查询

-->

<collection property="accounts" ofType="account"

select="com.itheima.dao.IAccountDao.findByUid"

column="id">

</collection>

</resultMap>

<!-- 配置查询全部操做 -->

<select id="findAll" resultMap="userMap">

select * from user

</select>

<collection>标签:

主要用于加载关联的集合对象

select 属性:

用于指定查询 account 列表的 sql 语句,因此填写的是该 sql 映射的 id

column 属性:

用于指定 select 属性的 sql 语句的参数来源,上面的参数来自于 user 的 id 列,因此就写成 id 这一

个字段名了

相关文章
相关标签/搜索