【Spring集成MyBatis】MyBatis注解开发

news2024/12/23 3:48:57

文章目录

  • 1. MyBatis的常用注解
  • 2. 基于注解的MyBatis增删改查
    • 完整代码
    • 加载映射关系
    • 测试代码
  • 3. MyBatis的注解实现复杂映射开发
    • 一对一操作的实现
    • 一对一操作实现的第二种方式
    • 一对多操作的实现
    • 多对多操作实现

1. MyBatis的常用注解

在这里插入图片描述

2. 基于注解的MyBatis增删改查

使用注解开发,就可以删掉原本写MyBatis语句的xml文件了,注解只要在UserMapper.java接口上进行实现即可

@Insert("insert into user values(#{id}, #{username}, #{password}, #{birthday})")
void save(User user);

@Delete("delete from user where id=#{id}")
void delete(int id);

@Update("update user set username=#{username}, password=#{password}, birthday=#{birthday} where id=#{id}")
void update(User user);

@Select("select * from user where id=#{id}")
User findById(int id);

@Select("select * from user")
List<User> findAll();

完整代码

package com.example.demo.mapper;

import com.example.demo.domain.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

public interface UserMapper {


    @Insert("insert into user values(#{id}, #{username}, #{password}, #{birthday})")
    void save(User user);

    @Delete("delete from user where id=#{id}")
    void delete(int id);

    @Update("update user set username=#{username}, password=#{password}, birthday=#{birthday} where id=#{id}")
    void update(User user);

    @Select("select * from user where id=#{id}")
    User findById(int id);

    @Select("select * from user")
    List<User> findAll();
}

加载映射关系

原本在sqlMapConfig.xml文件中的加载映射文件修改为加载映射关系:

<!-- 加载映射关系 -->
<mappers>
    <package name="com.example.demo.mapper"/>
</mappers>

测试代码

原本数据库中的内容:
在这里插入图片描述

package com.example.demo;

import com.example.demo.domain.User;
import com.example.demo.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

public class DemoApplication {

    public static void main(String[] args) throws IOException {
//        1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//        2. 加载SqlMapConfig.xml配置文件
        InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//        3. 创建SqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
//        4. 获取SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//        增加User信息
        User saveUser = new User();
        saveUser.setUsername("newUser");
        saveUser.setPassword("aaaaaa");
        saveUser.setBirthday(new Date());
        mapper.save(saveUser);
//        删除User信息
        int deleteUserId = 3;
        mapper.delete(deleteUserId);
//        修改User信息
        User updateUser = new User();
        updateUser.setId(2);
        updateUser.setUsername("ccc");
        updateUser.setPassword("1234567update");
        mapper.update(updateUser);
//        根据Id查询User
        User user = mapper.findById(1);
        System.out.println(user);
//        查询所有user
        List<User> userList = mapper.findAll();
        System.out.println(userList);

        sqlSession.commit();

//        6. 释放资源
        sqlSession.close();

    }
}

打印的信息:
在这里插入图片描述

更新后的内容:
在这里插入图片描述

3. MyBatis的注解实现复杂映射开发

在这里插入图片描述
此处对应于【Spring集成MyBatis】MyBatis的多表查询的内容,来写一下对应的注解实现。

一对一操作的实现

原本基于配置是这么写的

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.dao.OrderMapper">
    
    <resultMap id="orderMap" type="com.example.demo.domain.Order">
<!--        手动指定字段与实体属性的映射关系-->
<!--        column:数据表的字段名称-->
<!--        property:实体的属性名称-->
        <id column="oid" property="id"></id>
        <result column="ordertime" property="orderTime"></result>
        <result column="total" property="total"></result>
        <result column="uid" property="user.id"></result>
        <result column="username" property="user.username"></result>
        <result column="password" property="user.password"></result>
        <result column="birthday" property="user.birthday"></result>
    </resultMap>

    <select id="findAll" resultMap="orderMap">
        SELECT *, o.id `orderid`, u.id `userid` FROM `order` o, `user` u WHERE o.uid=u.id
    </select>

</mapper>

使用注解后如下修改

package com.example.demo.mapper;

