您当前的位置: 首页 >  mybatis

Charge8

暂无认证

  • 3浏览

    0关注

    447博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

MyBatis select查询(resultType/resultMap)和延迟加载

Charge8 发布时间:2018-11-16 23:06:31 ,浏览量:3

MyBatis select标签, 常用元素有:id、parameterType、resultType、resultMap等

    id:配合Mapper的全限定名,联合成为一个唯一的标识,用户标识这条SQL。

    parameterType:表示这条SQL接受的参数类型,可以是MyBatis系统定义或者自定义的别名

    resultType:表示这条SQL返回的结果类型,与parameterType一样,可以是系统定义的别名,也可以是类的全限定名。

    resultMap:它是映射器的引用,将执行强大的映射功能。resultMap也提供了自定义映射的POJO类型。 

我们可以使用resultType和resultMap中的一个,但不能同时使用。

id在命名空间中唯一的标识符,可以被用来引用这条语句。parameterType将会传入这条语句的参数类的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset。resultType从这条语句中返回的期望类型的类的完全限定名或别名。注意如果是集合情形,那应该是集合可以包含的类型,而不能是集合本身。使用 resultType 或 resultMap,但不能同时使用。resultMap外部 resultMap 的命名引用。结果集的映射是 MyBatis 最强大的特性,对其有一个很好的理解的话,许多复杂映射的情形都能迎刃而解。使用 resultMap 或 resultType,但不能同时使用。

 

一、resultType元素

   resultType属性:要求结果集的列名和属性名必须要匹配, 若不匹配时,可以使用SQL语句的AS别名(不推荐) 或者 设置开启自动驼峰命名规则映射 或者使用 resultMap属性。

1、查询一条记录, 返回 POJO类 或者返回MyBatis封装好的 Map集合(key是列名称,value是列对应的值)

     POJO类

	public User getUser(Integer id);

	
	
		select * from t_user where id = #{id}
	
                        User user = userMapper.getUser(1);
			System.out.println(user);
----
User [id=1, username=admin, pazzword=172eee54aa664e9dd0536b063796e54e, state=1, regDate=Sun Oct 14 00:00:00 CST 2018]

     Map集合(key是列名称,value是列对应的值)

	public Map selectUserMap(int id);

	
		select * from t_user where id = #{id} 
	
                        Map userMap = userMapper.selectUserMap(1);
			System.out.println(userMap);
----
{reg_date=2018-10-14 00:00:00.0, pazzword=172eee54aa664e9dd0536b063796e54e, id=1, state=1, username=admin}

2、查询所有结果,返回 List集合 和 Map集合

    List集合

	public List selectUserAll();

	
	
		select * from t_user
	
			List userlist = userMapper.selectUserAll();
			System.out.println(Arrays.asList(userlist));
----
[[User [id=1, username=admin, pazzword=172eee54aa664e9dd0536b063796e54e, state=1, regDate=Sun Oct 14 00:00:00 CST 2018], User [id=2, username=user, pazzword=3be7f713d9321e812231bb838448385d, state=1, regDate=Mon Oct 15 00:00:00 CST 2018]]

    Map集合

    Map,Map中的key是User的id,Map的值是User对象,实现它的关键是我们要在接口的方法上加一个注解,告诉Mybatis用哪个字段做Map的key.

	@MapKey("id")
	public Map selectUserMap();

	
		select * from t_user
	
			Map userMap = userMapper.selectUserMap();
			System.out.println(Arrays.asList(userMap));
----
[{1={reg_date=2018-10-14 00:00:00.0, pazzword=172eee54aa664e9dd0536b063796e54e, id=1, state=1, username=admin}, 2={reg_date=2018-10-15 00:00:00.0, pazzword=3be7f713d9321e812231bb838448385d, id=2, state=1, username=user}]

 

二、resultMap元素

使用场景很广泛:

  • 字段有自定义的转化规则
  • 复杂的多表查询

1、使用resultMap自定义数据库字段名称和JavaBean的属性名称的对应关系

	public User getUser(Integer id);

	
		select * from t_user where id = #{id} 
	
	
	
		
		
		
		
		
		
		
	

			User user = userMapper.getUser(1);
			System.out.println(user);
----
User [id=1, username=admin, pazzword=172eee54aa664e9dd0536b063796e54e, state=1, regDate=Sun Oct 14 00:00:00 CST 2018]

2、使用resultMap实现关联查询 ( 类(引用)类型成员属性 )使用 association 标签

    假设  一个用户对应一个角色,

    1)使用 association标签实现关联查询, 两个表的重复字段通过别名识别

          association 标签 :类(引用)类型成员属性映射                  property - 对应属性名                 javaType - 类的具体类型

   

	public User getUser(Integer id);

        
		select 
			t.id,
			t.username, 
			t.pazzword,
			t.state,
			t.reg_date regDate,
			r.id rid,
			r.roleName,
			r.state rstate
		from t_user t, t_role r 
		where t.role_id = r.id and t.id = #{id} 
	
        
		
		
		
		
		
		
		
		
		
			
			
			
			
		
	

			User user = userMapper.getUser(1);
			System.out.println(user);
----
User [id=1, username=admin, pazzword=172eee54aa664e9dd0536b063796e54e, state=1, regDate=Sun Oct 14 00:00:00 CST 2018, role=Role [id=1, roleName=超级管理员, state=0]]

     

2)使用 association标签分步实现关联查询(传递一个参数)

     分步查询通常应用于关联表查询,将查询sql拆分,分步查询与关联表查询的不同:

      从代码层面来说:关联表查询能够有效的简化代码编写逻辑,减小代码编写难度,同时避免BUG(代码多了,bug就多了);

      而分步查询则能够增强代码的可用性

      从功能上说:关联表查询毕竟只需要查询一次数据库,对于业务量较小的系统来说,效率更高,数据库压 力相对较小;

      分步查询虽然需要多次查询数据,但是这也意味着能够更好地使用数据缓存服务,且缓存的   数据耦合度低,利用率高,而且单次查询效率很高,数据库压力较小(对于业务量较大的系统来说)。还有一点则是数据库锁的问题,毕竟关联查询是多表同时使用,分步查询每次只操作一个表。 

