Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用MyBatis 3和Java进行延迟加载_Java_Sql_Mybatis - Fatal编程技术网

使用MyBatis 3和Java进行延迟加载

使用MyBatis 3和Java进行延迟加载,java,sql,mybatis,Java,Sql,Mybatis,我正在使用Mybatis(3.2.7版本)作为JAVA项目的ORM框架。 由于我有JPA的背景,我热衷于探索Mybatis支持的懒散加载。 但我无法理解任何实质性的东西。 (我正在使用JAVA API和注释配置MYBATIS,仅用于查询目的) 根据Mybatis文件: 1.lazyLoadingEnabled:默认值=真 全局启用或禁用延迟加载。启用时,所有关系都将被延迟处理 加载。对于特定关系,可以使用fetchType属性替换此值 在上面。 二,。侵略性延迟加载:默认值=真 启用时,具有延迟

我正在使用Mybatis(3.2.7版本)作为JAVA项目的ORM框架。 由于我有JPA的背景,我热衷于探索Mybatis支持的懒散加载。 但我无法理解任何实质性的东西。
(我正在使用JAVA API和注释配置MYBATIS,仅用于查询目的)

根据Mybatis文件: 1.lazyLoadingEnabled:默认值=真

全局启用或禁用延迟加载。启用时,所有关系都将被延迟处理 加载。对于特定关系,可以使用fetchType属性替换此值 在上面。

二,。侵略性延迟加载:默认值=真

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

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

a。JAVA类:

Feedback.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
}
User.java

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

// getters and setters
}
b。数据库模式:

反馈表

                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     | 
c。通过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);
d。在反馈映射器中查询数据库和数据库查询:

@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、 反馈映射器中的1个代码:

@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)时填充“sender”对象。我希望不应立即填充sender对象,而应仅在对获取的反馈对象调用getSender()时填充。请帮忙

我最近的观察:

Mybatis团队在其文档中确实犯了错误,即在文档中:

  • lazyLoadingEnabled:默认值=真

  • 侵略性延迟加载:默认值=真

    但看看他们的源代码:

     protected boolean lazyLoadingEnabled = false;
     protected boolean aggressiveLazyLoading = true;
    
    **但是,经过纠正后,结果不会受到影响,并且延迟加载不起作用:(**


  • 更新

    我查看了源代码,问题是配置类没有反映文档

    在配置类中,默认情况下禁用延迟加载。这在提交中已更改,但未更新文档以反映更改

    protected boolean lazyLoadingEnabled = false;
    
    我填写了一份错误报告

    现在,添加configuration.setLazyLoadingEnabled(true)以启用延迟加载


    旧答案:

    文档不正确。如果aggressiveLazyLoading为true,则在对对象进行任何方法调用后都会加载所有惰性属性。 因此,调用feedback.toString()将获取反馈的sender属性


    您应该将aggressiveLazyLoading设置为false以实现您想要的功能。

    我想我找到了一种方法来启用lazyloading(尽管不确定):

    • MyBatis文档在配置中具有以下设置:
    设置:lazyLoadTriggerMethods

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

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

    默认值:等于、克隆、哈希代码、toString

    • 根据源代码,这件事正确地映射到文档中给出的内容:

    • Mapper中的查询(大部分未更改):

    -调用映射器的JAVA代码

    • 代码的输出
    1.发送方延迟加载前的反馈对象:

    {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中缺乏文档,我不确定这是否与任何缺陷有关。

    我认为使用
    打印来验证mybatis中的延迟加载并不容易。
    我们可以使用
    configuration.getLazyLoadTriggerMethods().clear();
    删除默认的triggerMethods作为前面的答案。但是当我们打印它,或者使用
    toString
    时,它仍然会调用
    getXXX
    。因此它仍然会触发延迟加载以选择更多。因此我们无法调试或打印以查看延迟加载的过程

    我找到了一种方法来验证这个函数

  • 将日志级别设置为调试
  • 编写以下代码并查看控制台

  • //configuration.setAggressiveLazyLoading(false);sqlSessionFactory=new SqlSessionFactoryBuilder().build(配置);SIR在我的配置设置中已经完成了:(我错误地认为您使用了积极的延迟加载。默认的FetchType可能不正确,并且不反映实际配置。将FetchType设置为lazy应该是目前的一种解决方法。最初是FetchType.lazy,但没有用:(我更新了答案,因为默认情况下禁用了延迟加载。请尝试通过调用configuration.setLazyLoadingEnabled(true)来启用它)。文档将很快更新。是的,你是对的。Mybatis团队在文档中确实犯了错误,即文档:
    1.lazyLoadingEnabled:default value=TRUE
    2.aggressiveLazyLoading:default value=TRUE
    但查看他们的源代码:
    受保护的布尔值lazyLoadingEnabled=false;
    protected boolean aggressiveLazyLoading=true;
    **但是,经过更正后,结果不会受到影响,并且延迟加载不起作用:(**
    @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);
    
            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);
    
    {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}
    
            log.info("user :{}", userLazyDepartment);
            log.info("user :{}", userLazyDepartment.getDepartment());