import com.example.demo.domain.Order;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface OrderMapper {

    @Select("select *, o.id oid from `order` o, user u where o.uid=u.id")
    @Results({
            @Result(column = "oid", property = "id"),
            @Result(column = "ordertime", property = "orderTime"),
            @Result(column = "total", property = "total"),
            @Result(column = "uid", property = "user.id"),
            @Result(column = "username", property = "user.username"),
            @Result(column = "password", property = "user.password")
    })
    List<Order> findAll();

}

一对一操作实现的第二种方式

其中,在要封装的User对象中,我们可以在@Result注解中写明属性名称、数据库查询到的值、要封装的实体类型等等等,有点类似于之前的注解中的那些属性,不同的事这里通过一个@One来指定通过哪个接口的方法来获得对应的数据,这时候会将column的值注入到这个方法中来获得具体的结果
也就是,首先使用

select * from `order`

来查询出order下的所有信息,包括id、ordertime、total、uid,接着,我们需要根据里面的uid可以查出对应的User信息并封装到Order实体类下的user属性中

select * from `user` where id=(上面查询结果的所有uid)

这里就需要在@Result注解中进一步指定property、column、javaType、one(由于是一对一所以使用one,一对多使用many)

package com.example.demo.mapper;

import com.example.demo.domain.Order;
import com.example.demo.domain.User;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface OrderMapper {

    @Select("select * from `order`")
    @Results({
            @Result(column = "id", property = "id"),
            @Result(column = "ordertime", property = "orderTime"),
            @Result(column = "total", property = "total"),
            @Result(
                    property = "user", // 要封装的属性名称
                    column = "uid", // 根据哪个字段去查询user表的数值
                    javaType = User.class, // 要封装的实体类型
                    // select属性 代表查询哪个接口的方法获得数据
                    one = @One(select = "com.example.demo.mapper.UserMapper.findById")
            )
    })
    List<Order> findAll();

}

以上两种一对一操作的测试代码:

package com.example.demo;

import com.example.demo.domain.Order;
import com.example.demo.domain.User;
import com.example.demo.mapper.OrderMapper;
import com.example.demo.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

public class DemoApplication {

    public static void main(String[] args) throws IOException {
//        1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//        2. 加载SqlMapConfig.xml配置文件
        InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//        3. 创建SqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
//        4. 获取SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();

        OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
        List<Order> orderList = orderMapper.findAll();
        for (Order order : orderList) {
            System.out.println(order);
        }

//        6. 释放资源
        sqlSession.close();

    }
}

结果:
在这里插入图片描述

一对多操作的实现

查询User对应的订单,和【Spring集成MyBatis】MyBatis的多表查询中一样,首先需要再User里面加上一个orderList属性,用于封装所有的订单,并写好对应的set、get方法以及对应的toString方法。
类似于一对一操作的第二种实现方式,我们需要在@Result里面指定property、column、javaType,由于返回的是List,就不用one而用many
首先查询出所有的用户,并在用户下面封装其订单列表。
通过

select * from user

查出了用户的id,username,password,birthday的信息,我们需要根据里面的id到order表里查询对应的订单

select * from `order` where uid=(上面user查询出来的所有id)

即再通过一个@Result注解指定根据uid查询订单的方法。目前Order类里还没有根据uid查询订单的方法,所以我们需要再去实现一下根据uid查询订单的方法
在OrderMapper里写:

@Select("select * from `order` where uid=#{id}")
List<Order> findByUid(int id);

在UserMapper里写根据userid查询指定订单

@Select("select * from user")
@Results({
        @Result(column = "id", property = "id"),
        @Result(column = "username", property = "username"),
        @Result(column = "password", property = "password"),
        @Result(column = "birthday", property = "birthday"),
        @Result(
                property = "orderList",
                column = "id",
                javaType = List.class,
                many = @Many(select = "com.example.demo.OrderMapper.findByUid")
        )
})
List<User> findUserAndOrderAll();

测试:

package com.example.demo;

import com.example.demo.domain.User;
import com.example.demo.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class DemoApplication {

    public static void main(String[] args) throws IOException {
//        1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//        2. 加载SqlMapConfig.xml配置文件
        InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//        3. 创建SqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
//        4. 获取SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = mapper.findUserAndOrderAll();
        for (User user : userList) {
            System.out.println(user);
        }

//        6. 释放资源
        sqlSession.close();

    }
}

查询出来的结果如下:
在这里插入图片描述

