2.5 使用接口实现“增删改”操作
2.5.1 使用insert元素完成增加操作
MyBatis框架实现增加操作可使用insert元素来映射插入语句。下面通过示例来实现用户表增加操作的具体方法,先在UserMapper接口中增加add()方法:
其中插入的User对象作为入参,其返回值为int类型,即返回执行SQL影响的行数。
修改UserMapper.xml,增加插入语句,见示例36。
【示例36】 UserMapper.xml
其中insert元素的属性:
(1)id:与select元素的id一样,是命名空间中唯一的标识符,可以被用来引用这条语句。
(2)parameterType:与select元素的parameterType一样,是传入参数类型的完全限定名或别名。
对于“增删改”(insert、update、delete)这类数据库更新操作,需要注意以下两点。
(1)该类型的操作本身默认返回执行SQL影响的行数,所以DAO层的接口方法的返回值一般设置为int类型,最好不要返回boolean类型。
(2)insert、update、delete等元素中均没有resultType属性,只有查询操作需要对返回结果类型(resultType/resultMap)进行相应的指定。
接下来修改测试类UserMapperTest.java,增加testAdd()方法进行插入数据测试,并开启事务控制模拟异常,若发生异常则进入回滚,且测试事务,见示例37。
【示例37】 UserMapperTest.java
由于之前已经在MyBatisUtil中开启了事务控制:
那么在此处测试方法中,当SqlSession执行add()方法后就需要进行commit,完成数据的插入操作。若在执行过程中拋出了异常,那么就必须在catch中进行回滚,以此来保证数据的一致性,同时设置count为0。
2.5.2 使用update元素完成修改操作
MyBatis框架使用update元素来映射修改语句,其具体用法与insert类似,下面通过示例实现根据用户id修改用户信息的操作方法,先在UserMapper接口中增加modify()方法:
其中,要修改的User对象作为入参,返回值为im类型,即返回执行SQL影响的行数。修改UserMapper.xml,增加修改语句,见示例38。
【示例38】 UserMapper.xml
其中,update元素的属性id和parameterType的含义和用法等同于insert元素中的属性用法,此处不再赘述。另外,由于是修改操作,因此更新的字段只更新modifyBy和modifyDate,而不需要更新createBy和creationDate。
接下来修改测试类UserMapperTest.java,用增加testModify方法进行修改数据测试,并开启事务控制模拟异常,若发生异常则进入回滚,且测试事务,见示例39。
【示例39】 UserMapperTest.java
该测试方法与add的测试方法基本上一样,只不过需要调用modify()方法进行数据的修改,并且事务处理也与add的测试方法一样,此处不再赘述。
2.5.3 使用@Param注解实现多参数入参
除了根据用户id修改用户信息操作,百货中心供应链管理系统还有一个需求,即修改个人密码。此需求也是修改操作,但是可以传入的参数只有两个:用户id和新密码。若按照之前封装成User对象的方式进行传参,并不是很合适。然而,可以采用更灵活的方式处理,即直接进行多参数入参即可,代码可读性高,还可清晰地看出这个接口方法所需的参数。
修改UserMapper接口,以增加修改个人密码的方法,当方法参数有多个时,每个参数前都需增加@Param注解,具体示例代码如下:
使用@Param注解传入多个参数,如@Param("userPassword")String pwd,相当于将该参数pwd重命名为userPassword,在映射的SQL中需要使用#{注解名称},如#{userPassword}。
下面继续修改UserMapper.xml,增加id为updatePwd的SQL映射,见示例40。
【示例40】 UserMapper.xml
知识拓展:在上机练习4中,提出使用多参数入参的方式进行订单表的查询操作,若不使用@Param注解,则会报错,报错信息类似于Parameter '参数名' not found。探究原因,需要深入MyBatis源码,MyBatis的参数类型为Map,若使用@Param注解参数,那么就会记录指定的参数名为key;若在参数前没有加@Param注解,那么就会使用param+它的序号作为Map的key。故在进行多参数入参时,若没有使用@Param注解指定的参数,那么在映射的SQL语句中将获取不到#{参数名},从而报错。
最后修改测试类UserMapperTest.java,以增加testUpdatePwd方法进行个人密码修改测试,见示例41。
【示例41】 UserMapperTest.java
在该测试方法中,不需要再封装User对象,直接进行两个参数的入参即可,效果清晰明了。
经验:在MyBatis框架中的参数入参,何时需要封装成对象入参,何时又需要使用多参数入参?
一般情况下,超过4个以上的参数最好封装成对象入参(特别是在常规的增加和修改操作时,由于字段较多,封装成对象比较方便)。
对于参数固定的业务最好使用多参数入参,因为这种方法比较灵活,代码的可读性高,可以清晰地查看接口方法中所需的参数是什么,并且对于固定的接口,其参数一般是固定的,直接多参数入参即可,无须封装对象。如修改个人密码、根据用户id删除用户、根据用户id查看用户明细,都可以采取这种方式。
需要注意的是,当参数为基础数据类型时,不管是多参数入参,还是单独的一个参数入参,都需要使用@Param注解来进行参数的传递。
2.5.4 使用delete元素完成删除操作
MyBatis使用delete元素来映射删除语句,其用法与insert、update类似,下面通过示例实现根据用户id删除用户的方法,先在UserMapper接口中增加delete方法:
其中delId(用户id),使用@Param注解来指定参数名为id,返回值为int类型,即返回执行SQL影响的行数。
修改UserMapper.xml,以增加删除语句,见示例42。
【示例42】 UserMapper.xml
delete元素的属性id和parameterType的含义和用法等同于insert、update的属性用法,此处不再赘述。
接下来修改测试类UserMapperTest.java,以增加testDeleteUserById方法,进行修改数据测试,并开启事务控制模拟异常,若发生异常则进入回滚,且测试事务,见示例43。
【示例43】 UserMapperTest.java
该测试方法与示例41的测试方法基本上一样,只不过调用相应的deleteUserById()方法进行数据的删除,并且事务处理也相同,此处不再赘述。
2.5.5 技能训练
上机练习5 实现供应商表的查询
需求说明
(1)在上机练习4的基础上,实现供应商表的增加操作。
(2)实现根据供应商id修改供应商信息的操作。
(3)实现根据供应商id删除供应商信息的操作。
(1)增加和修改供应商。
①使用insert元素和update元素。
②parameterType: Java 实体类 Provider。
③DAO层接口方法的返回类型:int。
(2)删除供应商。
①使用delete元素。
②使用@Param注解参数。
③DAO层接口方法的返回类型:int。
createBy、creationDate、modifyDate和modifyBy这4个字段应根据方法的增加或者修改进行灵活操作。
本章总结
➢ MyBatis框架的基本要素包括核心对象、核心配置文件、SQL映射文件。
➢ MyBatis框架的SQL映射文件提供select、insert、update、delete等元素来实现SQL语句的映射。
➢ SQL映射文件的根节点是mapper元素,需要指定namespace来区别于其他的mapper,以保证全局唯一,并且其名称必须要跟接口相同,其作用是绑定DAO接口,即面向接口编程。
➢ SQL映射文件的select返回结果类型的映射可以使用resultMap属性和resultType属性,但不能同时使用。
➢ 关于MyBatis的SQL语句参数入参,对于基础数据类型的参数数据,可使用@Param注解实现参数入参;复杂数据类型的参数直接入参即可。
本章作业
—、选择题
1.以下有关MyBatis框架映射文件中<insert>元素说法正确的是( )。
A.<insert>元素用于映射插入语句,在执行完元素中定义的SQL语句后,没有返回结果
B.<insert>元素的属性与<select>元素的属性相同
C.keyColumn属性用于设置第几列是主键,当主键列不是表中的第1列时需要设置
D.useGeneratedKeys(仅对insert有用)属性会使MyBatis框架使用JDBC的getGeneratedKeys()方法来获取由数据库内部生成的主键
2.以下关于<select>元素及其属性说法错误的是( )。
A.<select>元素用来映射查询语句,它可以从数据库中读取数据,并组装数据给开发人员
B.parameterType属性表示传入SQL语句参数类的全限定名或者别名
C.resultMap元素表示外部resultMap元素的命名引用,返回时可以同时使用两个属性resultType和resultMap
D.在同一个映射文件中可以配置多个<select>元素
3.下列关于MyBatis框架核心对象说法错误的是( )。
A.SqlSession是线程级别的,不能共享
B.SqlSessionFactoryBuilder负责构建SqlSessionFactory,并且可提供多个build()方法的重载
C.一个SqlSession实例中只能执行一次SQL语句,并且一旦关闭了SqlSession就需要重新创建
D.SqlSessionFactory的生命周期与应用的生命周期相同
4.关于MyBatis框架的核心配置文件的描述错误的是( )。
A.MyBatis框架的核心配置文件主要包含数据源和事务管理等设置和属性信息
B.在MyBatis框架的核心配置文件中使用properties元素的resource属性来对数据库配置文件进行引入
C.在MyBatis框架的核心配置文件中可以配置多套运行环境,但是每个SqlSessionFactory实例只能选择一个运行环境
D.通过environment元素的default属性来指定默认的运行环境ID,这个运行环境ID可以是之前没有定义的运行环境ID
5.下列不属于SqlSession的方法是( )。
A.selectOne ()
B.selectList ()
C.save ()
D.update ()
二、简答题
1.简述MyBatis框架核心对象SqlSessionFactory的获取方式。
2.简述MyBatis框架映射文件中的主要元素及其作用。
三、操作题
使用接口方式实现百货中心供应链管理系统商品表(tb_product)的“增删改查”操作,具体要求如下。
(1)实现订单表的查询操作(商品名称模糊查询)。
(2)实现订单表的增加操作。
(3)实现根据供应商id修改订单信息的操作。
(4)实现根据供应商id删除订单信息的操作。