role

public Role getRole(Integer id);


	
		select * from t_role where id = #{id}
	

user

  select::表明当前属性是调用select指定方法查出的结果 是XXXMapper.xml中namespace。方法名   column:指定将哪一列的值传给这个方法

        public User getUser(Integer id);

	
		select * from t_user where id = #{id}
	
	
		
		
		
		
		
		
		
		
		
		
	

			User user = userMapper.getUser(1);
			System.out.println(user);
----
User [id=1, username=admin, pazzword=172eee54aa664e9dd0536b063796e54e, state=1, regDate=Sun Oct 14 00:00:00 CST 2018, role=Role [id=1, roleName=超级管理员, state=0]]

3、使用resultMap实现关联查询 ( 集合 List/Set 类型成员属性 )使用 collection 标签

     假设  一个角色对应多个用户,

     1)使用 collection 标签实现关联查询, 两个表的重复字段通过别名识别

         collection 标签 :集合类型成员属性映射                 property - 对应属性名                ofType - 设置集合中存放的数据的类型

  

	public Role getRoleOfUser(Integer id);

	
		select
			r.id,
			r.rolename,
			r.state,
			t.id tid,
			t.username,
			t.pazzword,
			t.state tstate,
			t.reg_date regDate 
		from t_role r, t_user t 
		where r.id=t.role_id and r.id = #{id}
	
	
		
		
		
		
		
			
			
			
			
			
		
	

			Role role = roleMapper.getRoleOfUser(1);
			System.out.println(role);
----
Role [id=1, roleName=超级管理员, state=0, users=[User [id=1, username=admin, pazzword=172eee54aa664e9dd0536b063796e54e, state=1, regDate=Sun Oct 14 00:00:00 CST 2018], User [id=2, username=user, pazzword=3be7f713d9321e812231bb838448385d, state=1, regDate=Mon Oct 15 00:00:00 CST 2018]]]

   

    2)使用 collection 标签分步实现关联查询(传递一个参数)

     user

	public List selectUserByRoleid(Integer roleId);

	
		select * from t_user where role_id = #{roleId}
	

     role

         select - 对应属性名的实现接口.id名(即方法名)           column - 传过去的数据库表的字段别名(无别名用列名)

	public Role getRoleOfUser(Integer id);

	
		select * from t_role where id = #{id}
	
	
		
		
		
		
		
		
	

在开发中

    针对属性是单对象类型时,使用 association元素,通常直接使用多表查询操作,即内联查询

    针对属性是集合对象类型时,使用 collection元素,通常使用延迟加载,即额外SQL查询

三、延迟加载(也称懒加载)

     Hibernate中,涉及到关联查询的时候,懒加载是默认就开启着的

     延迟加载就是当在真正需要使用到数据时,才会发送SQL语句进行查询该数据。

     MyBatis 默认关闭延迟加载,需要我们在全局配置文件里手动配置, 也可在sql映射文件设置。

lazyLoadingEnabled延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。true | falsefalseaggressiveLazyLoading当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载(参考lazyLoadTriggerMethods).true | false

false (true in ≤3.4.1)

jdbcTypeForNull当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。JdbcType 常量. 大多都为: NULL, VARCHAR and OTHEROTHERlazyLoadTriggerMethods指定哪个对象的方法触发一次延迟加载。用逗号分隔的方法列表。equals,clone,hashCode,toString

     开启的方法就是配置三个全局变量:

	
		
		
		
		
		
		
		
		
		
		

.     如果想单个开启或禁用延迟加载,可以使用fetchType属性来实现

      fetchType="lazy" 表示使用懒加载   fetchType="eager"表示开启立即加载


		
四、分步查询传入多参数

       不管是 association 标签还是 collection 标签,在分步查询的时候,都可以用column属性,给select指定的sql语句传入某列的值做参数,如果需要传入多个参数的话,可以把参数封装成Map对象,写成这个格式 column="{key1=column1,key2=column2}"。

        key - 指接收参数的#{value} value值,

        column1 - 指传入的数据库表的字段别名(无别名用列名)  

把上面 二 -- 3 -- 2的实例, 业务改为, 查询 一个角色中的多用户state与role的state相同的user

use

        public List selectUserByRoleid(Integer roleId, Integer rstate);

	
		select * from t_user where role_id = #{roleId} and state = #{rstate}
	

role

	public Role getRoleOfUser(Integer id);

	
		select * from t_role where id = #{id}
	
	
		
		
		
		
		
	

			Role role = roleMapper.getRoleOfUser(1);
			System.out.println(role);
----
Role [id=1, roleName=超级管理员, state=0, users=[User [id=2, username=user, pazzword=3be7f713d9321e812231bb838448385d, state=0, regDate=Mon Oct 15 00:00:00 CST 2018]]]

 

  不要注重实例业务, 学习其中知识点。

ends~

关注
打赏
1664721914
查看更多评论
立即登录/注册

微信扫码登录

0.0534s