mybatis-映射器-select

        select元素是我们最常用也是功能最强大的sql语言。select元素帮助我们从数据库中读取出数据,组装数据给业务人员。执行select语句之前,我们需要定义参数,它可以是一个简单的参数类型,例如int,float,String,也可以是一个复杂的参数类型,例如JavaBean,Map等,这些都是mybatis接受的参数类型。执行sql后,mybatis也提供了强大的映射规则,甚至自动映射来帮助我们把返回的结果集绑定到javabean中。

      一:select元素的主要配置

       id:它和Mapper的命名空间组合起来是唯一的,提供给mybatis调用,如果命名空间和id组合起来不唯一,mybatis将抛出异常。

      parameterType:可以给出类的全命名也可以给出类的别名,但使用别名必须是mybatis内部定义或者自定义的,我们可以选择javabean,map等复杂的参数类型传递给sql。

     parameterMap: 即将被废弃的元素,不考虑。

    resultType:定义类的全路径,在运行自动匹配的情况下,结果集将通过javabean的规范映射;或定义为int,double,float等参数,也可以使用别名,但需符合别名规范,不能和resultMap同时使用。

    resultMap:它是映射集的引用,将执行强大的映射功能,我们可以使用resultType或者resultMap其中的一个,resultMap给予了我们自定义映射规则的机会,可以配置映射规则,级联,typeHandler等。

     flushCache:它的作用是在调用sql后,是否要求mybatis情况之前查询的本地缓存和二级缓存,取值为布尔值,默认为false。

    useCache:启动二级缓存的开关,是否要求mybatis将结果缓存,取值为布尔值,默认为true。

    timeout:设置超时参数,等超时的时候将抛出一次,单位为秒,默认值是数据库厂商提供的jdbc驱动所设置的秒数。

     fetchSize:获取记录的总条数设定,默认值是数据库厂商提供的jdbc驱动所设置的条数。

     statementType:告诉mybatis使用哪个jdbc的Statement工作,取值为STATEMENT(Statement),PREPARED(PreparedStatement),CallableStatement,默认值为PREPARED。

     resultSetType:这是对jdbc的resultSet接口而言,它的值包括FORWARD_ONLY(游标运行向前访问),SCROLL_SENSITIVE(双向滚动,但不及时更新,就是如果数据库里的数据修改过,并不在resultSet中反应出来),SCROLL_INSENSITIVE(双向滚动,并及时跟踪数据库的更新,以便更改resultSet中的数据),默认值是数据库厂商提供的jdbc驱动所设置的

    databaseId:它的使用可以参考前面databaseIdProvider数据库厂商标识的内容,提供多种数据库的支持。

   resultOrdered:这个设置仅使用于嵌套结果集的select语句,如果为true,就是假设包含了嵌套结果集或者是分组了,当返回一个结果行的时候,就不能对前面结果集的引用。这就确保了在获取嵌套的结果集的时候不至于导致内存不够用。取值为布尔值,默认false。

   resultSets:适合多个结果集的情况,它将列出执行sql后每个结果集的名称,每个名称之间的用逗号分隔,很少使用。


        二:简易数据类型的例子

       例如,统计一个姓氏的用户数量,我们应该把姓氏作为参数传递,而将结果设置为整型返回给调用者,代码如下:

<!--  根据姓氏查询该姓氏的用户数量 -->	
   <select id="countFirstName" parameterType="string" resultType="int" >
      select count(*) as total from t_user where name like contat(#{firstName},'%')
   </select>

  在UserDao中定义如下方法:

package org.mybatis.mapper;

import org.mybatis.pojo.User;

/**
 * 用户接口
 * 
 * @author wj
 *
 */
public interface UserMapper {
	/**
	 * 获取用户
	 * 
	 * @param id
	 * @return
	 */
	public User getUser(Long id);

	/**
	 * 插入用户
	 * 
	 * @param user
	 * @return
	 */
	public int insertUser(User user);

	/**
	 * 
	 * 查询指定姓氏的人数
	 * 
	 * @param firstName
	 * @return
	 */
	public int countFirstName(String firstName);
}

    这样就可以使用mybatis调用sql了,操作步骤可以概括如下:

   1)用id标记出这条sql

   2)parameterType定义参数类型

   3)resultType定义了返回值类型

   这是一个简单的例子,mybatis的映射往往比这复杂。


     三:自动映射

      有这样一个参数autoMappingBehavior,当它不设置为NONE的时候,mybatis会提供自动映射的功能,只要返回的sql列名和javabean的属性一致,mybatis就会帮助我们回填这些字段而无需任何配置,它可以很大程度上简化我们的配置工作。在实际情况中,大部分的数据库规范都是要求每个单词用下划线分割,而java则是用驼峰命名法来命名,于是使用列的别名就可以使得mybatis自动映射,或者直接在配置文件中开启驼峰命名。

      下面再来看一个例子,体验下自动映射。我们需要通过角色编号查询一个角色,并将结果集映射到角色的javabean上。下面先给出javabean,代码如下所示:

