【Spring整合MyBatis】Spring整合MyBatis的具体方法

在前面写的博客中,介绍了MyBatis通过配置方式和通过注解方式写的方法:

  1. 【Spring集成MyBatis】MyBatis诞生及代码快速入门(非注解开发)
  2. 【Spring集成MyBatis】MyBatis的Dao层实现(基于配置,非注解开发)
  3. 【Spring集成MyBatis】动态sql
  4. 【Spring集成MyBatis】核心配置文件
  5. 【Spring集成MyBatis】MyBatis的多表查询
  6. 【Spring集成MyBatis】MyBatis注解开发

在这篇博客中将具体介绍Spring整合MyBatis
Spring开放了一些接口,便于其他框架整合到Spring框架中去,所以导入坐标的时候,我们会导入来源于mybatis整合好的mybatis-spring坐标。

文章目录

  • 1. 原本MyBatis代码
    • 数据库表account
    • 类account.java
    • 配置文件SqlMapper.xml
    • 外部数据源文件jdbc.properties
    • 基于注解写的AccountDao.java
    • 测试代码
    • 运行结果
  • 2. Spring整合MyBatis
    • 导入相关坐标
    • 写SpringConfig配置类
    • JdbcConfig配置类
    • MyBatis配置类
    • 测试方法

1. 原本MyBatis代码

数据库表account

在这里新建了一个数据库表Account:
在这里插入图片描述

类account.java

package com.example.project2.domain;

public class Account {
    private int id;
    private String username;
    private double money;

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", money=" + money +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }
}

配置文件SqlMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <properties resource="jdbc.properties"></properties>
    <typeAliases>
        <package name="com.example.project2.domain"/>
    </typeAliases>

<!--    加载数据源-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="url" value="${jdbc.url}"/>
                <property name="driver" value="${jdbc.driver}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

<!--    加载Mapper类-->
    <mappers>
        <package name="com.example.project2.dao"/>
    </mappers>

</configuration>

外部数据源文件jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=123456

基于注解写的AccountDao.java

package com.example.project2.dao;

import com.example.project2.domain.Account;
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 AccountDao {

    @Insert("insert into account(username, money) values(#{username}, #{money})")
    void save(Account account);

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

    @Update("update account set username=#{username} and money=#{money} where id=#{id}")
    void update(Account account);

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

    @Select("select * from account")
    List<Account> findAll();
}

测试代码

package com.example.project2;

import com.example.project2.dao.AccountDao;
import com.example.project2.domain.Account;
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 Project2Application {

    public static void main(String[] args) throws IOException {
//        加载输入流
        InputStream inputStream = Resources.getResourceAsStream("SqlMapper.xml");
//        获得工厂
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//        工厂加载输入流
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
//        获得SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();

        AccountDao accountDao = sqlSession.getMapper(AccountDao.class);
        List<Account> accountList = accountDao.findAll();
        for (Account account : accountList) {
            System.out.println(account);
        }

//        关闭SqlSession
        sqlSession.close();
    }

}

运行结果

在这里插入图片描述

2. Spring整合MyBatis

导入相关坐标

在pom.xml中导入所有相关坐标:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>project2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>project2</name>
    <description>project2</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>6.0.3</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <version>8.0.33</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>3.0.1</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.21</version>
        </dependency>
    </dependencies>

</project>

其中,mybatis-springmybatis存在版本对应关系,这个需要去官网查询对应的版本(但是我去官网找了一下没找到),版本不匹配可能会导致运行出现问题等情况。注意:Spring整合MyBatis的依赖版本必须为3.0.0以上!——该句出自:整合Spring6+MyBatis3.5.10出现的bug

写SpringConfig配置类

SpringConfig配置类中,需要使用注解@Configuration注明这是配置类
@ComponentScan指定扫描的包,这个一般可以写大一点
@PropertySource指定外部数据源
@Import表示导入其他配置类,这里还需要配置JDBC的一些属性,同时配置MyBatis的属性
JDBC的属性和MyBatis属性的配置类实际作用就是将上面的SqlMapper.xml的那些配置信息,写入到配置类中

package com.example.project2.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;

@Configuration
@ComponentScan("com.example.project2")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class, MyBatisConfig.class})
public class SpringConfig {
}

JdbcConfig配置类

在JdbcConfig配置类中,主要写数据库驱动、链接、用户名密码等信息,即数据源来源的所有信息,对应于原本SqlMapper.xml中的<environment>下的部分

package com.example.project2.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;

import javax.sql.DataSource;

public class JdbcConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}

其中,jdbc.properties中的内容:

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=123456

MyBatis配置类

原本在写MyBatis测试的时候,我们需要先加载输入流、获得工厂建造器、通过工厂建造器获得工厂、打开SqlSession会话链接

//        加载输入流
InputStream inputStream = Resources.getResourceAsStream("SqlMapper.xml");
//        获得工厂
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//        工厂加载输入流
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
//        获得SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();

