全部章节   >>>>


本章目录

2.1 标签

2.1.1 标签简单应用

2.1.2 使用JDBC方式返回主键自增的值

2.1.3 使用标签返回普通主键的值

2.1.4 实践练习

2.2 标签和标签

2.2.1 标签用法

2.2.2 标签用法

2.2.3 删除具有主从关系的主表记录

2.2.4 实践练习

2.3 映射器方法多参数传递

2.3.1 MyBatis默认参数位置

2.3.2 使用Map类型作封装参数

2.3.3 使用注解类型作为参数

2.3.4 实践练习

2.4 MyBatis注解映射

2.4.1 MyBatis注解的基本用法

2.4.2 @Insert注解

2.4.3 @Update注解

2.4.4 @Delete注解

2.4.5 @Provider注解

2.4.4 实践练习

总结:


2.1 <insert>标签

2.1.1 <insert>标签简单应用

在Mybatis中的映射Mappe.xml中,可以使用<insert>标签实现增加数据。

<insert>标签常见属性如下:

属性名

作用

id

对应接口中声明的增加方法名

parameterType

对应增加方法接收参数类型

flushCache

只要语句被调用,都会清空一级缓存和二级缓存

useGeneratedKeys

使用JDBC的getGeneratedKeys()方法取出由数据库生成的主键

keyProperty

通过getGeneratedKeys获取主键值后将要赋值的属性名

MyBatis<insert>标签实现增加功能步骤如下:

1、在接口中声明增加的抽象方法

2、在接口对应Mapper.xml中添加insert标签映射

示例:1、在UserMapper接口中增加一个抽象方法,代表具有增加数据功能

// 返回新增用户的记录数(影响的行数)
int addUser(SysUser user);

SysUser user接收实体对象,封装了要添加的数据

示例:2、在UserMapper.xml中添加该方法对应的sql语句映射: 使用<insert>标签定义增加sql语句

<insert id="addUser">
insert into sys_user(id,user_name,user_password,user_email,
user_info,head_img,create_time)
values(#{id},#{userName},#{userPassword},#{userEmail},
#{userInfo},#{headImg,jdbcType=BLOB},#{createTime,jdbcType=TIMESTAMP})
</insert>

id为方法名

#号代表取实体对象中的属性名

特殊类型使用jdbcType说明

示例:3、测试类实现方法调用:

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 创建一个SysUser对象
SysUser user = new SysUser();
user.setUserName("test1");
//设置user对象其他属性
// 正常情况下应该读入一张图片存到byte数组中,这里模拟字节数据
user.setHeadImg(new byte[] {1,2,3});
user.setCreateTime(new Date());
// 新增user对象到数据库中,result是执行SQL影响的行数
int result = userMapper.addUser(user);
// 提交事务,否则新增(更新)数据只存在于SqlSession中,会随着程序的关闭而消失
sqlSession.commit();
System.out.println("新增了"+result+"个用户"+",该用户的id="+user.getId());

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);  获取接口代理对象

2.1.2 使用JDBC方式返回主键自增的值

在使用主键自增(例如,MySQL、SQL Server数据库)时,插入数据库后可能需要得到自增的主键值,然后使用这个值进行一些其他的操作。

新增addUser2方法,修改映射Xml文件,增加属性如下:

