MyBatis详细教程!!(入门版)

目录

什么是MyBatis?

MyBatis入门

 1)创建工程

2)数据准备

3)配置数据库连接字符串

4)写持久层代码

5)生成测试类

MyBatis打印日志

传递参数

MyBatis的增、删、改

增(Insert)

删(Delete)

改(Update)

查(Select)

使用XML方式

增删改查

增(Insert)

删(Delete)

改(Update)

查(Select)

补充:MySQL开发规范


什么是MyBatis?

MyBatis是一款持久层框架,用于简化JDBC开发

持久层:持久化操作的层,通常指数据访问层(DAO),是用来操作数据库的

MyBatis入门

  1. 准备工作(创建springboot工程、数据库表准备、实体类)
  2. 引入MyBatis的相关依赖,配置MyBatis(数据库连接信息)
  3. 编写SQL语句(注解/XML)
  4. 测试

 1)创建工程

     创建springboot工程,并引入MyBatis、MySQL依赖

<!--Mybatis 依赖包--> 
<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.3.1</version>
</dependency>
<!--mysql驱动包-->
<dependency>
			<groupId>com.mysql</groupId>
			<artifactId>mysql-connector-j</artifactId>
</dependency>

MyBatis是一个持久层框架,具体的数据库存储和数据操作还是在MySQL中操作的

2)数据准备

  创建用户表

DROP DATABASE IF EXISTS mybatis_test; CREATE DATABASE mybatis_test;
DEFAULT CHARACTER SET utf8mb4;
USE mybatis_test;
DROP TABLE IF EXISTS userinfo;
CREATE TABLE `userinfo` ( `id` INT ( 11 ) NOT NULL AUTO_INCREMENT, `username` VARCHAR ( 127 ) NOT NULL, `password` VARCHAR ( 127 ) NOT NULL, `age` TINYINT ( 4 ) NOT NULL, `gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-⼥ 0-默认', `phone` VARCHAR ( 15 ) DEFAULT NULL, `delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除', `create_time` DATETIME DEFAULT now(), `update_time` DATETIME DEFAULT now(), PRIMARY KEY ( `id` ) ) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone ) VALUES ( 'admin', 'admin', 18, 1, '18612340001' ); INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone ) VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' ); INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone ) VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' ); INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone ) VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );

创建对应实体类UserInfo

(注意实体类中的属性名与表中的字段名一一对应)

import lombok.Data;
import java.util.Date;
@Data
public class UserInfo {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private Integer gender;
    private String phone;
    private  Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}

3)配置数据库连接字符串
spring:
  datasource:
   url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
   username: root
   password: root #改为你的数据库密码
   driver-class-name: com.mysql.cj.jdbc.Driver

4)写持久层代码

创建持久层接口UserInfoMapper

@Mapper
public interface UserInfoMapper {
    @Select("select username,`password`,age,gender,phone from userinfo")
    public List<UserInfo> queryAllUser();
}

Mybatis的持久层接⼝规范⼀般都叫XxxMapper

@Mapper注解:表⽰是MyBatis中的Mapper接⼝

程序运⾏时,框架会⾃动⽣成接⼝的实现类对象(代理对象),并给交Spring的IOC容器管理

5)生成测试类

在需要测试的Mapper接口中,右键->Generate->Test

书写测试代码

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void queryAllUser() {
        List<UserInfo> userInfoList=userInfoMapper.queryAllUser();
        System.out.println(userInfoList);
    }
}

注解@SpringBootTest,该测试类在运行时,就会自动加载Spring的运行环境

MyBatis打印日志

通过日志看到sql语句的执行、执行传递的参数以及执行结果

mybatis:
 configuration: # 配置打印 MyBatis⽇志
  log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

①:查询语句

②:传递参数及类型

③:SQL执行结果

传递参数
@Mapper
public interface UserInfoMapper {
    @Select("select username,`password`,age,gender,phone from userinfo where id=#{id}")
    public List<UserInfo> queryAllUser(Integer id);
}
@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void queryAllUser() {
        List<UserInfo> userInfoList=userInfoMapper.queryAllUser(4);
        System.out.println(userInfoList);
    }
}

MyBatis的增、删、改

增(Insert)

(Mapper中)