package org.mybatis.pojo;

public class Role {
	private Long id;
	private String roleName;
	private String note;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getRoleName() {
		return roleName;
	}

	public void setRoleName(String roleName) {
		this.roleName = roleName;
	}

	public String getNote() {
		return note;
	}

	public void setNote(String note) {
		this.note = note;
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "Role [id=" + id + ",roleName=" + roleName + ",note=" + note + "]";
	}

}

  而数据库的结构如下:

《mybatis-映射器-select》



      下面编写Mapper的映射语句,代码如下:

<!-- 根据角色id查找角色 -->
	<select id="getRole" parameterType="long" resultType="org.mybatis.pojo.Role">
		select id,role_name as roleName,note from role where id = #{id}
	</select>

   对于RoleDao接口,提供getRole方法,代码如下:

package org.mybatis.mapper;

import java.util.List;

import org.mybatis.pojo.Role;

//接口
public interface RoleMapper {
	// 通过id获取角色
	public Role getRole(Long id);

	// 插入角色
	public int insertRole(Role role);

	// 通过id删除角色
	public int deleteRole(Long id);

	// 通过角色名字,模糊查找
	public List<Role> findRole(String roleName);
}

      这样mybatis就可以通过mapper进行接口的调用。角色名称(role_name)使用sql提供的别名功能使得查询结果和javabean的属性一一对象起来,然后mybatis提供的自动映射的功能使得我们无需通过过多的提供配置信息,大大减少了我们的工作量。

     自动映射可以在settings元素中配置autoMappingBehavior属性值来设置其测量。它含三个值:

    NONE:取消自动映射。

   PARTIAL: 只会自动映射,没有定义嵌套结果集映射的结果集。

   FULL:会自动映射任意复杂的结果集(无论是否嵌套)


    默认值为PARTIAL,所以在默认的情况下,它可以做到当前对象的映射,使用FULL是嵌套映射,在性能上会下降。

    如果你的数据库是规范命名的,即每一个单词都用下划线分割,pojo采用驼峰式命名方法,那么可以设置mapUnderscoreToCamelCase为true,这样就可以实现从数据库到pojo的自动映射了。

   


       四:传递多个参数

       上面的例子是传递一个参数给映射器,更多的时候需要传递多个参数给映射器,比如需要根据角色名称和备注来模糊查询角色,这里就涉及到两个参数了。

     1,使用map传递参数

     可以使用mybatis提供的map接口作为参数来实现,代码如下:

    

