mybatis系列-tkmybatis-06-使用注解方式扩展接口,进行多表关联查询

本文主要是介绍mybatis系列-tkmybatis-06-使用注解方式扩展接口,进行多表关联查询,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        前面介绍了使用xml方式扩展数据库操作接口,其实,mybatis 注解方式 和 XML配置方式两者的使用基本上相同,只有在构建 SQL 脚本有所区别,所以这里重点介绍两者之间的差异,还是以多表关联查询举个例子。

示例

    还是上一章的需求,相比于上一章,我们在UsersMapper中增加selectAllUsersOrdersByAnnotation方法,然后在该方法上增加@Select注解和用于将返回结果映射到pojo对象中的@Results注解(跟xml中的ResultMap类似)

package com.example.demotkmybatisgeneralsecond.mapper;import com.example.demotkmybatisgeneralsecond.pojo.UserOrders;import com.example.demotkmybatisgeneralsecond.pojo.Users;import org.apache.ibatis.annotations.Result;import org.apache.ibatis.annotations.Results;import org.apache.ibatis.annotations.Select;import org.apache.ibatis.type.JdbcType;import tk.mybatis.mapper.common.Mapper;import java.util.List;public interface UsersMapper extends Mapper<Users> {/*xml方式扩展接口*/List<UserOrders> selectAllUsersOrders();List<UserOrders> selectUsersOrders(String userId);/*注解方式扩展接口*/@Select({"SELECT a.*, b.id as order_id, b.receiver_name , b.total_amount, b.real_pay_amount\n" +"    FROM users a LEFT JOIN orders b on a.id = b.user_id\n" +"    WHERE b.id is not NULL"})@Results({@Result(column="id", jdbcType= JdbcType.VARCHAR, property="id",id=true),@Result(column="username",jdbcType=JdbcType.VARCHAR,property="username"),@Result(column="password",jdbcType=JdbcType.VARCHAR,property="password"),@Result(column="nickname",jdbcType=JdbcType.VARCHAR,property="nickname"),@Result(column="realname",jdbcType=JdbcType.VARCHAR,property="realname"),@Result(column="face",jdbcType=JdbcType.VARCHAR,property="face"),@Result(column="mobile",jdbcType=JdbcType.VARCHAR,property="mobile"),@Result(column="email",jdbcType=JdbcType.VARCHAR,property="email"),@Result(column="sex",jdbcType=JdbcType.INTEGER,property="sex"),@Result(column="birthday",jdbcType=JdbcType.DATE,property="birthday"),@Result(column="created_time",jdbcType=JdbcType.TIMESTAMP,property="createdTime"),@Result(column="updated_time",jdbcType=JdbcType.TIMESTAMP,property="updatedTime"),@Result(column="order_id",jdbcType=JdbcType.VARCHAR,property="orderId"),@Result(column="receiver_name",jdbcType=JdbcType.VARCHAR,property="receiverName"),@Result(column="total_amount",jdbcType=JdbcType.INTEGER,property="totalAmount"),@Result(column="real_pay_amount",jdbcType=JdbcType.INTEGER,property="realPayAmount")})List<UserOrders> selectAllUsersOrdersByAnnotation();}

 

        按如上方式修改UserMapper后,重启服务,注入到Service层中的UserMapper就增加了自定义的联表查询方法。

 

主要注解介绍

mybatis 注解方式的最大特点就是取消了 Mapper 的 XML 配置,具体的 SQL 脚本直接写在 Mapper 类上动态生成 。

mybatis 提供的常用注解有: @Insert 、@Update 、@Select、 @Delete 等标签,这些注解其实就是 MyBatis 提供的来取代其 XML配置文件的。

1、@Select 注解

@Select,主要在查询的时候使用,查询类的注解,一般简单的查询可以使用这个注解。

