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

前端之家收集整理的这篇文章主要介绍了【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 USERwhere 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 USERwhere 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 USERWhere 
	        </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.3ResultType总结:

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

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

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


2.4输出类型为hashMap:

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


2.5ResultMap(重点)


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

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

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


例子:

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

selectid,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.whereif

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>
		


















猜你在找的XML相关文章