<!-- 通过角色名称和备注字段两个参数模糊查询角色 -->
   <select id="findRoleByMap" parameterType="map" resultMap="roleMap">
      select id,role_name as roleName,note from role
      where role_name like concat('%',#{roleName},'%')
      and note like concat('%',#{note},'%')
   </select>

   对于Role的接口,我们需要在提供一个findRoleByMap的方法

// 通过角色名称和备注两个参数模糊查询角色信息,返回角色数组
	public List<Role> findRoleByMap(Map<String, String> params);

     有了上面的接口,我们就可以使用这个方法了,代码如下:

			Map<String,String> paramsMap = new HashMap<String,String>();
			paramsMap.put("roleName", "jack");
			paramsMap.put("note", "test");
			roleMapper.findRoleByMap(paramsMap);

   上面的使用方法比较简单,但是有一个弊端,这样设置的参数使用了Map,而Map需要键值对应,由于业务关联性不强,需要深入看代码,造成可读性下降。mybatis提供了更好的实现方法,它就是注解参数的形式,下面看看使用注解,怎么实现参数的传递。


     2,使用注解的方式传递参数

     我们需要使用mybatis的参数注解@Param(org.apache.ibatis.annotations.Param)来实现传递参数的功能。操作方法是把RoleDao接口修改为下面的形式:

// 通过mybatis的注解实现传递参数
	public List<Role> findRoleByAnnotation(@Param("roleName") String rolename, @Param("note") String note);

   把映射器的xml修改为无需定义参数类型,代码如下:

  

<!-- 通过角色名称和备注字段两个参数模糊查询角色,通过mybatis的注解传递参数 -->
   <select id="findRoleByAnnotation"  resultMap="roleMap">
      select id,role_name as roleName,note from role
      where role_name like concat('%',#{roleName},'%')
      and note like concat('%',#{note},'%')
   </select>

       当我们把参数传递给后台的时候,通过@Param提供的名称Mybatis就会知道#{roleName}代表rolename,参数的可读性大大提高了。但这会引起另外一个麻烦,一条sql拥有10个参数的查询,如果我们都使用@Param方式,那么参数将十分复杂,可读性依旧不高,不够mybatis为我们提供了javabean定义参数的方式来解决这个问题。


     3:使用JavaBean传递参数

     在参数过多的情况下,Mybatis允许组织一个JavaBean,通过简单的setter和getter方法设置参数,这样就可以提供我们的可读性。首先定义一个RoleParams的JavaBean,代码如下所示:

package org.mybatis.params;

public class RoleParam {

	private String roleName;
	private String note;

	public String getRoleName() {
		return roleName;
	}

	public void setRoleName(String roleName) {
		this.roleName = roleName;
	}

	public String getNote() {
		return note;
	}

	public void setNote(String note) {
		this.note = note;
	}

}

  下面用javabean改写一下传递参数的例子,代码如下:

 

 <!-- 通过角色名称和备注字段两个参数模糊查询角色,通过javabean传递参数 -->
   <select id="findRoleByParms" parameterType="org.mybatis.params.RoleParam" resultMap="roleMap">
      select id,role_name as roleName,note from role
      where role_name like concat('%',#{roleName},'%')
      and note like concat('%',#{note},'%')
   </select>


   同样在Role的接口中提供一个方法

// 通过javabean的方法传递参数
	public List<Role> findRoleByParms(RoleParam params);

   然后在使用这个接口的时候直接传入javabean对象即可,这就是通过javabena传递多个参数的方式。


   小结:

     上面讲解了三种方式进行多个参数的传递,一是通过map的方式,二是通过mybatis注解的方式,三是通过javabean的方式。下面分析下利弊:

      1,使用map传递参数,因为map导致业务可读性的丧失,从而导致后续扩展和维护的困难,在实际的应用中,不建议使用。

     2,使用@Param注解传递多个参数,这种方式的使用受到参数个数(n)的影响。当n《=5时,它是最佳的传参方式,它比javabean更好,因为更加直观;当n大于5时,多个参数将给调用带来困难。

    3,当参数个数多于5个时,建议使用javabean方式


   

      五:使用resultMap映射结果集

       前面介绍了自动映射,返回的也只是简单的javabean对象,但是在某些时候,我们需要处理更为复杂的映射,resultMap为我们提供了这样的模式。我们需要在映射器中定义resultMap,这也是我们常见的场景,代码如下:

<resultMap type="role" id="roleMap">
     <!--定义结果类型转换标识,才能使用类型转换器  -->
     <id column = "id" property = "id" javaType ="long" jdbcType = "BIGINT"/>
     <result column ="role_name" property = "roleName" javaType = "string" jdbcType = "VARCHAR"/>
     <result column = "note" property = "note"/>
   </resultMap>

<!-- 根据角色id查找角色 -->
	<select id="getRole" parameterType="long" resultMap="roleMap">
		select id,role_name as roleName,note from role where id = #{id}
	</select>

    下面解释下resultMap的配置:

   1,定义了唯一的标识(id)为roleMap的resultMap,用type属性去定义它对应的是哪个JavaBean(也可以使用别名),上面我用的就是别名。

   2,通过id元素定义resultResultMap,这个对象代表着使用哪个属性作为其主键。result元素定义了普通列的映射关系,例如,把sql结果返回的列role_no和type属性定义的javabean的属性id等做一 一对应。

   3,这样select语句就不在需要使用自动映射的规则,直接用resultMap属性指定resultMap定义的id(roleMap)即可,这样mybatis就会使用我们的自定义映射规则。


    resultMap是映射器里面最为复杂的元素,它一般用于复杂,级联的配置,我们可以使用resultMap通过自动映射来完成,这样配置的工作量就会大大减少。·



    原文作者:修炼中的菜鸟
    原文地址: https://blog.csdn.net/wj903829182/article/details/72718314
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