@Select({"select","id, company_id, username, password, nickname, age, sex, job, face_image, province, ","city, district, address, auth_salt, last_login_ip, last_login_time, is_delete, ","regist_time","from sys_user","where id = #{id,jdbcType=VARCHAR}"})@Results({@Result(column="id", property="id", jdbcType=JdbcType.VARCHAR, id=true),@Result(column="company_id", property="companyId", jdbcType=JdbcType.VARCHAR),@Result(column="face_image", property="faceImage", jdbcType=JdbcType.VARCHAR),@Result(column="auth_salt", property="authSalt", jdbcType=JdbcType.VARCHAR),@Result(column="last_login_ip", property="lastLoginIp", jdbcType=JdbcType.VARCHAR),@Result(column="last_login_time", property="lastLoginTime", jdbcType=JdbcType.TIMESTAMP),@Result(column="is_delete", property="isDelete", jdbcType=JdbcType.INTEGER),@Result(column="regist_time", property="registTime", jdbcType=JdbcType.TIMESTAMP)})User selectByPrimaryKey(String id);

注意:如果是多个参数,需要将 #后面的参数和传入的变量名保持一致。

 

2、@Insert 注解

@Insert,插入数据时使用,直接传入数据实体类,mybatis 会属性自动解析到对应的参数。所以需要将 #后面的参数和实体类属性保持一致。

 

@Insert({"insert into sys_user (id, company_id, ","username, password, ","nickname, age, sex, ","job, face_image, ","province, city, ","district, address, ","auth_salt, last_login_ip, ","last_login_time, is_delete, ","regist_time)","values (#{id,jdbcType=VARCHAR}, #{companyId,jdbcType=VARCHAR}, ","#{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, ","#{nickname,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER}, #{sex,jdbcType=INTEGER}, ","#{job,jdbcType=INTEGER}, #{faceImage,jdbcType=VARCHAR}, ","#{province,jdbcType=VARCHAR}, #{city,jdbcType=VARCHAR}, ","#{district,jdbcType=VARCHAR}, #{address,jdbcType=VARCHAR}, ","#{authSalt,jdbcType=VARCHAR}, #{lastLoginIp,jdbcType=VARCHAR}, ","#{lastLoginTime,jdbcType=TIMESTAMP}, #{isDelete,jdbcType=INTEGER}, ","#{registTime,jdbcType=TIMESTAMP})"})int insert(User record);

 

注意:需要将 #后面的参数和实体类属性保持一致。

 

3、@Update 注解

@Update,一般数据更新操作可以使用 @Update注解实现。

@Update({"update sys_user","set company_id = #{companyId,jdbcType=VARCHAR},","username = #{username,jdbcType=VARCHAR},","password = #{password,jdbcType=VARCHAR},","nickname = #{nickname,jdbcType=VARCHAR},","age = #{age,jdbcType=INTEGER},","sex = #{sex,jdbcType=INTEGER},","job = #{job,jdbcType=INTEGER},","face_image = #{faceImage,jdbcType=VARCHAR},","province = #{province,jdbcType=VARCHAR},","city = #{city,jdbcType=VARCHAR},","district = #{district,jdbcType=VARCHAR},","address = #{address,jdbcType=VARCHAR},","auth_salt = #{authSalt,jdbcType=VARCHAR},","last_login_ip = #{lastLoginIp,jdbcType=VARCHAR},","last_login_time = #{lastLoginTime,jdbcType=TIMESTAMP},","is_delete = #{isDelete,jdbcType=INTEGER},","regist_time = #{registTime,jdbcType=TIMESTAMP}","where id = #{id,jdbcType=VARCHAR}"})int updateByPrimaryKey(User record);

4、@Delete 注解

@Delete 数据删除的注解

@Delete({"delete from sys_user","where id = #{id,jdbcType=VARCHAR}"})int deleteByPrimaryKey(String id);

 

5、@Results 和 @Result 注解 

@Results 和 @Result 主要作用是,当有一些特殊的场景需要处理,查询的返回结果与期望的数据格式不一致时,可以将将数据库中查询到的数值自动转化为具体的属性或类型,,修饰返回的结果集。比如查询的对象返回值属性名和字段名不一致,或者对象的属性中使用了枚举等。如果实体类属性和数据库属性名保持一致,就不需要这个属性来修饰。

 

