前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MyBatis(随笔2 : Sql映射文件 )

MyBatis(随笔2 : Sql映射文件 )

作者头像
Java_慈祥
发布2024-08-06 13:02:08
920
发布2024-08-06 13:02:08
举报
文章被收录于专栏:SSM专栏

Sql文件映射

这里只是笔记,属性详情,关键还是要多练 ——实例代码 MyBatisDemo

MyBatis 真正的强大在于映射语句,专注于SQL,功能强大,SQL映射的配置却是相当简单

SQL映射文件的几个顶级元素

name

详情

mapper

namespace: 命名空间

cache

配置给定命名空间的缓存

cache-ref

从其他命名空间引用缓存配置

resultMap

用来描述数据库结果集和对象的对应关系

sql

可以重用的SQL块,也可以被其他语句引用

insert

映射插入语句

update

映射更新语句

delete

映射删除语句

select

映射查询语句

:--------:

-------------:

  • mapper namespace:命名空间: 一般引用对应的接口类地址,也可以随便起名,如果面向接口编程则必须要是对应接口的地址引用… namespace和子元素的id联合保证唯一,接口中的方法与映射文件中的sql 语句 一一对应;
代码语言:javascript
复制
<mapper namespace="命名空间">
	<select id="login" …
		……
	</select>
</mapper>
  • Select select是MyBatis中最常用的元素之一, 用于查询 sql 操作; select语句有很多属性可以详细配置每一条语句 常用属性 id 命名空间中唯一的标识符可随意 但如果是 面向接口编程 方法名与映射文件中的SQL语句 id 一 一 对应(要相同); parameterType 传入SQL语句的参数类型, 基础数据类型: int、String、 Date等只能传入一个,通过 #{随意参数名} 即可获取传入的值; 这里参数名可以随意… 因为参数只有一个无须细分了~ 复杂数据类型: Java实体类、Map等通过 #{属性名} 或者 #{map的keyName} 即可获取传入值; Map可用于多个参数; resultType SQL语句返回值的类型 与parameterType类似, 可以是基础或复杂数据类型… MyBatis中resultType自动映射, 字段名 和 属性名必须一致才可以哦~ 注意: 返回结果如果是 实体类类型,尽量类属性名 与数据库列名一致,不然会很麻烦哦~ resultMap 命名引用外部的resultMap flushCache 将其设置为true,不论语句什么时候被调用,都会导致缓存被清空。默认值:false useCache 将其设置为true,将会导致本条语句的结果被缓存。默认值:true timeout 这个设置驱动程序等待数据库返回请求结果,并抛出异常时间的最大等待值。默认不设置(驱动自行处理) fetchSize 这是暗示驱动程序每次批量返回的结果行数 …
  • resultMap 上面查询结果类型是 User类型, 但如果数据库列名与实体类的属性名, 不一致,MyBatis 文件映射不出来:而可以通过SQL 语句查询,列起别名形式进行, 改正: 但还是不好,而且 两表连接查询时候, Java一般会在实体类中存在另一个类型对象…这个怎么解决呢~ eg: 查看用户及用户的部门信息… 用户表/部门表; 而两表连接需要存部门的信息; 用户有部门属性,所以一般实体类 会放一个部门类的对象… 这就可以使用 resultMap常用属性 id 唯一标识,id 值用于select元素 resuMap的引用; type 表示resultMap的映射结果; id 标签 子节点:< id property="属性名“ column=”主键列名“ /> 一般一个resultMap 只有一个表示查询的主键列,提高程序效率; 如果需要查询多个数据时, !不然你永远只会查到一条数据!吃过亏的我...可别学我 至于为啥:resultMap中如果不定义类似主键之类的能够区分每一条结果集的字段的话,会引起后面一条数据覆盖前面一条数据的现象。 result: 子节点:用于标识属性,< result property="属性名“ column=”列名“ /> 如果查询时候有些属性应该有值,结果却是 null 就是没有映射上!或 映射级别过低… assoction 子节点: A表 B表, 两表连接… A类存在B类型对象属性; 就需要使用 assoction 进行映射; assoction 处理 ”一对一“ 的关联关系; w是人事部 s是技术部… property:表示在A类中的属性名; javaType : 表示该属性的类名; … collection 同 assoction 类似, assoction表示 一对一, 而 collection 则表示 一对多; 即:查询人事部的所有员工; Java的部门类中就需要一个用户集合… 关于映射级别 可以在MyBatis-config.xml 中 < setting name=“auto<appMappingBehavior” value=“PARTIAL” /> NONE : 禁止自动映射; PARTIAL : 默认值,允许自动映射; 但 collection/assoction 子元素中,无法自动映射;——级别不够 FULL :更高级的映射, 允许 collection/assoction 子元素中自动映射;