多对多操作实现

查询User对应的角色,和【Spring集成MyBatis】MyBatis的多表查询中一样,首先需要再User里面加上一个roleList属性,用于封装所有的角色,并写好对应的set、get方法以及对应的toString方法。
实现过程如下:
先查询所有的User信息

select * from USER

根据userid查询所有的对应的role及其信息

select * from user_role ur, role r where ur.roleId=r.id and userid=(上面查出来的所有id)

那么首先我们需要建立roleMapper,并在RoleMapper中写上对应的查询语句:

package com.example.demo.mapper;

import com.example.demo.domain.Role;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface RoleMapper {

    @Select("select * from user_role ur, role r where ur.roleId=r.id and userid=#{id}")
    List<Role> findByUid(int id);
}

接着,在UserMapper中类似一对多一样补充如下方法:

@Select("select * from User")
@Results({
        @Result(column = "id", property = "id"),
        @Result(column = "username", property = "username"),
        @Result(column = "password", property = "password"),
        @Result(column = "birthday", property = "birthday"),
        @Result(
                property = "roleList",
                column = "id",
                javaType = List.class,
                many = @Many(select = "com.example.demo.mapper.RoleMapper.findByUid")
        )
})
List<User> findUserAndRoleAll();

最后测试:

package com.example.demo;

import com.example.demo.domain.User;
import com.example.demo.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class DemoApplication {

    public static void main(String[] args) throws IOException {
//        1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//        2. 加载SqlMapConfig.xml配置文件
        InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//        3. 创建SqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
//        4. 获取SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = mapper.findUserAndRoleAll();
        for (User user : userList) {
            System.out.println(user);
        }

//        6. 释放资源
        sqlSession.close();

    }
}

结果如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1251878.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Leetcode—83.删除排序链表中的重复元素【简单】

2023每日刷题&#xff08;四十&#xff09; Leetcode—83.删除排序链表中的重复元素 实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* deleteDuplicates(struct ListNode* head) {i…

张弛语言课,战争电影配音声音细致声音来复原战场

为战争片进行声音配音是一项挑战性的工作&#xff0c;它要求精确再现战场的紧张感和复杂情绪。配音人员和声音设计团队必须创造出真实的战争声景&#xff0c;从战斗的轰鸣声到士兵的呐喊&#xff0c;这些声音元素都需细致打造&#xff0c;以传递战争的惨烈、英勇和人性的复杂。…

工作中死循环害死人

背景&#xff1a;研发的一段代码&#xff0c;循环一直没有跳出&#xff0c;导致其他依赖逻辑有问题&#xff0c;生产事故导致9万左右数据不正常。 这里while&#xff08;true&#xff09;真的不要轻易用 &#xff0c;后来研发改动限制mysql的id切分步长&#xff0c;控制不会有数…

2017年2月16日 Go生态洞察:Go 1.8版本的革新

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

移动机器人路径规划(七)--- 基于MDP的路径规划MDP-Based Planning

目录 1 什么是MDP-Based Planning 2 worst-case analysis for nondeterministic model 3 Expected Cost Planning 4 Real Time Dynamic Programming&#xff08;RTDP&#xff09; 1 什么是MDP-Based Planning 之前我们从起点到终点存在很多可执行路径&#xff0c;我们可以…

可验证随机函数(VRF)

文章目录 一、背景以及场景共识发展第一代 POW “以力取胜”第二代 POS/DPOS “民主投票”第三代 VRF “运气抽签” 二、可验证随机函数&#xff08;VRF&#xff09;快速开始1. VRF是什么?2. MD5 hash函数和VRF&#xff08;Verifiable Random Function&#xff09;区别3. VRF-…

日历视图,轻松解决时间管理难题丨三叠云

日历组件 路径 仪表盘设计 >> 组件 功能简介 仪表盘新增「日历」组件。日历组件是以日历图的形式去呈现数据的一种方式&#xff0c;支持【列表模式】和【面板模式】。 【列表模式】&#xff1a; 通过日历方式筛选数据&#xff0c;数据将会以列表的方式呈现。 【面…

视频图片提取秘籍:从指定时长中提取想要的视频封面

