mybatis--映射文件详解

Mybatis映射文件

一、输入映射

parameterType

指定输入参数的java类型,可以使用别名或者类的全限定名。它可以接收简单类型、POJO、HashMap。

1、传递简单类型

根据用户ID查询用户信息:

<select id="findUserById" parameterType="int" resultType="com.itheima.mybatis.po.User">
		SELECT * FROM USER WHERE id =#{id}
</select>

2、传递POJO对象

添加用户:

<insert id="insertUser" parameterType="com.itheima.mybatis.po.User">
		<selectKey keyProperty="id" resultType="int" order="AFTER">
			SELECT LAST_INSERT_ID()
		</selectKey>
		INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
</insert>

3、传递POJO包装对象

开发中通过pojo传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),

这时可以使用包装对象传递输入参数。

3.1需求

综合查询用户信息,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息)。

3.2 定义包装对象

一般User.java类要和数据表表字段一致,最好不要在这里面添加其他字段,在mybatis的逆向工程时,会根据表结构,生成po类,

如果在po类中扩展字段,此时会被覆盖掉。

所以针对要扩展的po类,我们需要创建一个扩展类,来继承它。

public class UserExt extends User{
	//这里可以定义user的一些扩展信息
}

定义POJO包装类:

public class UserQueryVO {

	//用户信息
	private UserExt userExt;

	//商品ID集合
	private List<Integer> idList;

	//商品信息

	public List<Integer> getIdList() {
		return idList;
	}

	public void setIdList(List<Integer> idList) {
		this.idList = idList;
	}

	public UserExt getUserExt() {
		return userExt;
	}

	public void setUserExt(UserExt userExt) {
		this.userExt = userExt;
	}

	//订单信息

}

3.3编写Mapper接口

//通过包装类来进行复杂的用户信息综合查询
public List<UserExt> findUserList(UserQueryVO userQueryVO);

3.4编写mapper映射文件

<!-- 通过包装类来进行复杂的用户信息综合查询 -->
<select id="findUserList" parameterType="userQueryVO" resultType="userExt">
		SELECT * FROM USER WHERE sex=#{userExt.sex} AND username LIKE ‘%${userExt.username}%‘
</select>

注意:入参的类型变为UserQueryVO、结果集的类型变为UserExt,#{}里面的参数变为UserQueryVO对象中的userExt属性的sex和username子属性。

3.5编写测试代码

@Test
public void findUserListTest() {
	// 创建SqlSession
	SqlSession sqlSession = sqlSessionFactory.openSession();
	// 通过SqlSession,获取mapper接口的动态代理对象
	UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

	//构造userQueryVO对象
	UserQueryVO userQueryVO = new UserQueryVO();

	// 构造UserExt对象
	UserExt userExt = new UserExt();
	userExt.setSex("1");
	userExt.setUsername("小明");

	userQueryVO.setUserExt(userExt);

	// 调用mapper对象的方法
	List<UserExt> list = userMapper.findUserList(userQueryVO);

	System.out.println(list);
	// 关闭SqlSession
	sqlSession.close();
}

4、传递HashMap

同传递POJO对象一样,map的key相当于pojo的属性

4.1映射文件

<!-- 传递hashmap综合查询用户信息 -->
	<select id="findUserByHashmap" parameterType="hashmap" resultType="user">
	   select * from user where id=#{id} and username like ‘%${username}%‘
	</select>

上边红色标注的id和username是hashmap的key。

4.2测试代码

Public void testFindUserByHashmap()throws Exception{
		//获取session
		SqlSession session = sqlSessionFactory.openSession();
		//获限mapper接口实例
		UserMapper userMapper = session.getMapper(UserMapper.class);
		//构造查询条件Hashmap对象
		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("id", 1);
		map.put("username", "管理员");

		//传递Hashmap对象查询用户列表
		List<User>list = userMapper.findUserByHashmap(map);
		//关闭session
		session.close();
	}

异常测试:

传递的map中的key和sql中解析的key不一致。

测试结果没有报错,只是通过key获取值为空。

二、输出映射

1、resultType

(1)使用方法

使用resultType进行结果映射时,查询的列名和映射的pojo属性名完全一致,该列才能映射成功。

如果查询的列名和映射的pojo属性名全部不一致,那么映射的对象为空,不会创建pojo对象;

如果查询的列名和映射的pojo属性名有一个一致,那么映射的对象不为空,会创建pojo对象,但是只有映射正确的那一个属性才有值。

(2)输出简单类型