最后,最后 还要注意的是: 数据库列一定要和实体类类对应!

sql语句多表查看不要出现相同的列名(这个问题不大) ,实体类的数据类型 要注意! 与数据库的值可以匹配的:

Error getting nested result map values for 'sort'. Cause: java.sql.SQLException: Invalid value for getInt() - '鏂囧叿'

中:获取“sort”的嵌套结果映射值时出错。 无效的值 getInt() '鏂囧叿'————这是我报的错真的是坑死了!实体类是 int 数据库是 字符串!!!

一定注意!

SQL映射 UserMapper.xml

代码语言:javascript
复制
	 <!-- 面向接口 -->
	 <!-- 
 		resultMap元素属性和子节点: 
 			id:		唯一标识,此ID 用于select元素 resultMap 属性的引用;
 			type:	表示resultMap 映射的类型;
 			result: 子节点 property类属性  column库列名 进行一一对应,解决了名字不匹配问题;
 		
 		resultMap 与 resultType 的关联:
 	 		resultType:	直接表示返回结果类型,包括基本数据类型 和 复杂数据类型;
 	 		resultMap:	则是对外部 resultMap 定义的引用,它的场景一般是 数据库字段与实体类属性名不一致使用; 或 两表连接A类存在B类型对象;
 	 		关联:		MyBatis进行查询映射时候,其实查询出来的字段值都放在一个对应的Map里面,key字段名 value值;
 	 					select 设置 resultType 时,返回结果也是Map 结构,而底层将 Map的值取出来进行 resultType类型的 setter(xx);进行赋值了;  所以需要get/set!别忘了哦! 
 	 					resultType  resultMap 本质上都是 Map 数据结构, 两者不可以同时在一个 select 中使用哦~;
 	 -->
	<resultMap type="User" id="userMap">
		<!-- property类属性  column库列名 MyBatis也会对 数据库/实体列 相同的进行一一映射,不一致的就需要手动进行映射了;  -->
		<id property="id" column="id"  />
 		<result property="userCode" column="userCode" />  
 		<!-- ...还好我这儿与数据库都一样就不需要一一映射了 -->
 		<association property="role" javaType="Role"  >
 		<!-- <result property="xxx" column="xxx" /> -->
 		<!--  ...还好我这儿与数据库都一样 且MyBatis: setting 设置 autoMappingBehavior 属性级别 FULL  就不需要一一映射了 -->
 		</association>
 	</resultMap>
	<!--MyBatis-config.xml setting 设置resultMap的自动映射级别,NONE(禁止自动匹配),PARTIAL(默认)自动匹配所有属性,有内部嵌套(association、collection)的除外,FULL(自动匹配所有属性) -->

	<!-- 面向接口形式, id 要与接口的方法名相同; -->
	<!-- 接口参数使用了 Java注解所以,映射文件这里就不需要,parameterType参数类型了, #{注解名} 找到对应注解值; -->
	<select id="login" resultMap="userMap"  >
 		SELECT su.*,sr.`roleName` FROM `smbms_user` su ,`smbms_role` sr WHERE su.`userRole` = sr.`id` AND su.`userName`= #{name} AND su.`userPassword` = #{pwd}
 	</select>

Java接口: UserMapper.Java