@Select({"select","id, company_id, username, password, nickname, age, sex, job, face_image, province, ","city, district, address, auth_salt, last_login_ip, last_login_time, is_delete, ","regist_time","from sys_user","where id = #{id,jdbcType=VARCHAR}"})@Results({@Result(column="id", property="id", jdbcType=JdbcType.VARCHAR, id=true),@Result(column="company_id", property="companyId", jdbcType=JdbcType.VARCHAR),@Result(column="face_image", property="faceImage", jdbcType=JdbcType.VARCHAR),@Result(column="auth_salt", property="authSalt", jdbcType=JdbcType.VARCHAR),@Result(column="last_login_ip", property="lastLoginIp", jdbcType=JdbcType.VARCHAR),@Result(column="last_login_time", property="lastLoginTime", jdbcType=JdbcType.TIMESTAMP),@Result(column="is_delete", property="isDelete", jdbcType=JdbcType.INTEGER),@Result(column="regist_time", property="registTime", jdbcType=JdbcType.TIMESTAMP)})User selectByPrimaryKey(String id);

 

上面的例子可以看到,数据库中的company_id 字段和实体类中定义的 companyId 属性的名称不一致,需要Result 转换。

 

以上就是项目中常用的增、删、改、查的操作, 当然这些在基本的方法不需要手动写,不管是tkMybatis还是Mybatis Spring默认都是支持的。讲这些主要是熟悉这些常用的注解。

传参方式

上面介绍了mybatis 常用的注解,如何实现增删改查的操作,相信很多人会有疑问了: mybatis 是如何将参数传递到 SQL 中的呢,都有哪几种传参方式呢? 下面就来一一介绍mybatis 注解版的传参方式。其实跟xml配置比较类似。

1、直接传参

对于单个参数的方法,可直接使用 #{id} 的方式接收同名的变量参数。

@Delete("delete from sys_user where id = #{id,jdbcType=VARCHAR}")int deleteByPrimaryKey(String id);

 

2、使用 @Param 注解

@Param注解的作用是给参数命名,参数命名后就能根据名字得到参数值,正确的将参数传入sql语句中 。如果你的方法有多个参数,@Param 注解 会在方法的参数上就能为它们取自定义名字,参数则先以 "param" 作前缀,再加上它们的参数位置作为参数别名。例如, #{param1}、 #{param2},这个是默认值。如果注解是 @Param("person"),那么参数就会被命名为 #{person}。

@Select("SELECT * FROM sys_user WHERE username = #{username} and password = #{password}")List<User> getListByUserSex(@Param("username") String userName, @Param("password") String password);// 不自定义param 时,默认使用 param + 参数序号 或者 0,1,值就是参数的值。@Select("SELECT * FROM sys_user WHERE username = #{param1} and password = #{param2}")List<User> getListByUserSex(String userName, String password);

 

3、Map 传值 

需要传送多个参数时,也可以考虑使用 Map的形式。

@Select("SELECT * FROM sys_user WHERE username=#{username} AND password = #{password}")List<User> getListByNameAndSex(Map<String, Object> map);//调用时将参数依次加入到 Map 中即可。Map param= new HashMap();param.put("username","admin");param.put("password","123456");List<User> users = userMapper.getListByNameAndSex(param)

 

4、使用pojo对象

使用pojo对象传参是比较常用的传参方式。像上面的insert、update 等方法。都是直接传入user对象。

@Update({"update sys_user","set company_id = #{companyId,jdbcType=VARCHAR},","username = #{username,jdbcType=VARCHAR},","password = #{password,jdbcType=VARCHAR},","nickname = #{nickname,jdbcType=VARCHAR},","age = #{age,jdbcType=INTEGER},","sex = #{sex,jdbcType=INTEGER},","job = #{job,jdbcType=INTEGER},","face_image = #{faceImage,jdbcType=VARCHAR},","province = #{province,jdbcType=VARCHAR},","city = #{city,jdbcType=VARCHAR},","district = #{district,jdbcType=VARCHAR},","address = #{address,jdbcType=VARCHAR},","auth_salt = #{authSalt,jdbcType=VARCHAR},","last_login_ip = #{lastLoginIp,jdbcType=VARCHAR},","last_login_time = #{lastLoginTime,jdbcType=TIMESTAMP},","is_delete = #{isDelete,jdbcType=INTEGER},","regist_time = #{registTime,jdbcType=TIMESTAMP}","where id = #{id,jdbcType=VARCHAR}"})int updateByPrimaryKey(User record);