注意,对简单类型的结果映射也是有要求的,查询的列必须是一列,才能映射为简单类型。

当输出结果只有一列时,可以使用ResultType指定简单类型作为输出结果类型。

2.1需求

综合查询用户总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息)。

2.2Mapper映射文件

<!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->
<select id="findUsersCount" parameterType="UserQueryVO"
		resultType="int">
		SELECT count(1) FROM USER WHERE sex = #{userExt.sex} AND username	LIKE ‘%${userExt.username}%‘
</select>

2.3Mapper接口

//综合查询用户信息总数。学习:resultType输出简单类型
public int findUsersCount(UserQueryVO vo);

2.4测试代码

@Test
public void testFindUsersCount() {
	// 创建SqlSession
	SqlSession sqlSession = sqlSessionFactory.openSession();
	// 通过SqlSession,获取mapper接口的动态代理对象
	UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

	//构造userQueryVO对象
	UserQueryVO userQueryVO = new UserQueryVO();

	// 构造UserExt对象
	UserExt userExt = new UserExt();
	userExt.setSex("1");
	userExt.setUsername("小明");

	userQueryVO.setUserExt(userExt);

	int count = mapper.findUsersCount(userQueryVO);
	System.out.println(count);	// 关闭SqlSession
	sqlSession.close();
}

(3)输出POJO单个对象和列表

注意:输出单个pojo对象和pojo列表(盛放pojo对象)时,mapper映射文件中的resultType的类型是一样的,mapper接口的方法返回值不同。

3.1Mapper映射文件

<select id="findUsersByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
		SELECT * FROM USER WHERE username LIKE ‘%${value}%‘
</select>

3.2Mapper接口

1、输出单个pojo对象

//根据用户名称来模糊查询用户信息
	public User findUsersByName(String username);

2、输出pojo列表

//根据用户名称来模糊查询用户信息列表
	public List<User> findUsersByName(String username);

总结:同样的mapper映射文件,返回单个对象和对象列表时,mapper接口在生成动态代理的时候,

会根据返回值的类型,决定调用selectOne方法还是selectList方法。

2、resultMap

resultMap可以进行高级结果映射(一对一、一对多映射)

(1)使用方法

如果查询出来的列名和属性名不一致,通过定义一个resultMap将列名和pojo属性名之间作一个映射关系。

1、  定义resultMap

2、  使用resultMap作为statement的输出映射类型。

(2)需求

把下面SQL的输出结果集进行映射

SELECT id id_,username username_,sex sex_FROM USER WHERE id = 1

(3)Mapper映射文件

定义resultMap:

<!-- 定义resultMap -->
<!--
	[id]:定义resultMap的唯一标识
	[type]:定义该resultMap最终映射的pojo对象
	[id标签]:映射结果集的唯一标识列,如果是多个字段联合唯一,则定义多个id标签
	[result标签]:映射结果集的普通列
	[column]:SQL查询的列名,如果列有别名,则该处填写别名
	[property]:pojo对象的属性名
-->
<resultMap type="user" id="userResultMap">
	<id column="id_" property="id"/>
	<result column="username_" property="username"/>
	<result column="sex_" property="sex"/>
</resultMap>

定义statement:

<!-- 根据ID查询用户信息(学习resultMap) -->
<select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
     SELECT id id_,username username_,sex sex_ FROM USER WHERE id = #{id}
</select>

(4)Mapper接口定义

	//根据ID查询用户信息(学习resultMap)
	public User findUserByIdResultMap(int id);

定义Statement使用resultMap映射结果集时,Mapper接口定义方法的返回值类型为mapper映射文件中resultMap的type类型。

(5)测试代码

@Test
public void findUserByIdResultMapTest() {
	// 创建SqlSession
	SqlSession sqlSession = sqlSessionFactory.openSession();
	// 通过SqlSession,获取mapper接口的动态代理对象
	UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

	// 调用mapper对象的方法
	User user = userMapper.findUserByIdResultMap(1);

	System.out.println(user);
	// 关闭SqlSession
	sqlSession.close();
}

三、动态SQL

1、If和where

?  If标签:作为判断入参来使用的,如果符合条件,则把if标签体内的SQL拼接上。

注意:用if进行判断是否为空时,不仅要判断null,也要判断空字符串‘’;

?  Where标签:会去掉条件中的第一个and符号。

(1)需求

用户信息综合查询列表和用户信息综合查询总数这两个statement的定义使用动态SQL。

(2)映射文件