我们需要将这些方法转换到MyBatis配置类中来
上面的核心其实就是SqlSessionFactoryBuilder,我们从中加载输入流获得的工厂
下面我们通过配置SqlSessionFactoryBean一些必要的属性来获得具体的工厂
setTypeAliasesPackage这个方法告诉 MyBatis 框架在指定的包路径下扫描实体类,然后为这些实体类设置别名。这样,在编写 MyBatis 的 Mapper 文件时可以直接使用实体类的别名来引用它们,而不必使用完整的类名。
举例来说,如果有一个位于 com.itheima.domain 包下的实体类 User,并且在 com.itheima.dao 包下编写了相应的 Mapper 接口,那么在 Mapper 文件中,可以使用 User 的别名来引用它,而不必写完整的类名 com.itheima.domain.User
setDataSource就是设置相应的数据源,我们在JdbcConfig中已经配置了,这里写在属性中,Spring会自动把我们之前写好的那个dataSource bean注入进来
接着,通过配置mapperScannerConfigurer来配置相应扫描包的范围,对应原本SqlMapper.xml中加载Mapper类的内容

package com.example.project2.config;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;

import javax.sql.DataSource;

public class MyBatisConfig {

    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
        SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
        ssfb.setTypeAliasesPackage("com.example.project2.domain");
        ssfb.setDataSource(dataSource);
        return ssfb;
    }

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer msc = new MapperScannerConfigurer();
        msc.setBasePackage("com.example.project2.dao");
        return msc;
    }

}

测试方法

package com.example.project2;

import com.example.project2.config.SpringConfig;
import com.example.project2.dao.AccountDao;
import com.example.project2.domain.Account;
import com.example.project2.service.AccountService;
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 org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

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

public class Project2Application {

    public static void main(String[] args) throws IOException {

        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);

        AccountService accountService = ctx.getBean(AccountService.class);

        Account account = accountService.findById(1);

        System.out.println(account);
    }
}

结果为:
在这里插入图片描述
PS:这里不需要再获得sqlSession。我认为是因为,在new AnnotationConfigApplicationContext方法的时候加载了Spring的配置类,在Spring配置类中又扫描了Service的相关内容、并import了MyBatisConfig
通过MyBatisConfig获得了sqlSessionFactory,通过扫描包的方法扫描到了dao包下的类完成了sqlSession获得具体mapper的创建(等价于AccountDao accountdao = sqlSession.getMapper(AccountDao.class)),而这个dao又进一步被注入到serviceImpl下的AccountDao中,进而可以在Service类中调用具体的方法。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端学习网站推荐

1.菜鸟教程&#xff08;程序员必备&#xff09;菜鸟教程 - 学的不仅是技术&#xff0c;更是梦想&#xff01; 2.npm库 npm | Home 3.uniapp学习官网 uni-app官网 4.vue官网 快速上手 | Vue.js 5.ECharts图表 Apache ECharts 6.ES6学习 ES6 入门教程 7.Three.js学习 Three.js…

17. Python 数据库操作之MySQL和SQLite实例

目录 1. 简介2. 使用PyMySQL2. 使用SQLite 1. 简介 数据库种类繁多&#xff0c;每种数据库的对外接口实现各不相同&#xff0c;为了方便对数据库进行统一的操作&#xff0c;大部分编程语言都提供了标准化的数据库接口&#xff0c;用户不需要了解每种数据的接口实现细节&#x…

Python教程:DataFrame数据中使用resample计算月线平均值

在pandas库中&#xff0c;DataFrame可以使用resample()方法来对时间序列数据进行重采样。重采样是将原始数据按照指定的频率进行重新组织&#xff0c;以便进行更细粒度的分析或转换。下面是一个示例&#xff0c;演示如何使用resample()方法&#xff1a; # Author : 小红牛 # 微…

uiautomator2 无法连接 ATX-Agent

最近需要写个安卓自动项目&#xff0c;本身不想用appium 。主要是appium需要安装的依赖太多&#xff0c;一单换个环境又要配置新的环境。但是ATX-Agent装好之后怎么都连接不是。 报错信息如下&#xff1a; .........省略............ uiautomator2.exceptions.GatewayError: (…

解密 sqli靶场第一关:一步一步学习 SQL 注入技术

目录 一、判断是否存在注入点 二、构造类似?id1 --的语句 三、判断数据表中的列数 四、使用union联合查询 五、使用group_concat()函数 六、爆出数据库中的表名 七、爆出users表中的列名 八、爆出users表中的数据 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很…

肾合胶囊 | 冬不养肾春易病,若出现了这六大表现,小心是肾虚!

冬季作为一年中最寒冷的季节&#xff0c;自然万物皆静谧闭藏&#xff0c;而肾具有潜藏、封藏、闭藏精气的特点&#xff0c;是封藏之本&#xff0c;肾的脏腑特性与冬季相通应&#xff0c;所以在冬季更应该重视养肾。 而现在正值初冬&#xff0c;正是开始养肾的最佳时间。此时培…

肾合胶囊 | “导龙入海,引火归元”——浅谈中医治法中的“引火归元”!

中医有许多特色的治疗方法&#xff0c;医家更是给它们起了文艺的名字。逆流挽舟、提壶揭盖、增水行舟&#xff0c;这些治疗方法无不体现了中医对生活、对自然的深入观察&#xff0c;并将这些自然现象与临床相结合&#xff0c;创立了一个个行之有效的方剂。 我们今天谈一谈“引…