以上,就是Mybatis 传参的四种方式。根据方法的参数选择合适的传值方式。

 

这篇关于mybatis系列-tkmybatis-06-使用注解方式扩展接口,进行多表关联查询的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1075810

相关文章

使用Redis快速实现共享Session登录的详细步骤

《使用Redis快速实现共享Session登录的详细步骤》在Web开发中,Session通常用于存储用户的会话信息,允许用户在多个页面之间保持登录状态,Redis是一个开源的高性能键值数据库,广泛用于... 目录前言实现原理:步骤:使用Redis实现共享Session登录1. 引入Redis依赖2. 配置R

SpringBoot实现RSA+AES自动接口解密的实战指南

《SpringBoot实现RSA+AES自动接口解密的实战指南》在当今数据泄露频发的网络环境中,接口安全已成为开发者不可忽视的核心议题,RSA+AES混合加密方案因其安全性高、性能优越而被广泛采用,本... 目录一、项目依赖与环境准备1.1 Maven依赖配置1.2 密钥生成与配置二、加密工具类实现2.1

使用Python的requests库调用API接口的详细步骤

《使用Python的requests库调用API接口的详细步骤》使用Python的requests库调用API接口是开发中最常用的方式之一,它简化了HTTP请求的处理流程,以下是详细步骤和实战示例,涵... 目录一、准备工作:安装 requests 库二、基本调用流程(以 RESTful API 为例)1.

Nginx进行平滑升级的实战指南(不中断服务版本更新)

《Nginx进行平滑升级的实战指南(不中断服务版本更新)》Nginx的平滑升级(也称为热升级)是一种在不停止服务的情况下更新Nginx版本或添加模块的方法,这种升级方式确保了服务的高可用性,避免了因升... 目录一.下载并编译新版Nginx1.下载解压2.编译二.替换可执行文件,并平滑升级1.替换可执行文件

在Java中实现线程之间的数据共享的几种方式总结

《在Java中实现线程之间的数据共享的几种方式总结》在Java中实现线程间数据共享是并发编程的核心需求,但需要谨慎处理同步问题以避免竞态条件,本文通过代码示例给大家介绍了几种主要实现方式及其最佳实践,... 目录1. 共享变量与同步机制2. 轻量级通信机制3. 线程安全容器4. 线程局部变量(ThreadL

Django中的函数视图和类视图以及路由的定义方式

《Django中的函数视图和类视图以及路由的定义方式》Django视图分函数视图和类视图,前者用函数处理请求,后者继承View类定义方法,路由使用path()、re_path()或url(),通过in... 目录函数视图类视图路由总路由函数视图的路由类视图定义路由总结Django允许接收的请求方法http

使用Python开发一个Ditto剪贴板数据导出工具

《使用Python开发一个Ditto剪贴板数据导出工具》在日常工作中,我们经常需要处理大量的剪贴板数据,下面将介绍如何使用Python的wxPython库开发一个图形化工具,实现从Ditto数据库中读... 目录前言运行结果项目需求分析技术选型核心功能实现1. Ditto数据库结构分析2. 数据库自动定位3

Python yield与yield from的简单使用方式

《Pythonyield与yieldfrom的简单使用方式》生成器通过yield定义,可在处理I/O时暂停执行并返回部分结果,待其他任务完成后继续,yieldfrom用于将一个生成器的值传递给另一... 目录python yield与yield from的使用代码结构总结Python yield与yield

Go语言使用select监听多个channel的示例详解

《Go语言使用select监听多个channel的示例详解》本文将聚焦Go并发中的一个强力工具,select,这篇文章将通过实际案例学习如何优雅地监听多个Channel,实现多任务处理、超时控制和非阻... 目录一、前言:为什么要使用select二、实战目标三、案例代码:监听两个任务结果和超时四、运行示例五

python使用Akshare与Streamlit实现股票估值分析教程(图文代码)

《python使用Akshare与Streamlit实现股票估值分析教程(图文代码)》入职测试中的一道题,要求:从Akshare下载某一个股票近十年的财务报表包括,资产负债表,利润表,现金流量表,保存... 目录一、前言二、核心知识点梳理1、Akshare数据获取2、Pandas数据处理3、Matplotl