SpringBoot整合Mybatis(3000字)

news2024/11/27 18:26:33

SpringBoot整合Mybatis

文章目录

    • SpringBoot整合Mybatis
      • 依赖导入
      • 配置信息(application.yml)
      • 代码分层
      • 数据库(建库建表语句)
      • 各层代码
        • enity:
        • dao:
        • service:
        • controller:
      • 测试
    • Mybatis分页查询和模糊查询
      • 分页查询:
        • 测试:
      • 模糊查询:
        • 测试:
    • Mybatis的分布查询
      • 多对一:
      • 测试:
      • 一对多:
    • Mybatis的其他语句
      • Update:
      • delete:
      • Insert:
    • 小结

依赖导入

        <dependencies>
<!--            SpringBoot依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
<!--            Mybatis依赖-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.4</version>
            </dependency>
<!--            数据库连接-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.6</version>
            </dependency>
<!--            德鲁伊的连接池依赖-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.2.4</version>
            </dependency>
<!--            lombok依赖-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
 <!--          日志门面-->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.30</version>
            </dependency>
  <!--         log4j日志 -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
        </dependencies>

同时在Maven中检查一下依赖是否完全导入

请添加图片描述

配置信息(application.yml)

我们在resources目录下创建application.yml的文件

请添加图片描述

在application.yml文件中我们编写配置信息:

#端口号
server:
  port: 8888
#spring中datasource配置
spring:
  datasource:
#    我们选择我们的德鲁伊数据源
    type: com.alibaba.druid.pool.DruidDataSource
#    这里我们填写我们的数据库用户名和密码
    username: root
    password: 123456
#    这里填写我们的url地址,注意:不同版本的mysql在url‘?’后拼接的字符是不一样的,这里我的mysql版本是5.7的
    # 8.0版本以上的url是 jdbc:mysql://localhost:3306/ibcompany?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
    # 解释: 端口号是3306 对应数据库是ibcompany
    url: jdbc:mysql://localhost:3306/ibcompany?characterEncoding=utf8
    driver-class-name: com.mysql.jdbc.Driver
mybatis:
  # mapper映射文件所在的包
  mapper-locations: classpath:/mapper/*.xml
  # 实体类所在的包
  type-aliases-package: com.lty.enity
  configuration:
    # 将下划线映射成驼峰
    map-underscore-to-camel-case: true
    # 开启延迟加载
    lazy-loading-enabled: true
    # 按需加载关闭
    aggressive-lazy-loading: false
    # 这里开启打印日志,他会帮助我们生成对应的sql语句
    log-impl: org.apache.ibatis.logging.log4j.Log4jImpl

注意:

一定要先确认自己的Mysql版本号再去填写对应的urldriver-class-name

补充:怎么查看自己的mysql版本号:

  1. win+r 输入cmd + 回车
  2. 在控制台输入mysql --version
  3. 请添加图片描述

同时添加log4j的配置文件

请添加图片描述

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
        <param name="Encoding" value="UTF-8" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS}
%m (%F:%L) \n" />
        </layout>
    </appender>
    <logger name="java.sql">
        <level value="debug" />
    </logger>
    <logger name="org.apache.ibatis">
        <level value="info" />
    </logger>
    <root>
        <level value="debug" />
        <appender-ref ref="STDOUT" />
    </root>
</log4j:configuration>

代码分层

请添加图片描述

controller: 控制层负责编写控制用户访问代码

dao: 负责与数据库的交互

enity: 各个对象的实体层

service: 业务层

impl: 业务层的主要实现

mapper: 每个实体类对应的mapper文件

数据库(建库建表语句)

​ 建表的sql如下

CREATE DATABASE ibcompany;

CREATE TABLE `ib_user`(
`id` INT(25) PRIMARY KEY,
`name` VARCHAR(255),
`dept_name` VARCHAR(255),
`address` VARCHAR(255)
)CHARACTER SET = utf8;

CREATE TABLE `ib_dept`(
`id` INT(25) PRIMARY KEY NOT NULL AUTO_INCREMENT,
`dept_name` VARCHAR(255),
`company_number` INT(25)
)CHARACTER SET = utf8;

CREATE TABLE `ib_admin`(
`id` INT(25) PRIMARY KEY AUTO_INCREMENT,
`username` VARCHAR(255) NOT NULL,
`password` VARCHAR(255) NOT NULL
)CHARACTER SET = utf8;

​ 表中的各种信息大家可以自行填写

各层代码

enity:

我们根据数据库中表中的字段属性去实体类中编写对应的实体对象

@Data // lombok提供的注解 自动生成getter,setter方法
@AllArgsConstructor //所有的有参构造器
@NoArgsConstructor  //所有的无参构造器
public class User {
    private Integer id;
    private String name;
    private String deptName;
    private String address;
}

dao:

dao层所放置的代码是我们与数据库之间进行数据交互的代码。

注意我们的dao层需要的两个注解:

@Mapper:

Mapper注解用于标识与Mybatis对应的Mapper映射文件。Mybatis 会有一个拦截器,会自动的把 @Mapper 注解的接口生成动态代理类

@Repository

该注解则是将我们的dao层注入到IOC容器中去。当我们在某些地方如Service层需要调用dao层时,我们只需要通过@Autowired或者@Resource注解声明一下就可以直接进行调用。

@Mapper
@Repository
public interface UserDao {
       //获取所有的用户信息
       public List<User> getAllUser();
}

当我们写完对应的dao层代码,我们会发现它有红线提示。

请添加图片描述

这里的红线提示是指我们没有与之对应的Mapper映射文件,因此我们需要在resources下的Mapper中去创建对应的UserMapper.xml。

UserMapper.xml

<?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.lty.dao.UserDao">

    <select id="getAllUser" resultType="com.lty.enity.User">
        select * from ib_user;
    </select>
</mapper>

注意:

  • 这里的namespace必须要对应到dao层。
  • select标签中的id必须是对应的dao层的接口名字,如果名字不一致会导致匹配不上。resultType就是我们返回的数据类型。
  • 在select标签中我们就开始写我们对应的sql语句。

service:

请添加图片描述

我们service层一般是一个接口对应的一个实现类。并且实现类和接口分开进行放置。

service层的接口:

public interface UserService {
    List<User> getAllUser();
}

对应的实现类:

@Service

将我们的Service也注入到IOC容器中,也交给IOC容器进行管理,方便在后边Controller层中的使用。

@Service
public class UserServiceImpl implements UserService {
    //注入我们的dao层,与数据库之间进行交互
    @Autowired
    private UserDao userDao;

    /**
     * 得到所有的用户信息
     * @return 返回的是一个List的User集合
     */
    @Override
    public List<User> getAllUser() {
        return userDao.getAllUser();
    }
}