【Linux】第二十站:模拟实现shell

文章目录 一、shell的实现细节1.shell的一些细节2.用户名、主机名、工作目录2.输入命令3.改为循环4.切割字符串5.普通命令的执行6.内建命令的处理7.子进程的退出码8.总结 二、模式实现shell完整代码 一、shell的实现细节 1.shell的一些细节 shell操作系统的一个外壳程序。 s…

字符串原地旋转

记录一下做的练习题 字符串原地旋转&#xff1a;五 三 mat [[1,2,3],[3,4,5],[4,5,6]] tag0 total 0 for i in mat:total total i[tag]tag 1 print(total) 四 X [[12,7,3],[4,5,6],[7,8,9]] Y [[5,8,1],[6,7,3],[4,5,9]] res [[0,0,0],[0,0,0],[0,0,0]] for i in rang…

阶梯排列硬币

题意&#xff1a; 你总共有 n 枚硬币&#xff0c;并计划将它们按阶梯状排列。对于一个由 k 行组成的阶梯&#xff0c;其第 i 行必须正好有 i 枚硬币。阶梯的最后一行 可能 是不完整的。 给你一个数字 n &#xff0c;计算并返回可形成 完整阶梯行 的总行数。 示例 1&#xff…

线程的创建方式

作者简介&#xff1a; zoro-1&#xff0c;目前大二&#xff0c;正在学习Java&#xff0c;数据结构&#xff0c;mysql&#xff0c;javaee等 作者主页&#xff1a; zoro-1的主页 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f496; 线程的创建方…

Spring Security 6.1.x 系列(5)—— Servlet 认证体系结构介绍

一、前言 本章主要学习Spring Security中基于Servlet 的认证体系结构&#xff0c;为后续认证执行流程源码分析打好基础。 二、身份认证机制 Spring Security提供个多种认证方式登录系统&#xff0c;包括&#xff1a; Username and Password&#xff1a;使用用户名/密码 方式…

【采坑分享】导出文件流responseType:“blob“如何提示报错信息

目录 前言&#xff1a; 采坑之路 总结&#xff1a; 前言&#xff1a; 近日&#xff0c;项目中踩了一个坑分享一下经验&#xff0c;也避免下次遇到方便解决。项目基于vue2axioselement-ui&#xff0c;业务中导出按钮需要直接下载接口中的文件流。正常是没有问题&#xff0c;但…

STM32 默认时钟更改 +debug调试

STM32时钟 文章目录 STM32时钟前言一、修改系统时钟二、DEBUG 前言 为什么我们要改STM32的时钟呢&#xff0c;打个比方在做SPI驱动的时候&#xff0c;需要16M的时钟&#xff0c;但是stm32默认是72的分频分不出来&#xff0c;这个时候我们就要改系统时钟了&#xff0c;那么怎么…

[科普] 无刷直流电机驱动控制原理图解

Title: [科普] 无刷直流电机驱动控制原理图解 文章目录 I. 引言II. 直流电机的原理1. 有刷直流电机和无刷直流电机的区别2. 有刷直流电机的运行原理3. 既是电动机又是发电机 III. 无刷直流电机的原理1. 无刷直流电机与永磁同步电机的区别2. 无刷直流电机的换向控制原理3. 无刷直…

Spring Cache(缓存框架)

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

指针的进阶

重中之重&#xff1a; 目录 1.字符指针&#xff1a; 2.指针数组 3.数组指针 4.数组参数、指针参数 5.函数指针 1.字符指针&#xff1a; 一般实现&#xff1a; int main() {char ch w;char *pc &ch;*pc w;return 0; } 二班实现&#xff1a; int main() {const c…

人工智能基础_机器学习050_对比sigmoid函数和softmax函数的区别_两种分类器算法的区别---人工智能工作笔记0090

可以看到最上面是softmax的函数对吧,但是如果当k = 2 那么这个时候softmax的函数就可以退化为sigmoid函数,也就是 逻辑斯蒂回归了对吧 我们来看一下推导过程,可以看到上面是softmax的函数 可以看到k=2 表示,只有两个类别对吧,两个类别的分类不就是sigmoid函数嘛对吧,所以说 …

3 时间序列预测入门:TCN

0 引言 TCN&#xff08;全称Temporal Convolutional Network&#xff09;&#xff0c;时序卷积网络&#xff0c;是在2018年提出的一个卷积模型&#xff0c;但是可以用来处理时间序列。 论文&#xff1a;https://arxiv.org/pdf/1803.01271.pdf 一维卷积&#xff1a;在时间步长方…

2024年天津天狮学院专升本计算机科学与技术《数据结构》考试大纲

2024年天津天狮学院计算机科学与技术专业高职升本入学考试《数据结构》考试大纲 一、考试性质 《数据结构》专业课程考试是天津天狮学院计算机科学与技术专业高职升本入学考 试的必考科目之一&#xff0c;其性质是考核学生是否达到了升入本科继续学习的要求而进行的选拔性考试…