<insert id="addUser2" useGeneratedKeys="true" keyProperty="id">
insert into sys_user(user_name,user_password,user_email,user_info,head_img,create_time)
values(#{userName},#{userPassword},#{userEmail},#{userInfo},#{headImg,jdbcType=BLOB},
#{createTime,jdbcType=TIMESTAMP})
</insert>

得到生成的主键并且赋予对象的id属性

示例: 再次运行测试类实现方法调用:

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 创建一个SysUser对象
SysUser user = new SysUser();
user.setUserName("test1");
//设置user对象其他属性
// 正常情况下应该读入一张图片存到byte数组中,这里模拟字节数据
user.setHeadImg(new byte[] {1,2,3});
user.setCreateTime(new Date());
// 新增user对象到数据库中,result是执行SQL影响的行数
int result = userMapper.addUser2(user);
// 提交事务,否则新增(更新)数据只存在于SqlSession中,会随着程序的关闭而消失
sqlSession.commit();
System.out.println("新增了"+result+"个用户"+",该用户的id="+user.getId());

addUser方法和addUser2方法接口声明一样,但是在Xml映射中,addUser2添加了useGeneratedKeys和keyProperty属性。

useGeneratedKeys会调用JDBC的getGeneratedKeys()方法取出生成的主键。  keyProperty将主键值赋予对象的id属性。

2.1.3 使用<selectKey>标签返回普通主键的值

useGeneratedKeys 用于获取自增的主键值,而有些数据库使用时并未使用自增功能,如Oracle使用序列等。

<selectKey> 标签来获取主键的值,这种方式对于是否提供主键自增功能的数据库均适用:

// 新增用户,使用selectKey方式
int addUser3(SysUser user);

修改UserMapper.xml对应的addUser3接口方法映射:

<insert id="addUser3">
insert into sys_user(user_name,user_password,user_email,user_info,head_img,create_time)
values(#{userName},#{userPassword},#{userEmail},#{userInfo},
#{headImg,jdbcType=BLOB},#{createTime,jdbcType=TIMESTAMP}) <selectKey keyColumn="id" resultType="long" keyProperty="id" order="AFTER">
select last_insert_id()
</selectKey>
</insert>

2.1.4 实践练习

2.2 <update>标签和<delete>标签

2.2.1 <update>标签用法

在MyBatis的Mapper.xml映射文件中,定义<update>标签用于对数据进行单个或批量更新,实现步骤如下:

示例:

1、在UserMapper接口中添加updateUser(SysUser user)方法:

UserMapper.xml中定义与之对应的SQL和配置

<update id="updateUser">
update sys_user set user_name=#{userName},user_password=#{userPassword},
user_email=#{userEmail},user_info=#{userInfo},head_img=#{headImg,jdbcType=BLOB},
create_time=#{createTime,jdbcType=TIMESTAMP} where id=#{id}
</update>

2、添加测试调用修改方法:

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取一个SysUser对象
SysUser user = userMapper.selectById(1L);
// 修改SysUser对象信息
user.setUserName("admin2");
user.setUserEmail("admin2@mybatis.jack");
int result = userMapper.updateUser(user);
sqlSession.commit();
System.out.println("更新了"+result+"个用户信息");

2.2.2 <delete>标签用法

MyBatis的Mapper.xml中,定义<delete>标签用于对数据进行单个或批量更新。

示例:

1、在UserMapper接口中添加deleteUserById(Long id)方法,如下

<delete id="deleteUserById">
delete from sys_user where id=#{id}
</delete>

2、添加测试调用删除方法:

Long userId =15L; // 欲删除用户id
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
int result = userMapper.deleteUserById(userId);
sqlSession.commit();
System.out.println("删除了"+result+"个用户");

2.2.3 删除具有主从关系的主表记录

实际应用中,为了保证数据的合理性,经常会创建外键和其他表主键进行关联约束,这时当我们删除主表记录时,如有数据约束,则会报错。

解决方案是设置从表的“删除时”规则为“置为NULL”或“级联”删除。

示例:

1、级联为例删除有角色关联的用户记录(先删除角色关联信息)

// 删除指定用户id的用户角色关联记录,返回受影响的行数

int deleteUserRolesByUserId(Long userId);

新定义一个UserRoleMapper.java接口

创建接口对应的UserRoleMapper.xml,增加删除配置,如下:

<delete id="deleteUserRolesByUserId" >
delete from sys_user_role where user_id=#{userId}
</delete>

2、添加测试调用删除有角色关联用户的方法:

Long userId =16L; // 欲删除用户id
UserRoleMapper userRoleMapper = sqlSession.getMapper(UserRoleMapper.class);
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 删除从表用户角色关联记录
int cnt1 = userRoleMapper.deleteUserRolesByUserId(userId);
// 删除主表用户记录
int cnt2 = userMapper.deleteUserById(userId);
sqlSession.commit();
System.out.println("删除了"+cnt1+"条用户角色关联记录,删除了"+cnt2+"条员工记录");

2.2.4 实践练习

2.3 映射器方法多参数传递

2.3.1 MyBatis默认参数位置

目前案例接口中方法的参数只有一个,参数的类型可以分为两种,一种是基本类型,另一种是JavaBean。

在实际应用中经常会遇到使用多个参数的情况,可以将多个参数合并到一个JavaBean中,并使用这个JavaBean作为接口方法的参数,但是不适合于全部情况。

示例:

1、根据用户id和角色的enabled状态获取角色列表

// 在UserMappr接口中添加根据用户id和角色enabled状态获取用户的角色
List<SysRole> selectRolesByUserIdAndRoleEnabled(Long userId, Integer enabled);
// 在UserMappr.xml中添加根据用户id和角色enabled状态获取用户的角色
<select id="selectRolesByUserIdAndRoleEnabled" resultType="SysRole">
select r.id,r.role_name,r.enabled,r.create_by,r.create_time
from sys_role r join sys_user_role ur on r.id=ur.role_id join sys_user u
on u.id=ur.user_id where u.id=#{userId} and r.enabled=#{enabled}
</select>

2、添加测试调用查询方法:

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<SysRole> roles = userMapper.selectRolesByUserIdAndRoleEnabled(1L, 1);
for (SysRole role : roles) {
System.out.println("角色名:"+role.getRoleName()+",enabled:"+role.getEnabled());
}

这里运行报错,原因是无法识别多个参数

Mybatis映射器XML对于多个参数,默认情况下只识别arg0、arg1、paraml和param2这种内部定义的名称,

所以将参数名定义为#{arg0}和#{arg1}或者#{param1}和#{param2}即可解决错误,如下:

<select id="selectRolesByUserIdAndRoleEnabled" resultType="SysRole">
select r.id,r.role_name,r.enabled,r.create_by,r.create_time from sys_role r join sys_user_role ur on r.id=ur.role_id join sys_user u on u.id=ur.user_id where u.id=#{param1} and r.enabled=#{param2}
</select>

u.id=#{param1} and r.enabled=#{param2}  这里参数名换成mybatis内部定义的

2.3.2 使用Map类型作封装参数

Map是键+值对形式数据格式集合,也可以解决多参数问题,通过key来映射Mapper.xml中SQL使用的参数名字,value用来存放参数值,需要多个参数时,通过Map的key-value方式来传递参数值,如下:

示例:

1、根据用户id和角色的状态(enabled字段)获取角色列表

将多个参数以Map形式封装传递

List<SysRole> selectRolesByUserIdAndRoleEnabledByMap(Map<String,Object> params);

Mybatis能够识别map中的key

<select id="selectRolesByUserIdAndRoleEnabledByMap" resultType="SysRole">
select r.id,r.role_name,r.enabled,r.create_by,r.create_time
from sys_role r join sys_user_role ur on r.id=ur.role_id join sys_user u
on u.id=ur.user_id where u.id=#{userId} and r.enabled=#{enabled}
</select>

2、添加测试调用map传递参数的查询:

	UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
Map<String, Object> paramsMap = new HashMap<String, Object>();
paramsMap.put("userId", 1L);
paramsMap.put("enabled", 1);
List<SysRole> roles = userMapper.selectRolesByUserIdAndRoleEnabledByMap(paramsMap);
for (SysRole role : roles) {
System.out.println("角色名:"+role.getRoleName()+",enabled:"+role.getEnabled());
}

创建Map对象,将传递的参数进行封装

传入map对象进行方法调用

2.3.3 使用注解类型作为参数

MyBatis还提供了对Mapper接口方法多个参数进行注解说明

参数前使用@Param(“参数名”)进行修饰:

示例:

1、根据用户id和角色的enabled状态获取角色列表

使用@Param注解进行参数名修饰说明

List<SysRole> selectRolesByUserIdAndRoleEnabledByAnnotation(@Param("userId")Long userId,
@Param("enabled")Integer enabled);

直接对应@Param修饰后的名称即可

<select id=" selectRolesByUserIdAndRoleEnabledByAnnotation" resultType="SysRole">
select r.id,r.role_name,r.enabled,r.create_by,r.create_time
from sys_role r join sys_user_role ur on r.id=ur.role_id join sys_user u
on u.id=ur.user_id where u.id=#{userId} and r.enabled=#{enabled}
</select>

如果映射器中的方法定义有多个参数,可以通过Map的key-value方式传递参数值来解决,但由于这种方式还需要自己手动创建Map以及对参数进行赋值,使用起来并不简洁,所以推荐使用@Param注解的方式来传递映射器中方法的多参数。

2.3.4 实践练习

2.4 MyBatis注解映射

2.4.1 MyBatis注解的基本用法

为了提高开发效率,MyBatis提供了另外一种注解的方式来实现接口方法的映射。

MyBatis注解方式就是将SQL语句直接写在接口方法上,常用包含@Select、@Insert、@Update、@Delete和@Provider五种,分别对应CRUD操作。

@Select(“select * from 用户表名”)
public List<User> selectUsrs();

对于需求比较简单的系统,其效率较高。缺点是当SQL有变化时,需要重新编译代码。一般情况下不建议使用注解方式

@Select注解用于查询数据

示例:

1、在RoleMapper中实现根据角色id查询角色信息对象

@Select("select id, role_name roleName, enabled, create_by createBy, "+
"create_time createTime from sys_role where id =#{id}")
SysRole selectRoleById1(Long roleId);

就是将以前写在Xml中的配置拿到了接口中

@Select注解查询时,默认情况下需要保证表中的列和实体中的属性名一致,如果存在表中下划线,而类中是驼峰命名时可以通过以下方式解决:

1、在主配置中开启驼峰命名设置

2、在@Select注解时使用 @Results注解进行说明,类似resultMap标签

@Results({
@Result(property="id",column="id",id=true),
@Result(property="roleName",column="role_name"),
@Result(property="enabled",column="enabled"),
@Result(property="createBy",column="create_by"),
@Result(property="createTime",column="create_time")
})
@Select("select id, role_name, enabled, create_by, create_time "
+ "from sys_role where id =#{id}")
SysRole selectRoleById2(Long roleId);

2.4.2 @Insert注解

@Insert注解用于新增数据

示例:

1、在RoleMapper中实现新增角色信息

@Insert("insert into sys_role(id,role_name,enabled,create_by,create_time) "
+ "values(#{id},#{roleName},#{enabled},#{createBy},"
+ "#{createTime,jdbcType=TIMESTAMP})")
int addRole(SysRole role);

就是将以前写在Xml中的sql配置拿到了接口中

2、在RoleMapper中实现新增角色信息,并且获取自增主键值

@Insert("insert into sys_role(role_name,enabled,create_by,create_time) "
+ "values(#{roleName},#{enabled},#{createBy},"
+ "#{createTime,jdbcType=TIMESTAMP})")
@Options(useGeneratedKeys=true, keyProperty="id")
int addRole2(SysRole role);

声明获取返回自增主键值,放入id属性中

2.4.3 @Update注解

@Update注解用于修改数据

示例:

1、使用注解修改角色信息,接收角色对象,返回影响行数

@Update("update sys_role set role_name=#{roleName}, enabled=#{enabled}, "
+ "create_by=#{createBy}, create_time=#{createTime,jdbcType=TIMESTAMP} where id=#{id}")
int updateRole2(SysRole role);

2.4.4 @Delete注解

@Delete注解用于删除数据

示例:

1、使用注解删除角色信息

@Delete("delete from sys_role where id=#{id}")
int deleteRoleById2(Long id);

2.4.5 @Provider注解

当SQL语句需要添加条件或过于复杂时,普通CRUD注解无法满足,需要使用Provider注解应对复杂的SQL处理,包括了以下几种:

@SelectProvider

@InsertProvider

@UpdateProvider

@DeleteProvider

几种注解用法一致,主要用于配合对应注解产生复杂的Sql语句时使用

示例:

使用@SelectProvider实现权限信息复杂查询

public interface PrivilegeMapper {

@SelectProvider(type=PrivilegeProvider.class, method="selectPrivilegeById2")
SysPrivilege selectPrivilegeById2(Long id);
}
public class PrivilegeProvider {
public String selectPrivilegeById2(final Long id) {
return new SQL() {
{
SELECT("id, privilege_name, privilege_url");
FROM("sys_privilege");
WHERE("id=#{id}");
}
}.toString();
}
}

2.4.4 实践练习

总结:

  • MyBatis数据库操作时,需要先建立一个操作接口,声明操作的抽象方法,然后针对接口建立Mapper.xml映射文件,使用<insert><update><delete><select>标签分别完成对应方法Sql语句和参数、返回结果的配置。
  • <insert>标签完成增加映射时,可以使用useGeneratedKeys、keyProperty获取主键自增产生的值,也可以使用<selectKey>的方式获取。
  • 接口中方法如果接收多个参数时,可以采用默认参数名匹配,或者使用Map对参数进行封装,也可以使用@Param注解对参数进行修饰。
  • 对于简单的系统操作,可以直接在接口方法上使用@Select、@Insert、@Update、@Delete注解完成Sql语句匹配,提高开发效率。

Java EE数据持久化框架 • 【第2章 MyBatis实现DML操作】的更多相关文章

  1. Java EE数据持久化框架笔记 • 【目录】

    章节 内容 实践练习 Java EE数据持久化框架作业目录(作业笔记) 第1章 Java EE数据持久化框架笔记 • [第1章 MyBatis入门] 第2章 Java EE数据持久化框架笔记 • [第 ...

  2. Java EE数据持久化框架作业目录(作业笔记)

    第1章 MyBatis入门>>> 1.1.4 在Eclipse中搭建MyBatis基本开发环境 1.2.5 使用MyBatis查询所有职员信息 1.3.3 获取id值为1的角色信息. ...

  3. Java EE数据持久化框架 • 【第5章 MyBatis代码生成器和缓存配置】

    全部章节   >>>> 本章目录 5.1 配置MyBatis Generator 5.1.1 MyBatis Generator介绍 5.1.2 MyBatis Generat ...

  4. Java EE数据持久化框架 • 【第1章 MyBatis入门】

    全部章节   >>>> 本章目录 1.1 初识MyBatis 1.1.1 持久化技术介绍 1.1.2 MyBatis简介 1.1.2 Mybatis优点 1.1.3 利用Mav ...

  5. Java EE数据持久化框架 • 【第6章 MyBatis插件开发】

    全部章节   >>>> 本章目录 6.1 MyBatis拦截器接口 6.1.1 MyBais拦截器接口介绍 6.1.2 MyBais拦截器签名介绍 6.1.3 实践练习 6.2 ...

  6. Java EE数据持久化框架 • 【第4章 MyBatis动态SQL】

    全部章节   >>>> 本章目录 4.1 MyBatis动态标签 4.1.1  MyBatis动态标签介绍 4.1.2 < if >标签 4.1.3 update语 ...

  7. Java EE数据持久化框架 • 【第3章 MyBatis高级映射】

    全部章节   >>>> 本章目录 3.1 一对一映射 3.1.1 自动化一对一映射 3.1.2 标签配置一对一映射 3.1.3 标签配置一对一映射 3.1.4 实践练习 3.2 ...

  8. Java EE数据持久化框架mybatis练习——获取id值为1的角色信息。

    实现要求: 获取id值为1的角色信息. 实现思路: 创建角色表sys_role所对应的实体类sysRole. package entity; public class SysRole { privat ...

  9. Java EE互联网轻量级框架整合开发— SSM框架(中文版带书签)、原书代码

    Java EE互联网轻量级框架整合开发 第1部分 入门和技术基础 第1章 认识SSM框架和Redis 2 1.1 Spring框架 2 1.2 MyBatis简介 6 1.3 Spring MVC简介 ...

随机推荐

  1. Ecshop 后台管理员密码忘记了吧~!~!~!

    方法1:把下面的代码保存为文件 mima.php <?php define('IN_ECS', true); require(dirname(__FILE__) . '/includes/ini ...

  2. 【分布式】Zookeeper客户端基本的使用

    与mysql.redis等软件一样,zookeeper的软件包中也提供了客户端程序用于对服务器上的数据进行操作.本节我们就来学习zookeeper客户端的使用方法.不过在详细讲解zk客户端的使用方法之 ...

  3. Linux:find命令中

    默认情况下, find 每输出一个文件名, 后面都会接着输出一个换行符 ('\n'), 因此我们看到的 find 的输出都是一行一行的: ls -l total 0 -rw-r--r-- 1 root ...

  4. Shell脚本定期清空大于1G的日志文件

    一个关于如何在指定文件大于1GB后,自动删除的问题. 批处理代码如下: #!/bin/bash # 当/var/log/syslog大于1GB时 # 自动将其备份,并清空 # 注意这里awk的使用 i ...

  5. Spring boot 配置文件默认放置位置,和加载优先级

    一 .默认配置文件目录 spring boot 启动会扫描以下位置的application.properties 或者application.yml文件作为spring boot 的默认配置文件 ,加 ...

  6. 【.NET6】gRPC服务端和客户端开发案例,以及minimal API服务、gRPC服务和传统webapi服务的访问效率大对决

    前言:随着.Net6的发布,Minimal API成了当下受人追捧的角儿.而这之前,程序之间通信效率的王者也许可以算得上是gRPC了.那么以下咱们先通过开发一个gRPC服务的教程,然后顺势而为,再接着 ...

  7. Identity Server 4 从入门到落地(十一)—— Docker部署

    前面的部分: Identity Server 4 从入门到落地(一)-- 从IdentityServer4.Admin开始 Identity Server 4 从入门到落地(二)-- 理解授权码模式 ...

  8. Redis学习推荐资料合集

    目录 一.官方 二.书籍 三.推荐博客 一.官方 redis官网 redis中文网 redis中文命令网 redis模块 redis-github源码 redis报告 二.书籍 <Redis开发 ...

  9. 通过Docker部署Java项目的日志输出到宿主机指定目录

    之前写过2篇关于Docker部署的文章: 1.超!超!超简单,Linux安装Docker 2.Docker通过阿里云镜像仓库使用Gitlab_CI部署SpringBoot项目 用上篇博客部署Java程 ...

  10. bjdctf r2t3 onegadget

    没错,这就是一篇很水的随笔.... 两道很简单的题,先来看第一道.r2t3,保护检查了一下是只开启了堆栈不可执行. 简单看一下ida的伪代码. main函数让你输入一个name,然后会执行一个name ...