在实现类中我们可以看到service层中注入了dao层与数据库进行数据访问。

controller:

@RestController:

这个注解当我们ctrl+B进入就可以看到是@Controller + @ResponseBody 注解的合成注解

@ResponseBody:该注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据。

@Controller:则是用来标识这Controller控制层。

请添加图片描述

@RequestMapping:

请求路径:当我们在类上使用这个注解,就表示这个在这个类中所有请求前面都必须带有这个请求路径。

@RestController
@RequestMapping("/user")
public class UserController{
    @Autowired
    private UserService userService;

    @RequestMapping("/getAllUser")
    public List<User> getAllUser(){
        return userService.getAllUser();
    }
}

例如我们刚写好的一个控制层接口我们只需要访问 http://localhost:8888/user/getAllUser 即可。

因此我们这个Controller层就已经完成了。

测试

我们可以进行测试:

这里我使用的是postman。

请添加图片描述

我们可以看到已经发送成功,并且拿到了我们所需要的数据。

请添加图片描述

在控制台也打印出了我们的查询语句。

这样我们的SpringBoot与Mybatis的初级整合也就完成了!

Mybatis分页查询和模糊查询

分页查询:

先引入Mybatis的pageHelper的依赖

<!--            引入Mybatis的Pagehelper的依赖-->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>1.4.5</version>
            </dependency>

当我们引入这个pageHelper后,我们就得到了一个分页对象PageInfo

从中我们可以看出PageInfo拥有很多的属性

请添加图片描述

我们用的比较多的

pageNum: 起始的页码

pageSize: 每页的数量

因此我们需要定义一个自己的分页数据PageQuery

@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageQuery {
    //起始的页码 默认为第一页
    private Integer pageNum = 1;
    //每页显示的个数为3个信息
    private Integer pageSize = 3;
}

使用方法,我们只需要将我们定义的pageQuery对象传入即可,返回的对象是一个PageInfo对象

UserService:

    PageInfo<User> getAllUserByPage(PageQuery pageQuery);

UserServiceImpl:

    /**
     * 通过分页插件pageHepler进行分页
     * @return 返回的是PageInfo
     */
    @Override
    public PageInfo<User> getAllUserByPage(PageQuery pageQuery) {
        //先开启分页
        PageHelper.startPage(pageQuery.getPageNum(), pageQuery.getPageSize());
        //返回的是一个PageInfo对象
        return new PageInfo<User>(userDao.getAllUserByPage(pageQuery));
    }

