当前位置: 首页 > news >正文

MyBatis 操作数据库

文章目录

  • 一、为何学习 MyBatis
    • 1-1 JDBC 操作流程
    • 1-2 JDBC 优化方式
    • 1-3 认识 MyBatis
  • 二、使用 MyBatis
    • 2-1 添加依赖
    • 2-2 yml 配置连接字符串
    • 2-3 使用 @Mapper 注解
      • 2-3-1 添加实体类
      • 2-3-2 添加 mapper 接口
      • 2-3-3 进行 Service 业务
    • 2-4 使用 XML 配置文件
      • 2-4-1 实体类
      • 2-4-2 UserMapper 接口
      • 2-4-3 创建 mapper.xml
      • 2-4-4 在 yml 中声明 mapper.xml 的路径


提示:以下是本篇文章正文内容,Java系列学习将会持续更新

一、为何学习 MyBatis

1-1 JDBC 操作流程

这是因为 JDBC 的操作太繁琐了,我们回顾一下 JDBC 的操作流程:

  1. 创建数据库连接池 DataSource
  2. 通过 DataSource 获取数据库连接 Connection
  3. 编写要执行带 ? 占位符的 SQL 语句
  4. 通过 Connection 及 SQL 创建操作命令对象 Statement
  5. 替换占位符:指定要替换的数据库字段类型,占位符索引及要替换的值
  6. 使用 Statement 执行 SQL 语句
  7. 查询操作:返回结果集 ResultSet,更新操作:返回更新的数量
  8. 处理结果集
  9. 释放资源

所以需要引入一些框架进行 JDBC 优化,它可以帮助我们更方便、更快速的操作数据库。

1-2 JDBC 优化方式

Java中对JDBC优化的主要思路:

  1. ORM (Object Relational Mapping) —— 核心思路, 尝试把一张表中的一条条记录完全映射成一个个的对象——去掉 SQL。当表结构 + SQL查询真的做简单映射时,非常方便。
    但如果有复杂查询(一次涉及多表或者表的优化比较特殊时),就不好了

  2. 仅仅简化SQL的编写

常见框架模式
Hibernate框架偏向简化SQL的模式
MyBatis框架偏向ORM的模式
国内使用MyBatis相对较多(MyBatisPlus 做SQL生成)
Spring内部提供的JdbcTemplate偏向简化SQL的模式
JPA完全倒向了ORM的形式,建表的过程都被抽象,我们看到的只有类
(我写了类,框架根据类建表)

1-3 认识 MyBatis

MyBatis 官网

  • MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。
  • MyBatis 去除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
  • MyBatis 可以通过简单的 XML 或注解 来配置和映射原始类型、接口和 Java POJO(普通老式 Java对象)为数据库中的记录。

简单来说 MyBatis 是更简单完成程序和数据库交互的工具,也就是更简单的操作和读取数据库工具。

怎么学 MyBatis:

  1. 配置 MyBatis 开发环境;
  2. 使用 MyBatis 模式和语法操作数据库。

回到目录…

二、使用 MyBatis

MyBatis 也是一个 ORM 框架,即对象关系映射。在面向对象编程语言中,将关系型数据库中的数据与对象建立起映射关系,进而自动的完成数据与对象的互相转换:

  1. 将输入数据(即传入对象)+SQL 映射成原生 SQL
  2. 将结果集映射为返回对象,即输出对象

ORM 把数据库映射为对象:

  • 数据库表(table)–> 类(class)
  • 记录(record,行数据)–> 对象(object)
  • 字段(field)–> 对象的属性(attribute)

一般的 ORM 框架,会将数据库模型的每张表都映射为一个 Java 类。

Mybatis的使用有两种方式:

  1. 通过注解使用(相对比较容易, 好上手。做一些复杂操作的时候不太灵活)
  2. 通过XML配置文件的形式(比较规则,缺点就是XML 一大堆,又没有语法检查,出错不容易排查)

回到目录…

2-1 添加依赖

