gpt4 book ai didi

java - 在 Java 中使用 MyBatis 3 进行延迟加载

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:41:48 26 4
gpt4 key购买 nike

我正在使用 Mybatis(3.2.7 版本)作为我的 JAVA 项目的 ORM 框架。因为我有 JPA 背景,所以我很想探索 Mybatis 支持的 LAZYLOADING。但我无法理解任何实质性内容。
(我正在使用 JAVA API 和注释配置 MYBATIS,仅用于查询目的)

根据 Mybatis 文档:<我>1。 lazyLoadingEnabled:默认值=TRUE

全局启用或禁用延迟加载。启用后,所有关系都将是惰性的加载。可以使用 fetchType 属性为特定关系取代此值在上面。

2。 aggressiveLazyLoading :默认值=TRUE

启用后,具有延迟加载属性的对象将在调用任何延迟属性时完全加载。否则,每个属性都按需加载。

使用以下属性,我尝试了以下代码:

一个。 JAVA 类:

反馈.java

public class Feedback implements Serializable {
private static final long serialVersionUID = 1L;

private int id;
private String message;

/**
* while loading Feedback, I want sender object to be lazily loaded
*/
private User sender;
private boolean seen;

// getters and setters
}

用户.java

public class User implements Serializable, {
private static final long serialVersionUID = 1L;
private int id;
private String email;

// getters and setters
}

数据库架构:

反馈表

                Table "public.feedback"

Column | Type | Modifiers
-------------+-----------+-------------------------------------------------------
id | integer | PRIMARY KEY
seen | boolean | not null
sender_id | integer | FOREIGN KEY (sender_id) REFERENCES users(id)
message | text |

用户表:

                Table "public.users"

Column | Type | Modifiers
-------------+----------+----------------------------------------------------
id | integer | PRIMARY KEY
email | text |

通过 JAVA API 配置 MyBatis:

DataSource dataSource = new PGSimpleDataSource();
((PGSimpleDataSource) dataSource).setServerName("localhost");
((PGSimpleDataSource) dataSource).setDatabaseName(dbName);
((PGSimpleDataSource) dataSource).setPortNumber(5432);
((PGSimpleDataSource) dataSource).setUser(new UnixSystem().getUsername());
((PGSimpleDataSource) dataSource).setPassword("");

TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment(dbName, transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMapper(FeedbackMapper.class);

//
configuration.setAggressiveLazyLoading(false);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);

在 Feedbackmapper 中查询数据库和数据库查询:

d.1 Feedbackmapper 中的代码:

@Select("SELECT f.id, f.message, f.seen, f.sender_id FROM feedback f WHERE f.id= #{feedbackId}")
@Results(value = {
@Result(property = "id", column = "id"),
@Result(property = "sender", column = "sender_id", javaType = User.class, one = @One(select = "getUser", fetchType=FetchType.DEFAULT))
})
public Feedback getFeedback(@Param("feedbackId") int feedbackId);

@Select("SELECT id, email FROM users WHERE id=#{id}")
public User getUser(int id);

d.2:在feedbackMapper中调用查询的代码

    // setup Mybatis session factory and config
Feedback feedback =feedbackMapper.getFeedback(70000);
System.out.println(feedback);

但是在查询 getFeedback(id) 时仍然会填充“发件人”对象。我希望发件人对象不应该立即填充,但只有在我对获取的反馈对象调用 getSender() 时才填充。请帮忙

我最近的观察:

Mybatis 团队确实在他们的文档中弄错了,即在文档中:

  1. lazyLoadingEnabled:默认值=TRUE

  2. aggressiveLazyLoading : 默认值=TRUE

    但是看看他们的源代码:

     protected boolean lazyLoadingEnabled = false;
    protected boolean aggressiveLazyLoading = true;

    **然而,被更正后,结果不受影响,延迟加载不起作用:( **

最佳答案

我想我找到了一种启用延迟加载的方法(虽然不确定百分比):

  • MyBatis 文档在配置中有如下设置:

设置:lazyLoadTriggerMethods

描述:指定哪个对象的方法触发延迟加载

有效值:以逗号分隔的方法名称列表

默认值:equals,clone,hashCode,toString

  • 根据源代码,这个东西正确映射到文档中给出的内容:

    public class Configuration {
    // other attributes + methods
    protected Set<String> lazyLoadTriggerMethods = new HashSet<String>(Arrays.asList(new
    String[] { "equals", "clone", "hashCode", "toString" }));
    }
    • Mybatis 配置如下:

      TransactionFactory transactionFactory = new JdbcTransactionFactory();
      Environment environment = new Environment(dbName, transactionFactory, dataSource);
      Configuration configuration = new Configuration(environment);

      /**
      *This is the cause why LAZY LOADING is working now
      */
      configuration.getLazyLoadTriggerMethods().clear();

      ///////////////////////////////////////////////////
      configuration.setLazyLoadingEnabled(true);
      configuration.setAggressiveLazyLoading(false);
    • Mapper 中的查询(大部分不变):

      @Select("SELECT id, message, seen, sender_id 
      FROM feedback WHERE f.id= #{feedbackId}")
      @Results(value = {
      @Result(property = "id", column = "id"),
      @Result(property = "sender", column = "sender_id", javaType = User.class, one = @One(select = "getUser"))

      // Set fetchType as DEFAULT or LAZY or don't set at all-- lazy loading takes place
      // Set fetchType as EAGER --sender Object is loaded immediately

      })
      public Feedback getFeedback(@Param("feedbackId") int feedbackId);

      @Select("SELECT id, email FROM users WHERE id=#{id}")
      public User getUser(int id);

-调用mapper的JAVA代码

        FeedbackMapper mapper = sqlSession.getMapper(FeedbackMapper.class);
Feedback feedback =mapper.getFeedback(69999);
System.out.println("1. Feedback object before sender lazily load: \n"+ feedback);
System.out.println("2. Sender loaded explicitly \n" +feedback.getSender());
System.out.println("3. Feedback object after sender loading \n" + feedback);
  • 代码的输出

<我> 1. sender懒加载前的反馈对象:

{id : 69999,  message : message123, sender : null, seen : false}

2. Sender loaded explicitly

{id : 65538 , email: hemant@gmail.com}

3. Feedback object after sender loading:

{id : 69999, message : message123, sender : {id : 65538, email : hemant@gmail.com},
seen : false}

  • 虽然这工作令人满意,但在做

configuration.getLazyLoadTriggerMethods().clear();

但是由于 Mybatis 中缺少文档,我不确定这是否与任何缺点相关。

关于java - 在 Java 中使用 MyBatis 3 进行延迟加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24013855/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com