注意:

在返回之前我们必须用PageHelper的startPage方法将我们的分页数据传入进去,只有这样分页才会生效。

Controller层:

    @RequestMapping("/getAllUserByPage")
    public List<User> getAllUserByPage(PageQuery pageQuery){
        PageInfo<User> allUserByPage = userService.getAllUserByPage(pageQuery);
        //拿到pageInfo中的分页过后集合
        List<User> list = allUserByPage.getList();
        return list;
    }

测试:

请添加图片描述

IDEA控制台:

请添加图片描述

当我们想查看第二页,我们只需要在postman中输入pageNum=2,就可以查看到第二页。

模糊查询:

dao层:

       //根据用户用户名进行模糊查询
       public List<User> getAllUserByPageAndName(PageQuery pageQuery,@Param("name") String name);

对应的UserMapper.xml

    <select id="getAllUserByPageAndName" resultType="com.lty.enity.User">
        select * from ib_user
             <where>
                 <if test="name != null and name != ''">
                     and name like '%${name}%'
                 </if>
             </where>
    </select>

这里我们用到了Mybatis的动态sql,当我们传入的name为null或者为空字符。这样就直接查询所有用户。

controller:

    @RequestMapping("/getAllUserByPageAndName")
    public List<User> getAllUserByPageAndName(PageQuery pageQuery,String name){
        PageInfo<User> allUserByPage = userService.getAllUserByPageAndName(pageQuery,name);
        List<User> list = allUserByPage.getList();
        return list;
    }

其他层的代码大同小异。

测试:

请添加图片描述

Mybatis的分布查询

不知道当时我们查询所有用户时大家注意到每我们查出的用户信息中deptName总是null的。那是因为我们的数据库中user表内没有deptName的这个内容。deptName的内容在dept表中。因此我们要关联这两张表。

多对一:

这里我们采用分布查询的方式。

  1. 我们先在UserMapper.xml中的getAllUser进行修改,因为是分布查询,我们的主要思路是先查询User表,拿到User表中deptId,再根据deptId到dept表中进行查询到对应的deptName

        <resultMap id="getAllUserMap" type="User">
            <result property="id" column="id"></result>
            <result property="deptId" column="dept_id"></result>
            <!--        其中的deptName是多对一的关系,这里我们采用association-->
            <!--        select中我们写的是下一个查询的路径,也就是查询dept表的方法-->
            <association property="deptName" select="com.lty.dao.DeptDao.getDeptName" column="dept_id"></association>
        </resultMap>
    
        <select id="getAllUser" resultMap="getAllUserMap">
            select * from ib_user;
        </select>
    
  2. 我们创建1个DeptDao,在DeptDao中写查询deptName的方法getDeptName();

    DeptDao:

    @Mapper
    @Repository
    public interface DeptDao {
        String getDeptName(@Param("deptId") Integer id);
    }
    
    

    DeptMapper.xml:

        <select id="getDeptName" resultType="string">
            select dept_name
            from ib_dept
            where id = #{deptId};
        </select>
    

    注意:DeptDao中的方法路径必须和UserMapper中的select对应。

    测试:

    这里我们进行测试:

请添加图片描述

可以看到这个测试出来的数据就比较全面。

一对多:

​ 一个部门对应这多个User,因此我们这种情况属于一对多的关系。

这里我们所用的标签就为collection

  1. 我们在Dept实体类中加入 users;

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Dept {
        private Integer id;
        private String deptName;
        private Integer companyNumber;
        private List<User> users;
    }
    
  2. DeptDao

    Dept getDeptUsers(@Param("deptId") Integer id);
    
  3. DeptMapper.xml

    注意:是collection标签

    <resultMap id="getUsers" type="Dept">
        <collection property="users" select="com.lty.dao.UserDao.getUsers" column="id"></collection>
    </resultMap>
    <select id="getDeptUsers" resultMap="getUsers">
        select * from ib_dept
        where id = #{deptId};
    </select>
    
  4. UserDao

    List<User> getUsers(@Param("deptId") Integer id);
    
  5. UserMapper.xml:

    <select id="getUsers" resultType="User">
         select * from ib_user
            where dept_id = #{deptId}
    </select>
    

    测试:

    请添加图片描述

我们也可以看控制台的查询语句(2句sql)

请添加图片描述