需要导入3个依赖:

  • Spring Data JDBC: 这个依赖把 DataSource 对象注册到Spring中(默认HakiraDataSource),Aliyun开源Durid (国内用Durid的比较多)。
  • MySQL Driver: (无论是Durid or Hakira 最终依赖MySQL官方提供的DataSource)
  • MyBatis Framework: (引入了 Mybatis + MybatisSpring)
<!-- Spring Data JDBC -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!-- MySQL Driver -->
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<scope>runtime</scope>
</dependency>
<!-- MyBatis Framework -->
<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
	<version>2.1.4</version>
</dependency>

回到目录…

2-2 yml 配置连接字符串

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/lianxi?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 123456

回到目录…

2-3 使用 @Mapper 注解

2-3-1 添加实体类

// 表示数据库中直接读取出来的对象
@Data
public class UserDO {
    private Integer uid;
    private String username;
    private String password;
}

回到目录…

2-3-2 添加 mapper 接口

@Repository // 注册到 Spring
@Mapper // 让 mybatis 将这个接口看出一个 Mapper,并且使用代理对象代理它
public interface UserMapper { // 按照 Mybatis 的习惯,称为 UserMapper,或者习惯叫 UserDao / UserRepo

	// #{username} 会对应 @Param("username") username
    // #{password} 会对应 @Param("password") password
    @Select("select uid, username, password from users where username = #{username} and password = #{password}")
    User selectOneByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
    
    // 由于用不到这个返回值,所以写成 void 更常见
    // #{username} 会对应 userDO.getUsername() 或者 userDO.username
    // #{password} 会对应 userDO.getPassword() 或者 userDO.password
    @Insert("insert into users (username, password) values (#{username}, #{password})")
    void insert(UserDO userDO);

    // 通过 @Options 注解,添加一些配置,得到自增主键,设置成 uid
    // keyProperty: 对象的属性名是 uid, keyColumn: 表的字段名的 uid
    @Insert("insert into users (username, password) values (#{username}, #{password})")
    @Options(useGeneratedKeys = true, keyProperty = "uid", keyColumn = "uid")
    void insert2(UserDO userDO);

    @Update("update users set username = #{username}, password = #{password} where uid = #{uid}")
    int update(UserDO userDO);

    @Delete("delete from users where uid = #{uid}")
    int delete(@Param("uid") int i);
}

回到目录…

2-3-3 进行 Service 业务

@Service
public class UserService {
	// 依赖注入
    private final UserMapper userMapper;
    @Autowired
    public UserService(UserMapper userMapper) {
        this.userMapper = userMapper;
    }
	// 注册
    public User register(String username, String password) {
        User user = new User(username, password);
        userMapper.insert(user);
        return user;
    }
	// 登录
    public User login(String username, String password) {
        return userMapper.selectOneByUsernameAndPassword(username, password);
    }
}

回到目录…

2-4 使用 XML 配置文件

MyBatis XML 相关文档

2-4-1 实体类

正常情况下,我们的实体类的属性名和数据库中字段名应该一样。如果出现以下情况,就只能使用 XML文件了。

@Data
public class User {
    public Integer a;
    public String b;
    public String c;

    public User(String username, String password) {
        this.b = username;
        this.c = password;
    }
}

2-4-2 UserMapper 接口

// xml 中需要指定 Mapper 接口的位置
@Mapper
@Repository
public interface UserMapper {
    User selectOneByUid(@Param("uid") int uid);

    List<User> selectListByUidList(@Param("uidList") List<Integer> uidList);

    int insertBatch(@Param("userList") List<User> userList);

    User selectByUser(@Param("user") User user);
}

回到目录…

2-4-3 创建 mapper.xml