@Param 注解实现多参数

// 有时候, 参数需要很多可以使用 parameterType 的 Map Java实体类 但还是比较麻烦~ 还可使用Java 注解来解决…

// 只需要在定义接口时候在参数列表,需要的参数使用:@Param(" sql中使用的name ")参数类型 参数名 即可;

代码语言:javascript
复制
public interface UserMapper {
	//登录方法,根据用户名/密码用户登录,并显示用户部门名称.. 两表连接.. assoction;
	public User login(@Param("name")String name,@Param("pwd")String pwd);  //使用了: 注解形式传参;
}

注意

mybatis传单个类型参数,可以不用@param注解,前提是xml中不含有 条件表达式(when,if..动态标签中没有引用到该参数) 大忌!!

映射文件代码片段~

代码语言:javascript
复制
<!-- 动态SQl 后面文章有详细讲解~ -->
<!-- 单个参数如果参数不加 @param if/where/..中是无法使用的..大忌!(当时找了好久~) -->
<if test="w !=null and w != ''">
 	<!-- 通过 #{w} 方式引入单个参数的值,拼接动态SQL -->
</if>

运行类 Run.Java

代码语言:javascript
复制
	public User login(String name,String pwd){
		SqlSession session = MyBatisUtil.createSqlSession();
		UserMapper um = session.getMapper(UserMapper.class);
		User u = um.login(name, pwd);
		MyBatisUtil.closeSqlSession(session);
		return u;
	}
在这里插入图片描述
在这里插入图片描述
  • collection 一对多; 根据部门ID查部门,及其所有员工 SQL映射 RoleMapper.xml
代码语言:javascript
复制
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/> <!-- 二级缓存 -->
	<!-- 
		eviction		:文件的保存形式;
		flushInterval	:缓存对象的毫秒数;
		size			:缓存对象的个数; 先进先出原则,如果已经满了,则最先进的移除,添加新的
		readOnly		: 只读
	 -->
	
	<resultMap type="Role" id="RoleMap">
 		<result property="id" column="id" />  
 		<collection property="users" ofType="User"  >
 			<!--  ...还好我这儿与数据库都一样 且MyBatis: setting 设置 autoMappingBehavior 属性级别 FULL  就不需要一一映射了 -->
 		</collection>
 	</resultMap>
 	
	<select id="cha" resultMap="RoleMap" useCache="true" >
	SELECT rs.*,us.`userName` FROM `smbms_role` rs ,`smbms_user` us WHERE rs.`id` = us.`userRole` AND rs.`id`=#{id};
	</select>

Java接口 RoleMapper.Java

代码语言:javascript
复制
	//根据部门id查看部门信息,及该部门的所有员工
	public Role cha(@Param("id")int id);

运行类 Run.Java

代码语言:javascript
复制
		//根据编号查部门及 部门员工;
		public void bmcha(){
			SqlSession session = MyBatisUtil.createSqlSession();
			RoleMapper rm = session.getMapper(RoleMapper.class);
			//一级缓存:缓存数据存储在 sqlSession中;
			Role r = rm.cha(1);
			System.out.println(r.getRoleName()+"\t"+r.getId());
			List<User> u = r.getUsers();
			for (User user : u) {
				System.out.println(user.getUserName());
			}
			MyBatisUtil.closeSqlSession(session); 
		}
  • insert insert完成新增操作; 增 删 改 : 会对数据库造成影响, 属于事务. 所以在 MyBatisUtil 类中 SqlSessionFactory.openSession(false); // 参数false表是开启事务控制,不传参数表示默认为true(为自动提交事务) 如果是false 则记住需要手动提交事务哦, 不然数据不会改变哦; 常用属性 id 同上 parameterType同上 //一般只有查询,有返回结果… 增 删 改 差不多都一致。。。

SQL映射 UserMapper.xml