<!-- 综合查询用户信息,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->
<select id="findUsersByQueryVO" parameterType="cn.itcast.mybatis.po.QueryUserVO"
		resultType="User">
		SELECT * FROM USER
	<where>
		<if test="userExt != null">
			<if test="userExt.sex != null and userExt.sex != ‘‘">
				AND sex = #{userExt.sex}
			</if>
			<if test="userExt.username != null and userExt.username != ‘‘">
				AND username LIKE ‘%${userExt.username}%‘
			</if>
		</if>
	</where>
</select>

<!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->
<select id="findUsersCount" parameterType="QueryUserVO"
		resultType="int">
	SELECT count(1) FROM USER
	<where>
		<if test="userExt != null">
			<if test="userExt.sex != null and userExt.sex != ‘‘">
				AND sex = #{userExt.sex}
			</if>
			<if test="userExt.username != null and userExt.username != ‘‘">
				AND username LIKE ‘%${userExt.username}%‘
			</if>
		</if>
	</where>
</select>

(3)Mapper接口

//通过包装类来进行复杂的用户信息综合查询
public List<UserExt> findUserList(UserQueryVO userQueryVO);
//综合查询用户总数
public int findUsersCount(UserQueryVO userQueryVO);

(4)测试代码

不传用户名:

@Test
	public void testFindUserList() throws Exception{
		// 创建UserMapper对象
		SqlSession sqlSession = sqlSessionFactory.openSession();
		// 由mybatis通过sqlsession来创建代理对象
		UserMapper mapper = sqlSession.getMapper(UserMapper.class);

		QueryUserVO vo = new QueryUserVO();
		User user = new User();
		//此处使用动态SQL,不传username参数
		user.setSex("1");
//		user.setUsername("小明");
		vo.setUser(user);

		List<User> list = mapper.findUserList(vo);

		System.out.println(user);
		sqlSession.close();

	}

输出的SQL如下(也不包含用户名):

通过测试可以得知,打印出的SQL语句确实会随着条件的满足情况而不一样。

2、SQL片段

Mybatis提供了SQL片段的功能,可以提高SQL的可重用性。

2.1定义SQL片段

使用sql标签来定义一个SQL片段:

<!-- 定义SQL片段 -->
<!--
	[sql标签]:定义一个SQL片段
	[id]:SQL片段的唯一标识
	建议:
		1、SQL片段中的内容最好是以单表来定义
		2、如果是查询字段,则不要写上SELECT
		3、如果是条件语句,则不要写上WHERE
 -->
<sql id="select_user_where">
	<if test="userExt != null">
		<if test="userExt.sex != null and userExt.sex != ‘‘">
			AND sex = #{userExt.sex}
		</if>
		<if test="userExt.username != null and userExt.username != ‘‘">
			AND username LIKE ‘%${userExt.username}%‘
		</if>
	</if>
</sql>

2.2引用SQL片段

使用<includerefid=’’ /> 来引用SQL片段:

<!-- 根据用户id来查询用户信息(使用SQL片段) -->
<!--
	[include标签]:引用已经定义好的SQL片段
	[refid]:引用的SQL片段id
-->
<select id="findUserList" parameterType="userQueryVO" resultType="userExt">

	SELECT * FROM USER
<where>
		<include refid="select_user_where"/>
	</where>
</select>
<!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->
<select id="findUsersCount" parameterType="QueryUserVO"
		resultType="int">
	SELECT count(1) FROM USER
	<where>
		<include refid="select_user_where"/>
	</where>
</select>

3、foreach

向sql传递数组或List时,mybatis使用foreach解析数组里的参数并拼接到SQL中。

(1)传递pojo对象中的list集合

1.1需求

在用户查询列表和查询总数的statement中增加多个id输入查询。

1.2SQL

SELECT * FROM user WHERE id IN (1,10,16)

1.3定义pojo中的list属性

package com.itheima.mybatis.po;

import java.util.List;

/**
 * <p>Title: UserQueryVO</p>
 * <p>Description: TODO(这里用一句话描述这个类的作用) <p>
 */

public class UserQueryVO {

	//用户信息
	private UserExt userExt;

	//商品ID集合
	private List<Integer> idList;

	//商品信息

	public List<Integer> getIdList() {
		return idList;
	}

	public void setIdList(List<Integer> idList) {
		this.idList = idList;
	}

	public UserExt getUserExt() {
		return UserExt;
	}

	public void setUserExt(UserExt userExt) {
		this.UserExt = UserExt;
	}