在 resources/mapper 下创建 mapper.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 接口 -->
<mapper namespace="com.example.mybatis_xml.UserMapper">
	
	<!-- 映射到 User 实体类 -->
    <resultMap id="xxx" type="com.example.mybatis_xml.User">
    	<!-- id property="属性名" javaType="属性类型" column="字段名" jdbcType="字段类型" / -->
        <id property="a" javaType="Integer" column="uid" jdbcType="INTEGER" />
        <result property="b" javaType="String" column="username" jdbcType="VARCHAR" />
        <result property="c" column="password" />
    </resultMap>

	<!-- id="mapper中的方法名" parameterType="参数类型" -->
    <select id="selectOneByUid" resultMap="xxx" parameterType="int">
        select uid, username, password from users where uid = #{uid}
    </select>

    <select id="selectListByUidList" resultMap="xxx" parameterType="List">
        select uid, username, password from users where uid in (
        <!-- for (id : uidList) { -->
        <foreach collection="uidList" item="id" separator=", ">
            #{id}
        </foreach>
        ) order by uid
    </select>

    <insert id="insertBatch" useGeneratedKeys="true" keyProperty="a" keyColumn="uid">
        insert into users (username, password) values
        <foreach collection="userList" item="user" separator=", ">
            (#{user.b}, #{user.c})
        </foreach>
    </insert>

    <select id="selectByUser" resultMap="xxx" parameterType="com.peixinchen.mybatis_xml.User">
        select uid, username, password from users where
        <if test="user.a != null">
            uid = #{user.a}
        </if>
        <if test="user.b != null">
            and username = #{user.b}
        </if>
        <if test="user.c != null">
            and password = #{user.c}
        </if>
    </select>
</mapper>

2-4-4 在 yml 中声明 mapper.xml 的路径

mybatis:
  mapper-locations: classpath:mapper/**.xml

回到目录…


总结:
提示:这里对文章进行总结:
以上就是今天的学习内容,本文是MyBatis的学习,认识到MyBatis带给我们的便利,更简单的去操作数据库,MyBatis的两种使用方式:注解 / XML配置文件。之后的学习内容将持续更新!!!

相关文章:

  • Linux权限
  • 【深度学习】6-卷积过程中数据的结构变化
  • 牛客刷SQL
  • 如何高效的实现大型设备中卫星信号的传输和分配?
  • C语言描述数据结构 —— 二叉树(3)普通二叉树
  • Nginx rewrite
  • 【基于Arduino的垃圾分类装置开发教程一】
  • Synchronized 与 Lock 卖票问题、区别
  • 多疑型性格的危害,如何改变多疑型性格?
  • javaweb教师人事管理系统的设计
  • 【Swift 60秒】01 - Variables - 变量
  • 图像处理:单通道转为3通道
  • impala sql语法
  • 牛视系统源码定制,抖音矩阵系统定制开发。come here
  • 16 C++设计模式之职责链(Chain of Responsibility)模式
  • .pyc 想到的一些问题
  • [笔记] php常见简单功能及函数
  • 08.Android之View事件问题
  • Angular6错误 Service: No provider for Renderer2
  • ECMAScript6(0):ES6简明参考手册
  • java8 Stream Pipelines 浅析
  • Java程序员幽默爆笑锦集
  • Java教程_软件开发基础
  • Promise初体验
  • quasar-framework cnodejs社区
  • 前言-如何学习区块链
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 如何用vue打造一个移动端音乐播放器
  • 一个项目push到多个远程Git仓库
  • 智能合约开发环境搭建及Hello World合约
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • MPAndroidChart 教程:Y轴 YAxis
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • #include到底该写在哪
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • $GOPATH/go.mod exists but should not goland
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (多级缓存)缓存同步
  • (分享)自己整理的一些简单awk实用语句
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (强烈推荐)移动端音视频从零到上手(上)
  • (三) diretfbrc详解
  • (十)c52学习之旅-定时器实验
  • (五)网络优化与超参数选择--九五小庞
  • (转)EXC_BREAKPOINT僵尸错误
  • (转)memcache、redis缓存
  • (转)拼包函数及网络封包的异常处理(含代码)
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • (转载)在C#用WM_COPYDATA消息来实现两个进程之间传递数据
  • ***原理与防范
  • .NET Compact Framework 3.5 支持 WCF 的子集
  • .net core 连接数据库,通过数据库生成Modell
  • .net MySql