Mybatis源码分析--关联表查询及延迟加载(一)

阅读更多

Mybatis提供了关联查询映射的功能。

一、一对一关联


实体类如下:

Users表对应的实体类:

public class User {
	
	private int id;
	private String names;
	private int age;
	private Teacher teacher;
	
	......getXxx和setXxx方法

}
Teacher表对应的实体类:

public class Teacher {

	private int id;
	private String name;
	
	.....getXxx和setXxx方法
	
}


Mapper文件中的配置如下:

 
   
     
     
         
     	
     	
     	
     	 
             
             
         
     
     
 

Main函数如下:

public class LazyUser {
	
	public static void main(String [] args){
			
		   //mybatis的配置文件
		    String resource = "learn/mybatis-config.xml";
		    InputStream is = LazyUser.class.getClassLoader().getResourceAsStream(resource);
		    //构建sqlSession的工厂
		    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
		    SqlSession session = sessionFactory.openSession();
		    String statement = "com.tianjunwei.lazy.entity.Users.getUser";//映射sql的标识字符串
		    //执行查询返回一个唯一user对象的sql
		    User user = session.selectOne(statement, 1);
		    session.commit(true);
		    System.out.println(user.getNames());
		    Teacher teacher = user.getTeacher();
		    System.err.println(teacher.getName());
		    
		}
}
这样就可以通过查询获得一对一的User和Teacher的关联数据。

虽然上面的示例帮助我们查询到了User和Teacher的关联数据,但有时候可能我们并不需要关联数据,并且我们是使用一条sql语句通过两个表的联合查询来获得数据的。Mybatis给我们提供了延迟加载的机制,就是当我们不需要Teacher的数据时,并不会给我们查询,当需要Teacher数据时再进行查询,这样有一点不好的地方就是不是一次查询数据,需要多次连接数据库来获取数据。

1、首选需要在Mybatis的配置文件中添加如下配置:

  
  
  
 
2、修改Mapping文件中的内容:

其实就是执行两次sql语句分别获取Users和Teacher中的值


   
     
     
     
     
         
     	
     	
     
     
         
     	
     	
     	
     	 
             
             
         
     
     
 
Main函数中的方法还是和原来的一样

public class LazyMain {
	public static void main(String [] args){
			
			//mybatis的配置文件
		    String resource = "learn/mybatis-config.xml";
		    InputStream is = LazyMain.class.getClassLoader().getResourceAsStream(resource);
		    //构建sqlSession的工厂
		    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
		    SqlSession session = sessionFactory.openSession();
		    String statement = "com.tianjunwei.lazy.entity.User.getById";//映射sql的标识字符串
		    //执行查询返回一个唯一user对象的sql
		    User user = session.selectOne(statement, 1);
		    session.commit(true);
		    System.out.println(user.getNames());
		    Teacher teacher = user.getTeacher();
		    System.err.println(teacher.getName());
		    
		}
}

执行过程:从下图你可以看到是执行了两次Sql语句。



当把下面代码注释掉之后,就是我们不需要teacher的数据时

//Teacher teacher = user.getTeacher();
//System.err.println(teacher.getName());
执行结果如下图,就不会执行teacher相关的sql语句,这样就实现了延迟加载的功能。



以上介绍的是一对一的情况,Mapping文件中使用的是association标签


二、一对多关联


我们介绍一下一对多情况

Teacher的实体定义如下:

public class Teacher {

	private int id;
	private String name;
	
	private List users;
	
	.....getXxx和setXxx方法....
	
}
Mapper文件中的定义如下,一对多使用的标签是collection,这里我们还是使用延迟加载方式,实现原理就是执行两次SQL,按需执行SQL语句。

   
     
     
     
     
         
     	
     	
     	 //使用collection标签
     	 
     
     
         
     	
     	
     	
     
     
 
Main函数如下:

public class LazyMainTeacher {
	public static void main(String [] args){
			
			//mybatis的配置文件
		    String resource = "learn/mybatis-config.xml";
		    InputStream is = LazyMainTeacher.class.getClassLoader().getResourceAsStream(resource);
		    //构建sqlSession的工厂
		    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
		    SqlSession session = sessionFactory.openSession();
		    String statement = "com.tianjunwei.lazy.entity.Teacher.getTeacher";//映射sql的标识字符串
		    //执行查询返回一个唯一user对象的sql
		    Teacher teacher =  (Teacher) session.selectList(statement, 1).get(0);
		    session.commit(true);
		    System.out.println(teacher.getName());
		    List users = teacher.getUsers();
		    System.err.println(users.get(3).getAge());
		    
		}
}

运行结果:可以看到确实是执行两次SQL语句





你可能感兴趣的:(Mybatis源码分析--关联表查询及延迟加载(一))