@Mapper
public interface UserInfoMapper {
    @Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert into userinfo(username,`password`,age,gender,phone) values (#{username},#{password},#{age},#{gender},#{phone})")
    public Integer insert(UserInfo userInfo);

}

(MapperTest中)

@SpringBootTest
class UserInfoMapperTest {
    @Test
    void insert() {
        UserInfo userInfo=new UserInfo();
        userInfo.setAge(10);
        userInfo.setGender(2);
        userInfo.setUsername("赵六");
        userInfo.setPhone("123456");
        userInfo.setPassword("123");
       userInfoMapper.insert(userInfo);
    }
}

注意:如果使用了@Param属性来重命名,#{...}需要使用“参数.属性”来获取

@Insert("insert into userinfo(username,`password`,age,gender,phone) values (#{userinfo.username},#{userinfo.password},#{userinfo.age},#{userinfo.gender},#{userinfo.phone})")
public Integer insert(@Param("userinfo") UserInfo userInfo);

Insert语句返回值是收影响的行数

有些情况下我们需要获得新插入数据的id,此时使用@Options注解

@Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert into userinfo(username,`password`,age,gender,phone) values (#{username},#{password},#{age},#{gender},#{phone})")
    public Integer insert(UserInfo userInfo);
@Test
void insert() {
   UserInfo userInfo=new UserInfo()
   userInfo.setAge(10);
   userInfo.setGender(2);
   userInfo.setUsername("赵六");
   userInfo.setPhone("123456");
   userInfo.setPassword("123");
   Integer count = userInfoMapper.insert(userInfo);
   //设置useGeneratedKeys=true后,方法返回值仍然是受影响行数
   System.out.println("添加数据条数:" +count +",数据id:"+userInfo.getId());
}

useGeneratedKeys:令MyBatis使⽤JDBC的getGeneratedKeys⽅法来取出由数据库内部⽣成的主键,默认值:false.

keyProperty:这指定了实体类中用于存储数据库生成的主键的属性的名称,当 MyBatis 从数据库获取到新生成的主键后,它会将这个值设置到实体类的 id 属性中。

删(Delete)
@Delete("delete from userinfo where id=#{id}")
    public void delete(Integer id);
@Test
void delete() {
    userInfoMapper.delete(4);
}

改(Update)
@Update("update userinfo set username=#{username} where id=#{id}")
public void update(String username,Integer id);
@Test
void update() {
    userInfoMapper.update("王五",3);
}

查(Select)

上述查询中,我们发现,只有在java对象属性和数据库字段名一样(忽略大小写)时,才会进行赋值

(java对象中deleteFlag、createTime、updateTime属性与数据库中字段delete_flag、create_time、update_time对应不上)

解决办法

①起别名

@Select("select id, username, `password`, age, gender, phone, delete_flag as 
deleteFlag,create_time as createTime, update_time as updateTime from userinfo")
public List<UserInfo> queryAllUser();

②结果映射

@Select("select id, username, `password`, age, gender, phone, delete_flag, 
create_time, update_time from userinfo")
@Results({
 @Result(column = "delete_flag",property = "deleteFlag"),
 @Result(column = "create_time",property = "createTime"),
 @Result(column = "update_time",property = "updateTime")
})
List<UserInfo> queryAllUser();

可以给Results定义一个名称,使其他sql也能复用这个映射关系

@Select("select id, username, `password`, age, gender, phone, delete_flag, 
create_time, update_time from userinfo")
@Results(id = "resultMap",value = {
 @Result(column = "delete_flag",property = "deleteFlag"),
 @Result(column = "create_time",property = "createTime"),
 @Result(column = "update_time",property = "updateTime")
})
List<UserInfo> queryAllUser();
@Select("select id, username, `password`, age, gender, phone, delete_flag, 
create_time, update_time " +
 "from userinfo where id= #{userid} ")
@ResultMap(value = "resultMap")
UserInfo queryById(@Param("userid") Integer id);

③开启驼峰命名(推荐)

数据库中字段通常使用蛇形命名,java属性通常使用驼峰命名,可以通过配置使得这两种命名方式自动映射(abc_xyz => abcXyz)

mybatis:
 configuration:
 map-underscore-to-camel-case: true #配置驼峰⾃动转换 

MyBatis有使用注解和XML两种方式

下面,我们介绍

使用XML方式

①配置数据库连接字符串

#数据库连接配置
spring:
  datasource:
   url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
   username: root
   password: root  //改成你自己的密码
   driver-class-name: com.mysql.cj.jdbc.Driver
#配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件
mybatis:
 mapper-locations: classpath:mapper/**Mapper.xml

②写持久层代码

1)方法定义Interface

@Mapper
public interface UserInfoXMLMapper {
    List<UserInfo> queryAllUser();
}

2)方法实现:UserInfoXMLMapper.xml(路径参考yml中的配置 mapper-locations: classpath: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 namespace="com.example.sql.mapper.UserInfoMapper">
    <select id="queryAllUser" resultType="com.example.sql.UserInfo">
        select username,`password`,age,gender,phone from userinfo
    </select>
</mapper>
  • <mapper>标签:需要指定namespace 属性,表⽰命名空间,值为mapper接⼝的全限定 名,包括全包名.类名。
  • <select>查询标签:是⽤来执⾏数据库的查询操作的:

        ◦id :是和Interface (接⼝)中定义的⽅法名称⼀样的,表⽰对接⼝的具体实现⽅法。

        ◦ resultType :是返回的数据类型,也就是开头我们定义的实体类

单元测试

@SpringBootTest
public class UserInfoXMLMapperTest {
    @Autowired
    private UserInfoXMLMapper userInfoXMLMapper;
    @Test
    void queryAllUser(){
        List<UserInfo> userInfoList=userInfoXMLMapper.queryAllUser();
        System.out.println(userInfoList);
    }

}

增删改查
增(Insert)
@Mapper
public interface UserInfoXMLMapper {
    Integer insertUser(UserInfo userInfo);
}
<?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.sql.mapper.UserInfoXMLMapper">

    <insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
        insert into userinfo (username,`password`,age,gender,phone) values(#{username},#{password},#{age},#{gender},#{phone})
    </insert>
</mapper>
@SpringBootTest
public class UserInfoXMLMapperTest {
    @Autowired
    private UserInfoXMLMapper userInfoXMLMapper;
    @Test
    void insertUser(){
        UserInfo userInfo=new UserInfo();
        userInfo.setAge(10);
        userInfo.setGender(2);
        userInfo.setUsername("赵七");
        userInfo.setPhone("123457");
        userInfo.setPassword("123");
        Integer count=userInfoXMLMapper.insertUser(userInfo);
        System.out.println(count);

    }
}

使用@Param设置参数名称与注解类似

Integer insertUser(@Param("userinfo") UserInfo userInfo);
<insert id="insertUser">
 insert into userinfo (username, `password`, age, gender, phone) values
 (#{userinfo.username},#{userinfo.password},#{userinfo.age},#
{userinfo.gender},#{userinfo.phone})
</insert>

返回自增id

<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
 insert into userinfo (username, `password`, age, gender, phone) values
 (#{userinfo.username},#{userinfo.password},#{userinfo.age},#
{userinfo.gender},#{userinfo.phone})
</insert>

删(Delete)

UserInfoXMLMapper接⼝

Integer deleteUser(Integer id);

UserInfoXMLMapper.xml实现:

<delete id="deleteUser">
 delete from userinfo where id = #{id}
</delete>

改(Update)

UserInfoXMLMapper接⼝:

Integer updateUser(UserInfo userInfo);

UserInfoXMLMapper.xml实现:

update id="updateUser"> update userinfo set username=#{username} where id=#{id} update>

查(Select)

与注解方式类似,查找操作也涉及到java对象和数据库字段命名问题

解决办法

①起别名

②结果映射

③开启驼峰命名

(①③与注解一样),下面介绍结果映射

<resultMap id="BaseMap" type="com.example.demo.model.UserInfo">
 <id column="id" property="id"></id>
 <result column="delete_flag" property="deleteFlag"></result>
 <result column="create_time" property="createTime"></result>
 <result column="update_time" property="updateTime"></result>
</resultMap>
<select id="queryAllUser" resultMap="BaseMap">
 select id, username,`password`, age, gender, phone, delete_flag, 
create_time, update_time from userinfo
</select>

开发中,建议简单sql使用注解方式,复杂sql(如动态sql)使用xml方式

注解方式和xml方式可以一起使用


 

补充:MySQL开发规范

①表名、字段名使⽤⼩写字⺟或数字,单词之间以下划线分割.尽量避免出现数字开头或者两个下划线,中间只出现数字.数据库字段名的修改代价很⼤,所以字段名称需要慎重考虑。

MySQL在Windows下不区分⼤⼩写,但在Linux下默认是区分⼤⼩写.

因此,数据库名、表名、字段名都不允许出现任何⼤写字⺟,避免节外⽣枝

②表必备三字段:id,create_time,update_time,id必为主键,类型为bigintunsigned,​​​​​​​create_time,update_time的类型均为datetime类型,create_time表⽰创建时间, update_time表⽰更新时间

③在表查询中,避免使⽤*作为查询的字段列表,标明需要哪些字段

1. 增加查询分析器解析成本

2. 增减字段容易与resultMap配置不⼀致

3. ⽆⽤字段增加⽹络消耗,尤其是text类型的字段

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

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

相关文章

鸿蒙 DevEco Studio 3.1 Release 下载sdk报错的解决办法

鸿蒙 解决下载SDK报错的解决方法 最近在学习鸿蒙开发&#xff0c;以后也会记录一些关于鸿蒙相关的问题和解决方法&#xff0c;希望能帮助到大家。 总的来说一般有下面这样的报错 报错一&#xff1a; Components to install: - ArkTS 3.2.12.5 - System-image-phone 3.1.0.3…

Django-auth组件

Django-auth组件 1 表结构 我们从python manage.py migrate为我们创建的auth组件内置的表开始看 auth_user&#xff1a;用户表存储用户信息&#xff08;登录admin后台&#xff09; 里面的字段分两类&#xff1a;用户基本信息&#xff08;用户名&#xff0c;邮箱&#xff0c;密…

【线程的互斥】

线程的互斥 临界区资源多个线程的运行多个线程对同一资源的竞争原子性保持线程之间地互斥互斥量(锁的原理)为什么是原子的 正确使用锁 临界区资源 进程创建线程&#xff0c;是共享内存的&#xff0c;可以对共享的资源有很方便的操作&#xff0c;当一些共享资源可以被多个线程进…

【找出第 K 大的异或坐标值】python

4层循环暴力超时 class Solution:def kthLargestValue(self, matrix: List[List[int]], k: int) -> int:nums[]for a in range(len(matrix)):for b in range(len(matrix[0])):num0for i in range(a1):for j in range(b1):num^matrix[i][j]nums.append(num)nums.sort()retu…

Golang实现文件复制

方法&#xff1a;三种 package zdpgo_fileimport ("errors""io""os" )// CopyFile 使用io.Copy进行文件的复制&#xff0c;同时也会复制文件的所有权限 // param src 复制文件 // param des 目标文件 // return error 错误信息 func CopyFile(s…

【QGIS入门实战精品教程】10.7: 基于DEM的地形因子分析(坡度、坡向、粗糙度、山体阴影、耐用指数)

文章目录 一、加载dem二、山体阴影三、坡度四、坡向五、地形耐用指数六、地形位置指数七、地表粗糙度一、加载dem 二、山体阴影 方法一:符号系统 利用符号系统中的山体阴影,渲染出阴影效果。 方法二:山体阴影工具 该算法计算输入中的数字化地形模型的山体阴影。根据太阳的位…

2024年教你怎么将学浪视频保存到本地

你是否曾为无法将学浪视频保存到本地而烦恼&#xff1f;现在&#xff0c;我们将在2024年教给你如何解决这个问题&#xff01;只需简单几步操作&#xff0c;即可轻松将学浪视频保存到您的本地设备&#xff0c;随时随地想看就看&#xff01; 我已经将下载学浪的工具打包好了&…

OSPF网络类型实验2

对R4 对R5&#xff0c;找R1注册 对R1宣告环回&#xff0c;再宣告一下tunnel接口 本实验不考虑区域划分 现在已经全部宣告完成 对R1&#xff0c;2&#xff0c;3改接口 broadcast工作方式hello时间10s&#xff0c;然后进行dr选举&#xff0c;由于2&#xff0c;3之间没有伪广播 …

滑不动窗口的秘密—— “滑动窗口“算法 (Java版)

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人能接…

淘工厂订单导出自动化工具

目录 下载安装与运行 主要目的 其他工具的弊端 本工具的优势 视频演示 下载新版后的注意事项 支持的导出项 什么叫一单多拍 常见问题 如何实现快捷登录 导出卡住时如何操作 如何精确导出 下载安装与运行 下载、安装与运行 语雀 主要目的 导出订单信息&#xf…

兴业证券 | 哪些行业在提价?

一方面&#xff0c; 部分行业年初以来PPI价格整体上涨&#xff0c;4月进一步提价&#xff1b;另一方面&#xff0c;部分行业年初以来PPI价格整体下跌或者涨幅不高&#xff0c;但4月开始出现边际提升。 前言&#xff1a;年初以来&#xff0c;“提价”是一条重要的投资线索。我们…

秋招突击——算法打卡——5/25、5/26——寻找两个正序数组的中位数

题目描述 自我尝试 首先&#xff0c;就是两个有序的数组进行遍历&#xff0c;遍历到一半即可。然后求出均值&#xff0c;下述是我的代码。但这明显是有问题的&#xff0c;具体错误的代码如下。计算复杂度太高了&#xff0c;O&#xff08;n&#xff09;&#xff0c;所以会超时&…

Linux基础(六):Linux 系统上 C 程序的编译与调试

本篇博客详细分析&#xff0c;Linux平台上C程序的编译过程与调试方法&#xff0c;这也是我们后续程序开发的基础。 目录 一、第一个hello world程序 1.1 创建.c文件 1.2 编译链接 运行可执行程序 二、编译链接过程 2.1 预编译阶段 2.2 编译阶段 2.3 汇编阶段 2.4 链…

【Linux】常见命令:fping的介绍和用法举例

一、fping命令的安装 在终端中输入如下命令&#xff08;Ubuntu系统使用apt install&#xff0c;CentOS系统使用yum install&#xff09; sudo apt install fping安装效果&#xff08;截图&#xff09;&#xff1a; 二、fping命令的用法和选项 fping命令用于检测主机是否存在…

2024最新 Jenkins + Docker实战教程(一) - Jenkins介绍及安装

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

DiffMap:首个利用LDM来增强高精地图构建的网络

论文标题&#xff1a; DiffMap: Enhancing Map Segmentation with Map Prior Using Diffusion Model 论文作者&#xff1a; Peijin Jia, Tuopu Wen, Ziang Luo, Mengmeng Yang, Kun Jiang, Zhiquan Lei, Xuewei Tang, Ziyuan Liu, Le Cui, Kehua Sheng, Bo Zhang, Diange Ya…

大数据工具之HIVE-参数调优,调度乱码(二)

一、调度乱码 在利用HUE工具,搭建WORKFLOW流程的过程中,如果直接执行hivesql数据正常,不会出现乱码现象,如果利用WORKFLOW搭建的流程,进行数据的拉取,会出现数据中文乱码现象,这些乱码主要是由于select 中的硬编码中文导致出现的现象 具体现象如下: select case when …

auto关键字(C++11)

auto关键字&#xff08;C11&#xff09; 文章目录 auto关键字&#xff08;C11&#xff09;前言一、auto使用规则二、auto不适用的场景三、auto推荐适用的场景总结 前言 在C11中&#xff0c;auto关键字能够自动推导出变量的实际类型&#xff0c;可以帮助我们写出更加简洁、现代…

java8新特性——函数式编程详解

目录 一 概述1.1 背景1.2 函数式编程的意义1.3 函数式编程的发展 Lambda表达式1.1 介绍1.2 使用Lambda的好处1.3 Lambda方法1.3.1 Lambda表达式结构1.3.2 Lambda表达式的特征 1.4 Lambda的使用1.4.1 定义函数式接口1.4.2 Lambda表达式实现函数式接口1.4.3 简化Lambda表达式1.4.…

k8s devops实战教程+生产实践+可就业

k8s devops实战教程 简介教程涉及到内容教程获取学习教程后的收货助学群 简介 越来越多的企业应用云原生化&#xff0c;催生很多应用的部署方式也发生了很多变化。 从物理机部署应用过度到虚机部署应用再到应用容器化&#xff0c;从单应用再到服务拆分为微服务&#xff0c;靠人…