MyBatis框架

1. 什么是MyBatis框架

MyBatis框架是一个优秀的持久层框架,为了简化JDBC开发。传统的JDBC编程编写起来很麻烦。

MyBatis框架使用了数据库连接池技术,避免了频繁的创建和销毁操作。

初始情况下,数据库连接池会默认创建一定数量的connection对象,当有sql操作的时候就给这个sql操作分配一个connection对象,sql执行完毕后会把connection对象归还给数据库连接池

数据库连接池的优点:降低网络资源开销,资源重用,提高性能。

持久层:指的是持久化操作的层,负责进行数据库相关操作

下面创建Spring Boot项目,并加入MyBatis和MySQL,

Mybatis框架配置方式有两种,一种是注解,一种是xml

2. 注解

2.1 查询操作

数据库相关操作: 

DROP DATABASE IF EXISTS mybatis_test;
CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;
use mybatis_test;DROP TABLE IF EXISTS user_info;
CREATE TABLE `user_info` (`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() ON UPDATE now(),PRIMARY KEY ( `id` ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4INSERT INTO user_info( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO user_info( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO user_info( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO user_info( 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;
}

在properties中配置 

#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
#连接数据库的⽤⼾名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=root
#指定mybatis输出⽇志的位置, 输出控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

简单进行查找操作,查找所有数据

package com.example.demo.mapper;
import com.example.demo.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;@Mapper
public interfance UserInfoMapper{@Select("select username, password, age, gender, phone from user_info")public List<UserInfo> getAll();
}

 使用idea自带的测试生成功能,在UserInfoMapper接口下右键-Generate-test,选择要生成的测试代码编写测试代码,注意要在类加上@SpringBootTest注解,运行@Test注解旁边的启动按钮即可启动测试

@SpringBootTest
class UserInfoTest{@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid getAll() {List<UserInfo> list = userInfoMapper.getAll();System.out.println(list);}
}

 2.2. 传递参数

在刚才的UserInfoMapper接口里加入新的代码,使用#{}获取方法中的参数,建议把#{}内部的参数跟形参名保持一致

还可以使用@Param进行重命名,如果重命名,那么value必须和#{}中的值保持一致!!

 2.3 新增

直接构造一个对象然后插入

从上面可以看到insert返回值是数据库中受影响的行数,有时要求返回数据库中的某个值,比如一个购物网站,用户下单之后需要给用户返回一个订单号,这个订单号一般是自动生成的,此时就需要使用新的注解。

userGeneratedKeys:默认值是false。设置为true,这会令JDBC执行getGenerateKey,获取到数据库中的主键(一般是MySQL数据库中的自增字段)

keyProperty:指定唯一能够识别对象的属性,默认的值是useGeneratedKeys的返回值或者insert语句的selectKey子元素,默认值未设置(unset)

上面演示所示,可以看到count拿到的还是受到返回的行数,返回值类型还是数字。自增id会设置在keyProperty指定的属性当中。 

2.4 删和改

删和改一起展示

 可以看到id=9的行已经删除了,id=10的username已经修改为zhaoliu。

2.5 查

可以看到,红框中的三个字段的值都为null。为什么没有获取到?

可以看到我们自己定义的对象中的属性使用的是驼峰式,但数据库中的字段是以下划线来进行连接的,所以自然没办法获取到。有三种方法可以解决这个问题:1. 配置application文件 2. 结果映射 3. 起别名

1. 配置文件开启驼峰命名(推荐方法)

#properties:
mybatis.configuration.map-underscore-to-camel-case=true#yml:
mybatis:configuration:map-underscore-to-camel-case: true

2. 结果映射

@Select("select id, username, `password`, age, gender, phone, delete_flag, 
create_time, update_time from user_info")
@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 user_info where id= #{userid} ")
@ResultMap(value = "resultMap")
UserInfo queryById(@Param("userid") Integer id);

 3. 起别名

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

已经可以获取到了。

3. xml 

上面的注解方式只适合于简单的sql操作,一些复杂的sql操作最好使用xml的方式。

3.1 持久层代码

刚才介绍的注解方法,持久层代码只创建了一个接口,然后用idea自带的测试功能进行测试。

xml的持久层代码需要创建两个:

1. 方法定义:interface

2. 方法实现:xml文件

先来配置文件

# 数据库连接配置 yml配置方式
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: 1234driver-class-name: com.mysql.cj.jdbc.Driver
# 配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件
mybatis:mapper-locations: classpath:mapper/**Mapper.xmlconfiguration:map-underscore-to-camel-case: true
#驱动类名称 properties配置方式
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
#连接数据库的⽤⼾名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=1234
# 配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件
mybatis.mapper-locations=classpath:mapper/**Mapper.xml
#下划线转驼峰
mybatis.configuration.map-underscore-to-camel-case=true
#指定mybatis输出⽇志的位置, 输出控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

3.2 查 

创建接口跟刚才一样,下面来进行xml文件的编写,xml文件的配置是固定的,就是下面这个格式。

import com.example.demo.UserInfo;
import org.apache.ibatis.annotations.Mapper;import java.util.List;@Mapper
public interface UserInfoXmlMapper {List<UserInfo> queryAllUser();
}
<?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=""></mapper>

 

创建xml文件的路径要跟yml中配置的路径相同,并且必须以Mapper.xml结尾,笔者命名的是UserMapper.xml,前面的User可以自定义,但是后面必须跟yml中的保持一致

在xml中编写select语句 

mapper标签中的namespace中写的是接口的全限定名称

select标签中的id中写的是方法名,resultMap写的是返回的数据类型,只有select标签需要加resultMap

3.3 增

#返回自增id
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">insert into user_info (username, `password`, age, gender, phone) values(#{userInfo.username},#{userInfo.password},#{userInfo.age},#
{userInfo.gender},#{userInfo.phone})
</insert>

3.4  删

 

 3.5 改

 4. 多表查询

再创建一个表以完成多表查询

CREATE TABLE articleinfo (id INT PRIMARY KEY auto_increment,title VARCHAR ( 100 ) NOT NULL,content TEXT NOT NULL,uid INT NOT NULL,delete_flag TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',create_time DATETIME DEFAULT now(),update_time DATETIME DEFAULT now() 
) DEFAULT charset 'utf8mb4';
-- 插⼊测试数据
INSERT INTO articleinfo ( title, content, uid ) VALUES ( 'Java', 'Java正⽂', 1
);
import lombok.Data;
import java.util.Date;
@Data
public class ArticleInfo {private Integer id;private String title;private String content;private Integer uid;private Integer deleteFlag;private Date createTime;private Date updateTime;
//⽤⼾相关信息private String username;private Integer age;private Integer gender;
}
import com.example.demo.ArticleInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;@Mapper
public interface ArticleInfoMapper {@Select("SELECT ta.id,ta.title,ta.content,ta.uid,tb.username,tb.age,tb.gender " +"FROM articleinfo ta LEFT JOIN user_info tb ON ta.uid = tb.id " +"WHERE ta.id = #{id}")ArticleInfo queryUserByUid(Integer id);
}

5. #{}和${}的区别

前面代码中展示的都是#{},还有一种写法是${},那么他们的区别是什么呢?

之前使用#{}时运行时可以看到使用?来作为占位符,这种称为“预编译SQL”

换成${}

 

发现id的位置直接拼接成了数字,而不是占位符"?" 

接下来把where条件变成查询username,发现报错了,可以看到直接把admin拼接到了后面,没有加引号,这就是报错的原因。而#{}会根据数据类型自动拼接引号,如果不想报错需要修改为:'${username}',此处不做展示了

 总结一下:

#{}使用的预编译SQL,会先进行编译,用?作为占位符,然后再把参数填充进去。

${}使用的是即时sql,需要自行填充引号。

6. 预编译SQL和即时SQL的区别是什么?

1. 预编译SQL的性能更高:比如select语句,上面刚才举例区别是一个where条件用的是id字段,另一个用的是username字段,所以他们之间的区别很小,预编译SQL当编译第一次的时候会将编译后的sql语句缓存起来,下次再使用的时候直接使用,不用再次编译,提高了效率。

2. 预编译SQL可以防止SQL注入,SQL注入是:通过操作修改的数据来修改事先定义好的sql功能,达到攻击数据库的目的,比如有的登录场景,一些攻击者会在密码框内加入sql关键字,就可以直接登录成功。

虽然${}有上面这两个缺点,但是也有它的优点,一个是当有排序的场景的时候必须使用${},使用 #{}会报错,原因是#{}自动拼接了引号,导致sql语句出错

@Select("select id, username, age, gender, phone, delete_flag, create_time, 
update_time " +"from user_info order by id ${sort} ")
List<UserInfo> queryAllUserBySort(String sort);

另一个是使用like操作,#{}一样会报错,但是${}会导致sql注入,所以加入了concat()函数

@Select("select id, username, age, gender, phone, delete_flag, create_time, 
update_time " +"from user_info where username like concat('%',${key},'%')")
List<UserInfo> queryAllUserByLike(String key);

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDEA配置本地maven

因为idea和maven是没有直接关系的。所以使用idea创建maven工程之前需要将本地的maven配置到idea环境中&#xff0c;这样才可以在idea中创建maven工程。配置方法如下&#xff1a; 1.1 配置本地maven 第一步&#xff1a;关闭当前工程&#xff0c;回到idea主界面找到customize--…

论文阅读——Intrusion detection systems using longshort‑term memory (LSTM)

一.基本信息 论文名称&#xff1a;Intrusion detection systems using longshort‑term memory (LSTM) 中文翻译&#xff1a;基于长短期记忆(LSTM)的入侵检测系统 DOI&#xff1a;10.1186/s40537-021-00448-4 作者&#xff1a;FatimaEzzahra Laghrissi1* , Samira Douzi2*, Kha…

企业OA管理系统:Spring Boot技术实现与案例研究

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了企业OA管理系统的开发全过程。通过分析企业OA管理系统管理的不足&#xff0c;创建了一个计算机管理企业OA管理系统的方案。文章介绍了企业OA管理系统的系统分析部…

递归算法专题一>Pow(x, n)

题目&#xff1a; 解析&#xff1a; 代码&#xff1a; public double myPow(double x, int n) {return n < 0 ? 1.0 / pow(x,-n) : pow(x,n); }private double pow(double x, int n){if(n 0) return 1.0;double tmp pow(x,n / 2);return n % 2 0 ? tmp * tmp : tmp …

阿里云私服地址

1.解压apache-maven-3.6.1-bin 2.配置本地仓库&#xff1a;修改conf/dettings.xml中的<localReoisitory>为一个指定目录。56行 <localRepository>D:\apache-maven-3.6.1-bin\apache-maven-3.6.1\mvn_repo</localRepository> 3.配置阿里云私服&#xff1a;…

基于之前的秒杀功能的优化(包括Sentinel在SpringBoot中的简单应用)

这篇博客主要是对自己之前写的博客的一次优化&#xff0c;可以结合下面两篇博客进行这篇博客的阅读&#xff1a; 对自己关于秒杀功能的一次访谈与实战-CSDN博客 SpringBoot中使用Sharding-JDBC实战&#xff08;实战版本兼容Bug解决&#xff09;-CSDN博客 开始正题&#xff1a…

Redis Search系列 - 第七讲 Windows(CygWin)编译Friso

目录 一、背景二、安装CygWin三、编译Friso四、运行Friso五、Friso分词效果测试 一、背景 最近在做RedisSearch的中文分词效果调研&#xff0c;底层的中文分词插件使用的就是Friso&#xff0c;目前手里的Linux环境上yum镜像仓库有问题导致没法安装gcc&#xff0c;又急于验证Fr…

(动画)Qt控件 QLCDNumer

文章目录 LCD Number1. 介绍2. 核心属性3 . 代码实现:倒计时1. 在界⾯上创建⼀个 QLCDNumber , 初始值设为 10.2. 修改 widget.h 代码, 创建⼀个 QTimer 成员, 和⼀个 updateTime 函数3. 修改 widget.cpp, 在构造函数中初始化 QTimer4. 修改 widget.cpp, 实现 updateTime 4. 动…

《操作系统 - 清华大学》4 -5:非连续内存分配:页表一反向页表

文章目录 1. 大地址空间的问题2. 页寄存器&#xff08; Page Registers &#xff09;方案3. 基于关联内存(associative memory )的反向页表&#xff08;inverted page table&#xff09;4. 基于哈希&#xff08;hashed&#xff09;查找的反向页表5. 小结 1. 大地址空间的问题 …

web前端开发--动画效果

1、3D旋转 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>3D旋转</title><style type"text/css">div{/*设置大盒子样式*/width: 100px;height: 100px;/*background-color: rgba(255,0,0,0.5);*/ba…

linux入门——“僵尸进程、孤儿进程”

引入 在linux中&#xff0c;特别是我们自己写代码时&#xff0c;使用fork&#xff08;&#xff09;创建子进程的时候&#xff0c;需要知道两种特殊的进程——僵尸进程、孤儿进程。这是我们不可忽视的进程的两种特殊情况。 一、僵尸进程 在C语言编程中&#xff0c;僵尸进程的出…

【数据结构 | C++】部落

在一个社区里&#xff0c;每个人都有自己的小圈子&#xff0c;还可能同时属于很多不同的朋友圈。我们认为朋友的朋友都算在一个部落里&#xff0c;于是要请你统计一下&#xff0c;在一个给定社区中&#xff0c;到底有多少个互不相交的部落&#xff1f;并且检查任意两个人是否属…

维护在线重做日志(一)

学习目标 解释在线重做日志文件的目的概述在线重做日志文件的结构控制日志开关和检查点多路复用和维护在线重做日志文件使用OMF管理在线重做日志文件获取在线重做日志文件信息 在线重做日志文件提供了在数据库发生故障时重做事务的方法。 每个事务都同步写入重做日志缓冲区&a…

mayo介绍和QTqmake编译基于Opencascade开发的mayo工程-小白配置

目录: 一、mayo介绍:zap: 最新功能&#xff08;截止7.8.2&#xff09;在这里插入图片描述 二、编译准备三、编译过程3.1QT Creator打开源码的pro工程3.2修改几处pro配置3.3复制所需的动态链接库3.4编译完成 一、mayo介绍 1️⃣mayo是一个基于opencascade开源库开发的一个开源CA…

【Github】如何使用Git将本地项目上传到Github

【Github】如何使用Git将本地项目上传到Github 写在最前面1. 注册Github账号2. 安装Git工具配置用户名和邮箱仅为当前项目配置&#xff08;可选&#xff09; 3. 创建Github仓库4. 获取仓库地址5. 本地操作&#xff08;1&#xff09;进入项目文件夹&#xff08;2&#xff09;克隆…

【layui】table的switch、edit修改

<title>简单表格数据</title><div class"layui-card layadmin-header"><div class"layui-breadcrumb" lay-filter"breadcrumb"><a>系统设置</a><a>简单表格数据</a></div> </div>&…

Spring Template

Thymeleaf 入门 Web 开发离不开动态页面的开发&#xff0c;很早以前企业主要使用 JSP 技术来开发网页&#xff0c;随着技术的升级更替&#xff0c;目前来说最主流的方案是&#xff1a;Thymeleaf&#xff0c;Thymeleaf 是一个模板框架&#xff0c;它可以支持多种格式的内容动态…

【大语言模型】ACL2024论文-20 SCIMON:面向新颖性的科学启示机器优化

【大语言模型】ACL2024论文-20 SCIMON&#xff1a;面向新颖性的科学启示机器优化 目录 文章目录 【大语言模型】ACL2024论文-20 SCIMON&#xff1a;面向新颖性的科学启示机器优化目录摘要研究背景问题与挑战如何解决创新点算法模型实验效果推荐阅读指数&#xff1a;★★★★☆ …

HTML实现 扫雷游戏

前言&#xff1a; 游戏起源与发展 扫雷游戏的雏形可追溯到 1973 年的 “方块&#xff08;cube&#xff09;” 游戏&#xff0c;后经改编出现了 “rlogic” 游戏&#xff0c;玩家需为指挥中心探出安全路线避开地雷。在此基础上&#xff0c;开发者汤姆・安德森编写出了扫雷游戏的…

docker镜像源配置、换源、dockerhub国内镜像最新可用加速源(仓库)

一、临时拉取方式 在docker pull后先拼接镜像源域名&#xff0c;后面拼接拉取的镜像名 $ docker pull dockerpull.org/continuumio/miniconda3 二、永久配置方式 vim修改/etc/docker/daemon.json&#xff0c;并重启docker服务。 # 创建目录 sudo mkdir -p /etc/docker# 写…