Mybatis的其他语句

Update:

UserDao:

int UpdateUserById(@Param("id") Integer id, @Param("address") String address);

UserMapper.xml:

<update id="UpdateUserById">
    update ib_user
    set address = #{address}
    where id = #{id};
</update>

注意:标签为update

请添加图片描述

delete:

UserDao:

       int deleteById(@Param("id") Integer id);

UserMapper.xml:

<delete id="deleteById">
    delete from ib_user
      where id = #{id};
</delete>

请添加图片描述

控制台(可见执行了delete语句):

请添加图片描述

Insert:

UserDao:

int insertUser(@Param("user") User user);

UserMapper.xml

<insert id="insertUser">
    insert into ib_user
    values (null,#{user.name},#{user.address},#{user.deptId});
</insert>

从控制台可以看到添加成功!

请添加图片描述

小结

这篇博客有点长,博主个人觉得写的还是挺细的,希望能对初学者有帮助。同时这篇博客的源码也会同步到博主的github上。希望大家多点点赞和关注。LeetCode每日一题还是会更的,只是最近事太多了。

代码地址: github

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

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

相关文章

邮箱营销不再难:如何提高邮件的到达率和打开率?

在数字时代&#xff0c;电子邮件是企业与客户以及潜在客户沟通的重要渠道&#xff0c;是企业培养客户的有效方式之一。然而&#xff0c;由于每个人每天也要收到大量的垃圾邮件&#xff0c;所以企业必须确保在正确的时间将邮件传递给正确的人。在这篇文章中&#xff0c;小编将探…

BEVDet 论文学习

1. 解决了什么问题&#xff1f; 自动驾驶系统感知周围的环境再进行决策&#xff0c;极具挑战。基于视觉的自动驾驶系统对准确性和效率的要求很严格&#xff0c;人们会采用不同的范式来解决 3D 检测和分割任务。对于多相机 3D 目标检测&#xff0c;image-view-based 方法如 FCO…

缓存更新策略

缓存更新策略 内存淘汰超时剔除主动更新说明利用Redis的内存淘汰机制&#xff0c;不用自己维护&#xff0c;当内存不足时会自动淘汰部分数据。下次查询时更新缓存。给缓存数据添加TTL(过期时间)&#xff0c;到期后自动删除缓存。下次查询时更新缓存。编写业务逻辑&#xff0c;…

CSAPP Lab4- PerfLab

代码优化 typedef struct { unsigned short red; /* R value */ unsigned short green; /* G value */ unsigned short blue; /* B value */ } pixel图像用一维数组表示&#xff0c;第&#xff08;i,j&#xff09;个像素表示为I[RIDX(i,j,n)]&#xff0c;n为图像的维数 #def…

Datacom-HCIE 02(10月26日更新)--含解析

单选题 1.[试题编号&#xff1a;189785] &#xff08;单选题&#xff09;如图所示&#xff0c;VTEP1上在BD20域内开启了ARP广播抑制功能&#xff0c;并且VTEP1通过 BGP EVPN路由学习到了PC2的ARP信息&#xff0c;则PC1发送的针对PC2的ARP请求&#xff0c;VIEP1在转发给VIEP2时…

sqli-labs Less-11,12

less-11(基于错误的POST型单引号字符型注入) sqlmap 1.使用bp抓包 2.保存为1.txt在本地&#xff0c;使用sqlmap查询数据库 sqlmap.py -r "C:\Users\wy199\Desktop\1.txt" --dbs 3.查询当前数据库的所有表 sqlmap.py -r "C:\Users\wy199\Desktop\1.txt"…

正点原子ALPHA开发板核心资源分析

目录 正点原子ALPHA开发板核心资源分析I.MX6ULL实物图对比SOC 主控芯片&#xff08;MCIMX6Y2CVM08AB&#xff09;NAND FLASHEMMCDDR3L 正点原子ALPHA开发板核心资源分析 I.MX6ULL实物图对比 I.MX6ULL NAND BTB 接口核心板资源图与 I.MX6ULL EMMC BTB 接口核心板资源图如上图&a…

安装ElasticSearch之前的准备工作jdk的安装

一.windows 下载jdk的软件 (1).进入jdk1.8官网 (2).根据电脑是32位还是64位按需下载 (3).点击下载之后就会跳转到Oracle账号登录界面 没有 Oracle账号的注册一下就可以了 下载好的jdk如下: 双击下一步下一步安装jdk 默认安装就可以了 配置环境变量 (1).电脑左下方设置选项 (2).…

UFT软件的安装与注意事项

安装包下载 UFT软件的安装包网上也有许多&#xff0c;这里我分享下我使用的--->UFT安装包 下载完成解压后进行安装。 要注意关闭杀毒软件&#xff0c;否则安装过程中某些组件可能会安装不上。 部分电脑在安装过程中出现以下提示&#xff0c;可以点击确定 然后我们查看桌面上…

学习open62541 --- [77] 修改String类型变量的注意点

对于String类型的节点&#xff0c;其值的类型是UA_String&#xff0c;在这篇文章中我们解释了UA_String的生成方法。 当我们修改String类型节点的值时&#xff0c;会事先准备一个UA_String变量&#xff0c;这时就会遇到一个选择&#xff1a;是否需要动态分配内存&#xff0c;即…

一种基于数值的横向相互作用

( A, B )---144*30*2---( 1, 0 )( 0, 1 ) 让网络的输入有144个节点&#xff0c;训练集AB各由12张二值化的图片组成&#xff0c;让A中每行有1个1&#xff0c;B中全是0&#xff0c;排列组合A &#xff0c;统计迭代次数的顺序。 前面实验已经表明对于A中每行只有1个1&#xff0c;…

虚幻or现实?堆区、栈区真实存在吗?是操作系统在骗你罢了...

文章目录 &#x1f490;专栏导读&#x1f490;文章导读&#x1f427;引例 &#x1f426;进程地址空间&#x1f426;虚拟地址与物理内存的联系&#x1f514;回答引例中的问题&#x1f513;写时拷贝 &#x1f426;虚拟地址存在的意义&#x1f513;malloc的本质 &#x1f490;专栏…

Lift, Splat, Shoot 论文学习

1. 解决了什么问题&#xff1f; LSS 在工业界具有非常重要的地位。自从 Tesla AI Day 上提出了 BEV 感知后&#xff0c;不少公司都进行了 BEV 工程化的探索。当前 BEV 下的感知方法大致分为两类&#xff1a; 自下而上&#xff1a;利用 transformer 的 query 机制&#xff0c;…

软考 软件设计师上午题设计模式概念类

设计模式分类 创建型设计模式 简单工厂模式 不符合开闭原则&#xff0c;因此没有列入23类模式里 对扩展开放对修改关闭 工厂方法模式 说穿了&#xff1a;系统开放一个接口&#xff08;拓展开放&#xff09;、不提供修改的接口&#xff08;修改关闭&#xff09;&#xff0c;…

基于html+css的图展示83

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

使用贝壳物联控制led灯

1、完成esp8266 01S的固件刷机 1.1 使用刷机软件刷原生固件 esp8266 01S要使用标准固件1M&#xff08;主要是01S是8M&#xff09; 1.2 刷机接线方式 ttl直接连esp8266 接线&#xff1a; tts esp8266 3v3 ---》面包板高----》3.3 tx--------------…

BEVFormer 论文学习

1. 解决了什么问题&#xff1f; 3D 视觉感知任务&#xff0c;包括基于多相机图像的 3D 目标检测和分割&#xff0c;对于自动驾驶系统非常重要。与基于 LiDAR 的方法相比&#xff0c;基于相机图像的方法能够检测到更远距离的目标&#xff0c;识别交通信号灯、交通标识等信息。有…

[CTF/网络安全] 攻防世界 command_execution 解题详析

[CTF/网络安全] 攻防世界 command_execution 解题详析 ping命令ping命令的应用格式ping命令执行漏洞 ls命令cat命令姿势ping本地回环地址ping目录ping文件夹ping文件 Tips总结 题目描述&#xff1a;小宁写了个ping功能,但没有写waf,X老师告诉她这是非常危险的&#xff0c;你知道…

图【无向图】的创建与遍历

树&#xff1a;无回路 图&#xff1a;有回路 代码在最下面 邻接矩阵&#xff1a;重点&#xff1a;矩阵 &#xff08;一&#xff09;图的创建 存储方式 如图&#xff1a; 代码截图分析&#xff1a;顶点用一维数组存&#xff0c;边用两个点之间的值为0或1来表…

异地研发团队都使用哪些研发协同工具?盘点7类最主流的研发管理协同软件

产品研发场景下好用的协同办公软件有哪些&#xff1f;分享7类研发过程中主流的协同办公软件&#xff0c;比如项目管理协作与问题跟踪工具PingCode、代码托管与版本控制平台github、持续集成与持续部署&#xff08;CI/CD&#xff09;工具jinkens、文档协作与知识管理工具conflue…