1. 程式人生 > 其它 >Mybatis中@select註解聯合查詢

Mybatis中@select註解聯合查詢

前言

在專案中經常會使用到一些簡單的聯合查詢獲取對應的資料資訊,我們常規都是會根據對應的mapper介面寫對應的mapper.xml的來通過對應的業務方法來呼叫獲取,針對這一點本人感覺有點繁瑣,就對@select註解聯合查詢進行探索和嘗試,並將自己總結的分享給大家,有不到之處,敬請大家批評指正!!!

一.pom.xml所用到依賴如下

    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</
artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <
groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <
artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency>

二.application.yml的配置如下:

server:
  port: 8888

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/project?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&useSSL=false
    username: root
    password: 123456
mybatis:
  type-aliases-package: com.songwp.snowflake.entity
  mapper-locations: classpath:mybatis/mapper/*.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

三.資料庫測試表

-- ----------------------------
-- Table structure for sys_dept
-- 部門表
-- ----------------------------
DROP TABLE IF EXISTS `sys_dept`;
CREATE TABLE `sys_dept`  (
  `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '部門ID',
  `user_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '使用者ID',
  `dept_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '部門名稱',
  `parent_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '父級部門ID',
  `parent_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '父級部門名稱',
  `status` int(5) DEFAULT 0 COMMENT '部門狀態:0-正常  1-禁用',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of sys_dept
-- ----------------------------
INSERT INTO `sys_dept` VALUES ('5a8f893eedef4eafbc66feded3541c0f', '4117460f-20f7-47e7-bf8a-507a32880c06', '集團本部', 'GS-001', '集團本部', 0);
INSERT INTO `sys_dept` VALUES ('6271dd03e426400b9fd001bae9074efc', '4117460f-20f7-47e7-bf8a-507a32880c06', '財務部門', 'GS-003', '集團本部', 0);
INSERT INTO `sys_dept` VALUES ('f33503159a084e73b4e1313932cc9629', '4117460f-20f7-47e7-bf8a-507a32880c06', '研發部門', 'GS-002', '集團本部', 0);

-- ----------------------------
-- Table structure for sys_user
-- 使用者表
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user`  (
  `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主鍵ID',
  `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '使用者名稱',
  `nickname` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '真實姓名',
  `password` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密碼',
  `gender` int(5) DEFAULT 1 COMMENT '性別:0-女  1-男',
  `age` int(5) DEFAULT NULL COMMENT '年齡',
  `phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '聯絡電話',
  `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '住址',
  `status` int(5) DEFAULT 0 COMMENT '使用者狀態:0-正常  1-凍結  2- 已登出',
  `birthday` date DEFAULT NULL COMMENT '生日',
  `create_time` datetime DEFAULT NULL COMMENT '新增時間',
  `create_user` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '建立人',
  `update_time` datetime DEFAULT NULL COMMENT '修改時間',
  `update_user` varchar(0) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '修改人',
  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '備註',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES ('4117460f-20f7-47e7-bf8a-507a32880c06', 'zs', '張三', '123456', 0, 25, '13888888888', '陝西西安', 0, '1996-05-07', '2022-03-28 10:17:54', '張三', NULL, NULL, NULL);
INSERT INTO `sys_user` VALUES ('fb962a7f-3a61-4312-820c-9e67eefaa74a', 'zll', '趙老六', '123456', 1, 28, '13666666666', '陝西西安', 0, '1992-05-07', '2022-03-28 10:14:45', '趙老六', NULL, NULL, NULL);

四.@select註解中sql

假設我想使用者名稱(username)為“z's”和密碼(password)為“123456”的條件下使用者的資訊和對應部門的資訊為例:

SELECT
    u.username,
    u.PASSWORD,
    u.nickname,
    u.phone,
    u.gender,
    u.address,
    d.id AS dept_id,
    d.dept_name,
    d.STATUS AS dept_status 
FROM
    sys_user u
    INNER JOIN sys_dept d ON u.id = d.user_id 
WHERE
    u.username = 'zs' 
    AND u.PASSWORD = '123456'

Navicat中結果執行如下:

五.mapper介面

@Select("<script> SELECT " +
            "u.username," +
            "u.password," +
            "u.nickname," +
            "u.phone," +
            "u.gender," +
            "u.address," +
            "d.id as dept_id," +
            "d.dept_name," +
            "d.status as dept_status " +
            "from" +
            " sys_user u" +
            " inner join sys_dept d on u.id = d.user_id " +
            " where u.username = #{username} <when test='password !=null'> " +
            " and u.password = #{password} </when> </script>")
    List<Map> getByParmsMap(String username, String password);
1、@Select註解基本用法
@Select註解的目的是為了取代xml中的select標籤,只作用於方法上面。下面看一下@Select註解的原始碼介紹:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Select
{
    String[] value();
}

從上述可以看到兩點資訊:

(1)@Select註解只能修飾方法
(2)@Select註解的值是字元陣列。

所以,@Select註解的用法是這樣的:

@Select({ "select * from xxx", "select * from yyy" })
Person selectPersonById(Integer id);

雖然@Select註解的值是字元陣列,但是真正生效的應該是最後那條SQL語句。這一點請大家要留意一下。

2、@Select註解動態SQL拼寫
普通的字串值,只能實現變數的替換功能,如下所示,

@Select("select * from t_person where id = #{id}")
Person selectPersonById(Integer id);
如果要想實現複雜的邏輯判斷,則需要使用標籤,如下所示: @Select("<script> select * from t_person where id = #{id} <when test='address !=null'> and address = #{address} </when> </script>") Person selectPersonById(Integer id); 其實,標籤並非是@Select註解專用的,其他的註解,例如@Insert,@Update等等,都可以使用的。

六.業務層service介面

List<Map> getByParmsMap(String username, String password);

七.業務實現類的方法

public List<Map> getByParmsMap(String username, String password) {
        return userMapper.getByParmsMap(username,password);
 }

八.控制器controller方法

@RequestMapping(value = {"/getByParmsMap"}, method = RequestMethod.GET)
@ResponseBody
public List<Map> getByParmsMap(@RequestParam("username")String username,@RequestParam("password")String password){
    return userService.getByParmsMap(username,password);
}

九.Postman介面呼叫如下

[
    {
        "password": "123456",
        "address": "陝西西安",
        "gender": 0,
        "phone": "13888888888",
        "nickname": "張三",
        "dept_name": "集團本部",
        "dept_status": 0,
        "dept_id": "5a8f893eedef4eafbc66feded3541c0f",
        "username": "zs"
    },
    {
        "password": "123456",
        "address": "陝西西安",
        "gender": 0,
        "phone": "13888888888",
        "nickname": "張三",
        "dept_name": "財務部門",
        "dept_status": 0,
        "dept_id": "6271dd03e426400b9fd001bae9074efc",
        "username": "zs"
    },
    {
        "password": "123456",
        "address": "陝西西安",
        "gender": 0,
        "phone": "13888888888",
        "nickname": "張三",
        "dept_name": "研發部門",
        "dept_status": 0,
        "dept_id": "f33503159a084e73b4e1313932cc9629",
        "username": "zs"
    }
]

如下圖所示: