【SSM-MyBatis框架】Mapper.xml配置文件(mybatis的核心)

  Mapper.xml映射文件中定义了操作数据库的sql,每一个sql是一个statement,映射文件是myBatis的核心。

  1.输入映射(ParameterType)

    通过parameterType指定输入参数的类型,类型可以是简单类型,pojo,包装类型,hashmap。

    1.1 #{}与${}

     #{}实现向prepareStatement中的预处理语句中设置参数值,sql语句中#{}表示一个占位符。

   

<select id="findUserById" parameterType="int"  resultType="User">
	SELECT * FROM USER WHERE id = #{value}
</select>

   

   使用占位符可以防止sql的注入,在使用时不需要关心参数的类型,mybatis会自动的进行Java与jdbc的转换。#{} 可以接受简单类型和pojo的属性值。如果parameterType中指定的是单个的简单类型,#{}中可以使用value或是其他值。


  #{}与${}的不同:

   通过${}可以将parameterType传入的内容拼接在sql中,并且不进行jdbc类型转换,${}可以接受简单类型和pojo的属性值,若parameterType为单个简单类型时,${}中必须使用value。使用${}不能防止sql注入,但有时会很方便,例如:

 

	<select id="findUserByUsername" parameterType="java.lang.String" resultType="User">
				SELECT * FROM USER WHERE username LIKE '%${value}%'
	</select>

再比如order by排序,如果将列名通过参数传入sql,根据传的列名进行排序,应该写为:

ORDER BY${columnName}

如果使用#{}将无法实现此功能。

   1.2 传递包装类型对象:

     开发中通过pojo传递查询条件,查询条件是综合的查询条件时,不仅包含用户的查询条件,而且包含其他的查询条件,这时可以使用包装对象类型传递参数。

     1. 定义包装类型对象:

       

public class QueryVo {
	
	private User user;
	
	//自定义用户扩展类
	private UserCustom userCustom;


    2.mapper.xml文件:

   

<!-- 用户信息的综合查询	这是输入映射传递pojo包装类对象的测试
				UserQueryVo:就是UserCustom的包装类,在其中也可以包装其他类的对象
				 UserCustom:是User的扩展类-->
		<select id="findUserList" parameterType="queryVo" resultType="UserCustom">
			SELECT * FROM USER where user.sex=#{userCustom.sex} and user.username LIKE '%${userCustom.username}%'


		</select>		

    说明 :mybatis底层是通过ognl从pojo中获取属性值:#{userCustom.sex} ,userCustom即是传入的pojo包装对象的属性值。 queryVo即是上面包装对象的别名。


   1.3 传递HashMap:

     1.mapper.xml文件:

   

<select id="findUserListHashmap" parameterType="hashmap" resultType="UserCustom">
	SELECT * FROM USER where user.sex=#{sex} AND user.username LIKE '%${name}%'


</select>	



  2.测试文件:

   

public void findUserListHashmap() throws Exception {
		SqlSession session = sqlSessionFactory.openSession();
		
		//通过session自动创建mapper代理对象
		UserMapper userMap = session.getMapper(UserMapper.class);
		Map<String , Object> map = new HashMap<String, Object>();
		map.put("sex", "1");
		map.put("name","小明");
		List<UserCustom> list = userMap.findUserListHashmap(map);
		System.out.println(list);
	}


    2.输出映射:(ResultType、ResultMap)


     2.1ResultType,输出为简单类型:

      1.mapper.xml文件:

  

<!-- 输出映射的测试,输出一个简单类型(查询数据记录总数) -->
		<select id="findCount"  parameterType="UserQueryVo" resultType="int">
			SELECT COUNT(*) FROM USER Where 
	        </select>


    输出简单类型时,必须查询出来的结果集有一条记录,最终将第一个字段的值转换为输出类型。使用session中的selectOne可进行查询单条记录。


     2.2 ResultType,输出为pojo类型:

    1.mapper.xml


(方法调用selectOne)

<select id="findUserById" parameterType="int"  resultType="User">
	SELECT * FROM USER WHERE id = #{value}
</select>

   

(方法调用selectList)

<select id="findUserById" parameterType="user"  resultType="User">
	SELECT * FROM USER WHERE name like '%${name}%'
</select>

    2.3  ResultType 总结:

   

输出pojo对象和输出pojo列表在sql中定义的resultType是一样的。

返回单个pojo对象要保证sql查询出来的结果集为单条,内部使用session.selectOne方法调用,mapper接口使用pojo对象作为方法返回值。

返回pojo列表表示查询出来的结果集可能为多条,内部使用session.selectList方法,mapper接口使用List<pojo>对象作为方法返回值。


  2.4 输出类型为hashMap:

 

 输出类型可以改为hashMap,输出的字段名作为key,输出的字段值为value


  2.5 ResultMap(重点)