	//订单信息

}

1.4映射文件

<!-- [foreach标签]:表示一个foreach循环 -->
<!-- [collection]:集合参数的名称,如果是直接传入集合参数,则该处的参数名称只能填写[list]。 -->
<!-- [item]:每次遍历出来的对象 -->
<!-- [open]:开始遍历时拼接的串 -->
<!-- [close]:结束遍历时拼接的串 -->
<!-- [separator]:遍历出的每个对象之间需要拼接的字符 -->
<if test="idList != null and idList.size > 0">
<foreach collection="idList" item="id" open="AND id IN (" close=")" separator=",">
		#{id}
</foreach>
</if>

1.5Mapper接口

//根据用户ID的集合查询用户列表(学习foreach标签之通过POJO对象传ID集合)
public List<UserExt> findUserList(UserQueryVO vo);

1.6测试代码

@Test
public void testFindUserList() {
	// 创建SqlSession
	SqlSession sqlSession = sqlSessionFactory.openSession();
	// 通过SqlSession,获取mapper接口的动态代理对象
	UserMapper mapper = sqlSession.getMapper(UserMapper.class);

	// 构造QueryUserVO对象
	QueryUserVO vo = new QueryUserVO();
	// UserExt ext = new UserExt();
	// ext.setUsername("小明");
	// ext.setSex("1");
	// vo.setUserExt(ext);

	// 创建用户ID集合,然后设置到QueryUserVO对象中
	List<Integer> idList = new ArrayList<Integer>();
	idList.add(1);
	idList.add(10);
	idList.add(16);
	vo.setIdList(idList);

	// 调用mapper代理对象的方法
	List<UserExt> list = mapper.findUserList(vo);
	System.out.println(list);
	// 关闭SqlSession
	sqlSession.close();
}

(2)直接传递List集合

2.1需求

根据用户ID的集合查询用户列表

2.2SQL

SELECT * FROM user WHERE id IN (1,10,16)

2.3映射文件

<!-- 根据用户ID的集合查询用户列表(学习foreach标签之直接传ID集合) -->
<!--
	[foreach标签]:表示一个foreach循环
	[collection]:集合参数的名称,如果是直接传入集合参数,则该处的参数名称只能填写[list]。
	[item]:定义遍历集合之后的参数名称
	[open]:开始遍历之前需要拼接的SQL串
	[close]:结束遍历之后需要拼接的SQL串
	[separator]:遍历出的每个对象之间需要拼接的字符
 -->
<select id="findUsersByIdList" parameterType="java.util.List" resultType="user">
	SELECT * FROM USER
	<where>
		<if test="list != null and list.size > 0">
			<foreach collection="list" item="id" open="AND id IN (" close=")" separator=",">
				#{id}
			</foreach>
		</if>
	</where>
</select>

2.4Mapper接口

//根据用户ID的集合查询用户列表(学习foreach标签之直接传ID集合)
public List<User> findUsersByIdList (List<Integer> idList);

2.5测试代码

@Test
public void findUsersByIdListTest() {
	// 创建SqlSession
	SqlSession sqlSession = sqlSessionFactory.openSession();
	// 通过SqlSession,获取mapper接口的动态代理对象
	UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

	// 构造List<Integer>集合
	List<Integer> idList = new ArrayList<Integer>();
	idList.add(1);
	idList.add(10);
        idList.add(16);

	// 调用mapper对象的方法
	List<User> list = userMapper.findUsersByIdList (idList);
	System.out.println(list);
	// 关闭SqlSession
	sqlSession.close();
}

时间: 2024-10-11 17:16:08

mybatis--映射文件详解的相关文章

hibernate 对象关系映射文件详解

POJO 类和数据库的映射文件*.hbm.xml POJO类和关系数据库之间的映射可以用一个XML文档来定义. 映射文件的扩展名为.hbm.xml 在运行时Hibernate将根据这个映射文件来生成各种SQL语句 通过POJO类的数据库映射文件,Hibernate可以理解持久化类和数据表之间的对应关系,也可以理解持久化类属性与数据库表列之间的对应关系 映射文件说明 hibernate-mapping 类层次:class 主键:id 基本类型:property 实体引用类: many-to-one

Hibernate配置文件与映射文件详解

