栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java - Mybatis 框架详解(二)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java - Mybatis 框架详解(二)

目录
      • 1. 将id=?的数据的电子邮箱改为?
      • 2. 动态SQL--foreach
      • 3. 动态SQL--if
      • 4. 关于#{}和${}占位符
      • 5. 使用自定义别名解决名称不匹配的查询问题
      • 6. 使用解决查询时名称不匹配的问题
      • 7. 简单的关联表查询
      • 8. 练习

1. 将id=?的数据的电子邮箱改为?

在UserMapper接口中添加抽象方法:

Integer updateEmailById(
	@Param("id") Integer id, 
	@Param("email") String email
);

如果抽象方法的参数的数量超过1个,应该在每个参数之前添加@Param注解,并在注解中配置参数的名称,后续在配置SQL语句时,使用的#{}占位符中也需要写注解中配置的名称!

在SomeMapper.xml中添加配置:


	UPDATE t_user SET email=#{email} WHERe id=#{id}

在配置SQL时,如果抽象方法的参数只有1个,则在 #{} 占位符中写任意名称均可,因为框架会找唯一的那个参数!如果抽象方法的参数有多个(超过1个),由于.java文件在编译成.class文件时会丢失局部变量(参数也是一种局部变量)名称,所以,在#{}占位符中写参数名称是没有意义的,框架在执行时无法区分,可以使用#{arg0}表示第1个参数,使用#{arg1}表示第2个参数,以此类推,或者,使用#{param1}表示第1个参数,使用#{param2}表示第2个参数,以此类推……这样的做法虽然能解决问题,但是,SQL语句的代码的可读性就非常差,当抽象方法的参数都添加了@Param注解时,在SQL语句中就可以使用注解中配置的名称,以增加代码的可读性!

完成后,可以在Tests中编写单元测试:

@Test
public void updateEmailById() {
	Integer id = 1;
	String email = "u1@163.com";
	Integer rows = userMapper.updateEmailById(id, email);
	System.out.println("rows=" + rows);
}
2. 动态SQL–foreach

动态SQL:在配置SQL语句时,可以添加例如等节点,实现在SQL语句中的动态生成效果,例如使用时,就可以对参数进行判断,最终可能生成不同的SQL语句,使用对参数进行遍历,根据参数不同,生成的SQL语句也会不一样,这种机制就称之为“动态SQL”。

例如存在“一次性删除若干条数据”的需求,到底要删除多少条数据,这些数据的id分别是多少,对于开发人员来说是未知的!则SQL语句就是无法确定的!就需要使用动态SQL中的foreach的做法!即要求用户提供若干个id的集合,然后遍历该集合,形成SQL语句中where id in ()括号中的若干个问号!

首先,还是应该在UserMapper接口中添加抽象方法:

Integer deleteByIds(List ids);

	DELETE FROM t_user WHERe id IN
	
		#{id}
	

参数需要表示若干个id值,可以使用List集合,也可以使用数组,或者声明为可变参数(在处理过程中,等同于数组)。

然后,在SomeMapper.xml中添加配置:

在配置节点时,相关属性的配置:

  • collection:被遍历的参数对象。当抽象方法的参数只有1个,没有添加@Param注解时,当对象是List集合类型时,取值为list,当对象是数组类型时,取值为array;当抽象方法的参数有多个,并且添加了@Param注解时,该属性的值就是注解中定义的名称;

  • item:在遍历过程中,被遍历到的数据的名称,是自定义的,等同于for (Integer id : ids)中的id,并且,在子级的文本中使用#{}占位符时,使用的名称就是该item属性的值;

  • separator:分隔符,生成遍历结果时,每个数据之间的分隔符,即若干个id值之间的逗号;

  • open与close:遍历生成的SQL语句部分的最左侧和最右侧的字符串。

3. 动态SQL–if

在配置SQL时,可以使用对参数进行判断,例如:


	SELECT 
		id, username, 
		password, age,
		phone, email,
		is_delete AS isDelete
	FROM 
		t_user 
	ORDER BY 
		id