   ResultType可以指定pojo,将查询结果映射成pojo的属性。但是要求数据库列名与pojo属性名必须相同,才能映射成功。

 

   如过查询的字段名与pojo的属性名不同,则通过resultMap,将字段名和属性名做一个映射,resultMap实质上,还是将数据库字段映射到pojo中。

    resultMap可以实现将查询结果映射为复杂类型的pojo。如:在查询结果映射对象中,包括pojo和list实现一对一和一对多的查询。


      例子:

        实现下面一个sql的输出结果的参数映射:

             select id,id_ ,name, name_ from user where id=#{id}

     User类中属性名和上面查询的列名不一样。

    定义ResultMap:

          

     

<resultMap type="cn.edu.hpu.ssm.po.Orders" id="ordersMap">
				<id column="id" property="id"/>
				<result column="user_id" property="userId"/>
				<result column="number" property="number"/>
				<result column="createtime" property="createtime"/>
				<result column="note" property="note"/>
				
				<association property="user" javaType="cn.edu.hpu.ssm.po.User">
						<id column="user_id" property="id"/>
						<result column="username" property="username"/>
						<result column="sex" property="sex"/>
						<result column="address" property="address"/>
				</association>
</resultMap>


   ResultMap中参数的含义:

       type:定义映射的最终类型。  id:引用时的标识

   <id: column="" property="">   :

         id:表示查询结果集中唯一标识。  column:查询出来的列名。 property:type指定的pojo类中的属性名。

  <result column="" property=""/>
         reslut:对普通列的标识。    

   

2.6小结:

  使用ResultType进行结果映射时,只有查询出来的列名和pojo中的属性名一致时,才能映射成功。如果列名和pojo的属性名不一致,则需要通过ResultMap对列名和属性名进行一个映射。



 3.动态sql:(重点)

    通过mybatis提供的标签进行动态的sql拼接。

  1.where if

   mybatsi的核心,对sql语句进行灵活的操作,通过表达式进行判断,对sql进行灵活的拼接、组装。

   可以对输出参数进行判断,若果输入参数不为空,或是符合条件才进行sql拼接。

 

	<!-- 用户信息的综合查询	这是输入映射传递pojo包装类对象的测试
				UserQueryVo:就是UserCustom的包装类,在其中也可以包装其他类的对象
				 UserCustom:是User的扩展类-->
		<select id="findUserList" parameterType="UserQueryVo" resultType="UserCustom">
			SELECT * FROM USER 
			<!-- where 子句能够自动消除第一个and -->
			<where>
				<if test="userCustom != null">
					<if test="userCustom.sex != null and userCustom.sex != '' ">
						and user.sex=#{userCustom.sex} 
					</if>
					<if test="userCustom.username != null and userCustom.username !='' ">
						and user.username LIKE '%${userCustom.username}%'
					</if>
				</if>
			</where> 
		</select>		


    2.sql片段:

     将上面动态sql判断代码块抽取出来,组成一个sql片段。其他的statement可以对其引用。

 

<!-- 自定义sql片段,便于复用 -->
	<sql id="sql_mQUery">
				<if test="userCustom != null">
					<if test="userCustom.sex != null and userCustom.sex != '' ">
						and user.sex=#{userCustom.sex} 
					</if>
					<if test="userCustom.username != null and userCustom.username !='' ">
						and user.username LIKE '%${userCustom.username}%'
					</if>
				</if>
		
	</sql>


  引用sql片段:

 

<!-- 输出映射的测试,输出一个简单类型(查询数据记录总数) -->
		<select id="findCount"  parameterType="UserQueryVo" resultType="int">
			SELECT COUNT(*) FROM USER 
			<where>
				<!-- 如果指定的id对应的sql片段不在本mapper.xml中,则需要加入namespace -->
				<include refid="sql_mQUery"></include>
				<!-- 这里可以再指定sql片段 -->
			</where> 
		</select>



       3.ForEach

   向sql传递数组或者List,Mybatis使用foreach解析:

  例如:

SELECT * FROM USER WHERE id=1 OR id=10 ORid=16

    1.在输入参数类型中添加List<Integer> :

   

public class UserQueryVo {

	private UserCustom userCustom;

	private List<Integer> ids;
	

      2.mapper.xml:

  

<!-- 动态sql之foreach的练习 -->
		
		<select id="findUserByIds" parameterType="UserQueryVo" resultType="UserCustom">
			SELECT * FROM USER
			<where>
				<if test="ids != null">
					<!--使用foreach循环遍历
						 collection:指定集合的输入对象
						 item:每个遍历生成的对象
						 open:开始遍历时生成
						 close:结束遍历时生成
						separator:遍历两个对象中间的拼接
					 -->
					<foreach collection="ids" item="user_id" open="And ( " close=")" separator="OR">
							<!-- 每个遍历中所需拼接的字符串 -->
							id=#{user_id}
					</foreach>
				</if>
			</where>
		</select>
		














 



  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值