Hibernate是一个彻底的ORM(Object Relational Mapping,对象关系映射)开源框架. 我们先看一下官方文档所给出的,Hibernate 体系结构的高层视图: 其中PO=POJO+映射文件 根据体系结构视图可以了解到整个利用Hibernate框架实现的项目包括整个重要的配置文件: Hibernate配置文件:实现Hibernate基础配置,是Hibernate能够友好的与DB进行交互基础: 开发时放置src目录下,取名为:hibernate.cfg.xml(hiber

Hibernate 映射文件详解

Hibernate 映射文件详解 2010-09-02 19:03:33|  分类: Hibernate学习|举报|字号 订阅 Hibernate的持久化类和关系数据库之间的映射通常是用一个XML文档来定义的.该文档通过一系列XML元素的配置,来将持久化类与数据库表之间建立起一一映射.这意味着映射文档是按照持久化类的定义来创建的,而不是表的定义. 一.根元素:<hibernate-mapping>,每一个hbm.xml文件都有唯一的一个根元素,包含一些可选的属性 1)package:指定一个包

mybatis核心文件详解

MyBatis配置文件详解 configuration  这是配置文件的根元素标签,所有的其他元素都要在这个标签下使用. environments   用于管理所有环境,并可以指定默认使用哪个环境,通过default属性来指定 environment 用于配置环境.id属性用于唯一标识当前环境 transtionManager 用于配置事务管理器 type属性   用于指定MyBatis采用何种方式管理事务 JDBC:表示MyBatis采用与原生JDBC一致的方式管理事务. MANAGED:将事

Mybatis(三) 映射文件详解

前面说了全局配置文件中内容的详解,大家应该清楚了,现在来说说这映射文件,这章就对输入映射.输出映射.动态sql这几个知识点进行说明,其中高级映射(一对一,一对多,多对多映射)在下一章进行说明. 一.输入映射 输入映射:配置statement中输入参数的类型.有四种 1.1.传递简单类型,八大基本类型,比如int类型 findUserById:根据id进行查询对应user,那么传入的就应该是int类型的值.所以使用别名int来映射传入的值 1.2.传递pojo(代表正常的对象,比如user的jav

MyBatis -- sql映射文件详解

MyBatis 真正的力量是在映射语句中.和对等功能的jdbc来比价,映射文件节省很多的代码量.MyBatis的构建就是聚焦于sql的. sql映射文件有如下几个顶级元素:(按顺序) cache配置给定命名空间的缓存. cache-ref从其他命名空间引用缓存配置. resultMap最复杂,也是最有力量的元素,用来描述如何从数据库结果集中来加载你的对象. parameterMap已经被废弃了!老式风格的参数映射.内联参数是首选,这个元素可能在将来被移除. sql可以重用的SQL块,也可以被其他

Mybatis的配置文件和映射文件详解

一.Mybatis的全局配置文件 1.SqlMapConfig.xml是mybatis的全局配置文件,配置内容如下: properties(属性) settings(全局配置参数) typeAliases(类型别名) typeHandlers(类型处理器) objectFactory(对象工厂) plugins(插件) environments(环境集合属性对象) --environment(环境子属性对象) ----transactionManager(事务管理) ----dataSource

mybaits入门demo映射文件详解(三)

第二篇文章:  mybaits入门demo配置文件详解(二) Mapper XML 文件 MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大,映射器的 XML 文件就显得相对简单.如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码.MyBatis 就是针对 SQL 构建的,并且比普通的方法做的更好. SQL 映射文件有很少的几个顶级元素(按照它们应该被定义的顺序): cache – 给定命名空间的缓存配置. cache-ref –

Hibernate映射文件详解

Hibernate的持久化类和关系数据库之间的映射通常是用一个XML文档来定义的.该文档通过一系列XML元素的配置,来将持久化类与数据库表之间建立起一一映射.这意味着映射文档是按照持久化类的定义来创建的,而不是表的定义. 一.根元素:<hibernate-mapping>,每一个hbm.xml文件都有唯一的一个根元素,包含一些可选的属性 1)package:指定一个包前缀,如果在映射文档中没有指定全限定的类名,就使用这个作为包名,如 <hibernate-mapping package=

Hibernate映射文件详解(News***.hbm.xml)一

Hibernate是一个彻底的ORM(Object Relational Mapping,对象关系映射)开源框架. 我们先看一下官方文档所给出的,Hibernate 体系结构的高层视图: 其中PO=POJO+映射文件 根据体系结构视图可以了解到整个利用Hibernate框架实现的项目包括整个重要的配置文件: Hibernate配置文件:实现Hibernate基础配置,是Hibernate能够友好的与DB进行交互基础: 开发时放置src目录下,取名为:hibernate.cfg.xml(hiber