6. 使用解决查询时名称不匹配的问题

区分3个名词:

字段名(Field):创建数据表时指定的各字段的名称;

列名(Column):查询结果的表格中每项数据上方的名称,默认情况下,列名就是字段名,当然,也可以在查询时指定别名,则列名就是别名;

属性名(Property):类中定义的全局变量的名称;

如果查询结果的列名与封装结果的属性名不一致,且不指定别名,还可以通过配置来解决!

配置节点的目的就是指导MyBatis框架,如何将查询结果中的数据封装到返回的对象中!

配置代码如下:



	
	
	
	
	
	
	
	

配置完成后,在 SELECT * FROM t_user ORDER BY id

类似以上这种单表的数据查询中,如果查询结果的列名与类中的属性名是完全相同的,其实可以不必配置,所以,以上可以简化为:


	

另外,除了使用节点配置对应关系以外,还可以使用节点进行配置,只不过,节点应该只用于配置主键字段!例如配置为:


	
	

从查询结果看来,使用这2种节点的配置效果完全相同,但是,使用配置有利于MyBatis框架实现数据缓存!推荐将主键使用来配置!

7. 简单的关联表查询

创建t_department部门信息表:

CREATE TABLE t_department (
	id INT AUTO_INCREMENT COMMENT '部门id',
	name VARCHAR(20) NOT NULL COMMENT'部门名称',
	PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;

然后,还应该在项目中创建Department类:

public class Department {
	private Integer id;
	private String name;
	// SET/GET/toString
}

如果要使得用户数据与以上部门的数据产生关联,还应该先在用户数据表中添加“用户所归属的部门”字段:

ALTER TABLE t_user ADD COLUMN department_id INT;

修改了用户数据表,则应该在User类中也补充添加相应的字段:

private Integer departmentId;

然后,在2张中调整一下测试数据:

INSERT INTO t_department (name) VALUES ('软件研发部'), ('人力资源部'), ('财务部');

UPDATE t_user SET department_id=1 WHERe id IN (1,8,15);
UPDATE t_user SET department_id=2 WHERe id IN (4,11,14);
UPDATE t_user SET department_id=3 WHERe id IN (9,10,13);

假设存在需求:查询某个用户的信息,并显示该用户归属的部门的名称。

需要执行的SQL语句大致大致是:

select 
	t_user.id, username,
	password, age,
	phone, email,
	is_delete, department_id,
	name 
from 
	t_user 
left join 
	t_department 
on 
	t_user.department_id=t_department.id 
where 
	t_user.id=?

与数据表相对应的是实体类(Entity),当涉及关联表查询时,必然没有任何一个实体类可以封装查询结果,则需要自定义新的**VO类(Value Object)**来封装查询结果!这种类与实体类只是定位不同,它是与查询结果对应的,或者是根据查询结果来定制的,编码方式几乎一致!

所以,需要先创建VO类,表示此次的查询结果:

public class UserVO {
	private Integer id;
	private String username;
	private String password;
	private Integer age;
	private String phone;
	private String email;
	private Integer isDelete;
	private Integer departmentId;
	private String departmentName;
}

在UserMapper接口中定义抽象方法:

UserVO findVOById(Integer id);

然后SomeMapper.xml中配置以上方法对应的SQL语句:


8. 练习

创建DepartmentMapper接口,用于定义管理部门数据的抽象方法;

将SomeMapper.xml重命名为UserMapper.xml;

将UserMapper.xml复制得到DepartmentMapper.xml,并清空其中的配置,该DepartmentMapper.xml将用于配置管理部门数据的SQL语句;

通过MyBatis框架实现以下功能:

  1. 增加新的部门;

  2. 修改部门的名称;

  3. 根据某个id删除部门;

  4. 批量删除部门;

  5. 查询部门列表;

  6. 根据某个id查询部门。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/344793.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号