代码语言:javascript
复制
<!-- 新增 -->
<!-- 面向接口形式, id 要与接口的方法名相同; -->
 	<insert id="xz" parameterType="User" >
 		INSERT into `smbms_user` values
		(null,#{userCode},#{userName},#{userPassword},1,'1983-10-10','13688889999','北京市东城区前门东大街9号',2,1,'2020-08-18 09:56:31',NULL,NULL);
 	</insert>

Java接口: UserMapper.Java

代码语言:javascript
复制
public interface UserMapper {
	//新增
	public int xz(User u);

运行类 Run.Java

代码语言:javascript
复制
public void addxz(){
		//新增的User 对象;
		User us = new User();
		us.setUserCode("WSM");
		us.setUserName("wangX");
		us.setUserPassword("540707");
		SqlSession session = MyBatisUtil.createSqlSession();
		int jg = 0;
		try {
		//采用面向接口方法
		//sqlSession.getMapper(接口类.Class);   前提是映射文件命名空间指向接口的地址;
		// 且映射文件对应的ID名要 和 接口的方法名相同;
		// Mybatis 底层实现了UserMapper接口,并返回了对应实例,方便调用起对应方法;
		// 好处,不用在在意 SqlSession 的增删改查的方法: selectone(); insert();...方法了; 可以根据,自定义的方法来实现 "增删改查..操作";
		UserMapper um = session.getMapper(UserMapper.class);
		//返回影响行数
		jg = um.xz(us); 
		session.commit();  //手动提交事务
		// 注意增删改查操作; 需要提交,虽然数据库进行了新增,但是事务还没结束,根据事务原子性; 成功/失败; 
		} catch (Exception e) {
			e.printStackTrace();
			session.rollback();  //出现异常,事务回滚; 
		}finally{
			MyBatisUtil.closeSqlSession(session);
			if(jg==1){
				System.out.println("新增成功");
			}else{
				System.out.println("新增失败");
			}
		}
	};
  • Update Update完成修改操作;

SQL映射 UserMapper.xml

代码语言:javascript
复制
<!-- 修改 -->
 	<update id="xiugai"  >
 		UPDATE `smbms_user` SET `userName` =#{name} WHERE `id` =#{id}
 	</update>

Java接口: UserMapper.Java

代码语言:javascript
复制
	//修改 根据角色ID 修改角色姓名;
	public int xiugai(@Param("id")int id,@Param("name")String name);

运行类 Run.Java

代码语言:javascript
复制
	public void upd(){
		System.out.println("请输入要修改用户id");
		int id = input.nextInt();
		System.out.println("请输入修改后用户name");
		String name = input.next();
		SqlSession session = MyBatisUtil.createSqlSession();
		try {
			UserMapper um = session.getMapper(UserMapper.class);
			if(um.xiugai(id, name)==1){
				session.commit();  //成功提交事务
				System.out.println("成功");
			}else{
				System.out.println("失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
			session.rollback();
		}finally{
			MyBatisUtil.closeSqlSession(session);
			
		}
	}
  • delete 完成删除操作

SQL映射 UserMapper.xml

代码语言:javascript
复制
<!-- 删除 -->
 	<delete id="del" parameterType="int"  >
 		DELETE FROM `smbms_user`  WHERE id=#{del}  <!-- 参数只有一个可以随意一点了.. -->
 	</delete>

Java接口: UserMapper.Java

代码语言:javascript
复制
	//删除 根据角色Id 删除;
	public int del(int id);

运行类 Run.Java

代码语言:javascript
复制
	public void del(){
		System.out.println("请输入要删除ID");
		int id = input.nextInt();
		SqlSession session = MyBatisUtil.createSqlSession();
		try {
			UserMapper um = session.getMapper(UserMapper.class);
			if(um.del(id)==1){
				session.commit();  //成功提交事务
				System.out.println("成功");
			}else{
				System.out.println("失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
			session.rollback();
		}finally{
			MyBatisUtil.closeSqlSession(session);
			
		}
	}

这里只是笔记,属性详情,关键还是要多练 ——实例代码 MyBatisDemo

加油!奥利硕!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-08-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Sql文件映射
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档