在如今的内容丰富的互联网世界中&#xff0c;视频已经成为大家获取信息、娱乐和交流的重要方式之一。而视频的封面或图片&#xff0c;作为视频内容的“名片”&#xff0c;往往决定了观众是否愿意点击和进一步了解视频内容。视频图片提取&#xff0c;通常也被称为视频封面提取&a…

Python实现一箭穿心

文章目录 &#x1f384;效果&#x1f3f3;️‍&#x1f308;Turtle模块&#x1f339;代码&#x1f33a;代码讲解 &#x1f384;效果 &#x1f3f3;️‍&#x1f308;Turtle模块 Turtle是一个绘图工具&#xff0c;是Python标准库中的一个模块。它提供了一种简单而直观的方式来创…

【教学类-06-10】20231125(55格版)X-Y之间“乘法*题”(以1-9乘法口诀表为例)(0-9乘法口诀表 最大81)

图片展示 &#xff08;随机打乱排序&#xff09; 正序 背景需求&#xff1a; 2023年11月24日&#xff0c;准备了一些题目&#xff0c;分别给大4班孩子介绍“5以内加法、5以内减法、5以内加减混合”““10以内加法、10以内减法、10以内加减混合”“”20以内加减混合“七款学具…

Datax安装部署及读取MYSQL写入HDFS

一.DataX简介 1.DataX概述 DataX 是阿里巴巴开源的一个异构数据源离线同步工具&#xff0c;致力于实现包括关系型数据库(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP等各种异构数据源之间稳定高效的数据同步功能。 源码地址&#xff1a;https://github.com/alibaba/Data…

openpnp - 丝杠安装调整的总结

文章目录 openpnp - 丝杠安装调整的总结概述笔记发现的问题 - X轴有回差发现的问题 - 丝杠两边的轴承座中心有高差(不同轴)备注END openpnp - 丝杠安装调整的总结 概述 设备定制回来后, 丝杠没敢动(开始是小白, 也没发现丝杠的相关问题. 因为看到同学自己安装丝杠那么痛苦, 最…

【刷题宝典NO.5】

有效的括号 https://leetcode.cn/problems/valid-parentheses/ 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必…

数仓中数据清洗的方法

在数据采集的过程中&#xff0c;需要从不同渠道获取数据并汇集在数仓中&#xff0c;采集的原始数据首先需要进行解析&#xff0c;然后对不准确、不完整、不合理、格式、字符等不规范数据进行过滤清洗&#xff0c;清洗过的数据才能更加符合需求&#xff0c;从而使后续的数据分析…

5、LED流水灯

LED流水灯 思路&#xff1a;每次LED灯熄灭后&#xff0c;下一个LED灯亮 #include <REGX52.H> #include <INTRINS.H>void Delay500ms() //12.000MHz {unsigned char i, j, k;_nop_();i 4;j 205;k 187;do{do{while (--k);} while (--j);} while (--i); }void m…

3.读取字符串【2023.11.25】

1.问题描述 请使用 input 函数读取一串字符串&#xff0c;然后将其输出。 2.解决思路 输入一行字符串。 将读入的变量输出。 3.代码实现 strinput("请输入一个字符串") print(str)4.运行结果

brat文本标注工具——安装

目录 一、Linux系统安装 1. centOS系统 2. Ubuntu系统 3. macOS系统 4.说明 二、Google Chrome安装 1. 打开命令行&#xff0c;切换到管理者权限 2. 安装依赖 3. 下载Google浏览器的安装包 4. 安装Google Chrome 三、yum更新 四、Apache安装 安装Apache 启动Apac…

【Python百宝箱】Python轻松操控邮件:SMTP、POP3和IMAP的魅力

前言 在数字时代&#xff0c;电子邮件作为信息传递的主要手段&#xff0c;对个人和企业的日常工作至关重要。Python提供了多个强大的库&#xff0c;使得电子邮件的发送和接收变得轻松而灵活。本文将深入介绍Python中与电子邮件相关的主要库&#xff0c;为读者提供从基础到高级…

局域网的网络ip不稳定问题

在局域网的多个设备&#xff0c;互相通信时好时坏&#xff0c;不稳定。 遭遇过的情况如下&#xff1a; 用两个开发板&#xff1a;972开发板1和2&#xff0c;网口同时互相ping&#xff0c;出现1ping 2通--此时2ping 1不通&#xff0c;过段时间&#xff0c;1ping2不通--但2ping又…