1,配置相关

我们上一期详细讲了一下使用注解来实现操作数据库的方式,我们今天使用xml来实现,有同学可能有疑问,使用注解挺方便呀,为啥还要注解呀,先来说一下注解我感觉挺麻烦的,但是我们后面要学动态SQL,注解就要要重写一遍xml到注解,更麻烦了,所以我们还是要学这个,xml和注解是可以共存的,所以不怕冲突;

我们先来准备工作:

根据数据库创建model字段,

@Data
public class userInfo {private Integer id;private String userName;private String password;private Integer deleteFlag;private Date createTime;private Date updateTime;
}

 

下一个这个插件:

写yml配置:
 

  # 数据库连接配置datasource:url: jdbc:mysql://127.0.0.1:3306/book_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:configuration:map-underscore-to-camel-case: true #配置驼峰⾃动转换log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印sql语句mapper-locations: classpath:mapper/**Mapper.xml

最后一行就是yml的配置了,这一行的意思是我们在resources路径下创建一个mapper包,里面放一个~~名后后缀是Mapper.xml的文件,这个可以自己起名;

之后在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="org.example.java_test_6_7.mapper.UserMapper"></mapper>

 这个namespace对应的是自己项目名,后面.mapper.UserMapper对应的是这块

 下面我们点击那个小蓝鸟,如果能跳转到小红鸟那,就说明我们跳转成功了;、


2,CRUD

1,增

@Mapper
public interface UserMapper {void insertUserInfo(UserInfo userInfo);
}

之后在mapper中写:(可以直接alt+enter生成)

    <insert id="insertUserInfo"></insert>

 

注意这个要顶格写

    <insert id="insertUserInfo">insert into user_info (user_name,password,delete_flag) values (#{userName},#{password},#{deleteFlag})</insert>
@SpringBootTest
class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testvoid insertUserInfo() {UserInfo userInfo = new UserInfo();userInfo.setUserName("yaoyu");userInfo.setPassword("12412");userInfo.setDeleteFlag(0);userMapper.insertUserInfo(userInfo);}
}

 写测试类,测试通过,看看效果:

增添成功了; 

2,删

把刚才添加的字段删了:
 

    void deleteUserInfoById(Integer id);
    <delete id="deleteUserInfoById">delete from user_info where id = #{id}</delete>
    @Testvoid deleteUserInfoById() {userMapper.deleteUserInfoById(11);}

 删除成功了。

3,查

    UserInfo selectUserInfoBYId(Integer id);
    <select id="selectUserInfoBYId" resultType="org.example.java_test_6_7.model.UserInfo">select * from user_info where id = #{id}</select>
    @Testvoid selectUserInfoBYId() {UserInfo userInfo = userMapper.selectUserInfoBYId(1);System.out.println(userInfo);}

成功查询并拿到值了; 

4,改

void updateUserInfoById(UserInfo userInfo);
    <update id="updateUserInfoById">update user_info set user_name=#{userName}, password=#{password} ,delete_flag=#{deleteFlag} where id =#{id}</update>
    @Testvoid updateUserInfoById() {UserInfo userInfo = new UserInfo();userInfo.setId(1);userInfo.setUserName("姚宇");userInfo.setPassword("3141");userInfo.setDeleteFlag(0);userMapper.updateUserInfoById(userInfo);}

OK了 

5,java和数据库参数名对应不上

还是那三个方法

1,使用as

2,结果映射

3,驼峰自动转换

1和3跟注解是一模一样的就不讲了,这里我们讲结果映射:

UserInfo selectUserInfoBYId2(Integer id);
    <resultMap id="base" type="org.example.java_test_6_7.model.UserInfo"><result column="delete_flag" property="deleteFlag"></result><result column="user_name" property="userName"></result><result column="create_time" property="createTime"></result><result column="update_time" property="updateTime"></result></resultMap>
    @Testvoid selectUserInfoBYId2() {UserInfo userInfo = userMapper.selectUserInfoBYId2(1);System.out.println(userInfo);}

 看结果:

OK的,这里我已经把驼峰自动转换关掉了; 


3,多表查询

再来一个表,我们来弄model ;

@Data
public class BookInfo {private Integer id;private String bookName;private String author;private Integer count;private BigDecimal price;private String publish;private Integer status;private Date createTime;private Date updateTime;
}

来写一个多表查询语句 

SELECT bo.id, bo.book_name, bo.author, uo.user_name, uo.`password` FROM user_info uo LEFT JOIN book_info bo ON bo.id = uo.id WHERE bo.id = 1

 

结果,那我们该怎么接收它呢,我们只需要再创建一个对象,对应这个字段的属性就好了;

@Data
public class Testselect {private Integer id;private String bookName;private String author;private String userName;private String password;
}
    @Select("SELECT bo.id, bo.book_name, bo.author, uo.user_name, uo.`password` FROM user_info uo LEFT JOIN book_info bo ON bo.id = uo.id WHERE bo.id = #{id}")TestSelect selectUserInfoAndBookInfoById(Integer id);
    @Testvoid selectUserInfoAndBookInfoById() {TestSelect testSelect = userMapper.selectUserInfoAndBookInfoById(1);System.out.println(testSelect);}

 

 成功查到了


4,#{}和${}的区别

现在来正式讲一下$和#,

看一下#号的,这个 id后面是一个?下面表示它要填写的值,这个是预编译SQL用?来站位

看下用${}的:

    @Select("select * from user_info where id = ${id}")UserInfo selectUserInfoById3(Integer id);
    void selectUserInfoById3() {UserInfo userInfo = userMapper.selectUserInfoById3(1);System.out.println(userInfo);}

看到是没有任何占位符的,这个是即时SQL,

    @Select("select * from user_info where user_name = ${userName}")UserInfo selectUserInfoById4(String userName);

 来看看这个字符串的

    @Testvoid testSelectUserInfoById4() {UserInfo userInfo = userMapper.selectUserInfoById4("姚宇");System.out.println(userInfo);}

发现报错了啊, 这说明是SQL语句出现了问题的,这个是因为是直接拼接的,没有引号,正常字符串是需要加引号的,

    @Select("select * from user_info where user_name = '${userName}'")UserInfo selectUserInfoById4(String userName);

 

这下就通过了; 

我们来具体说说区别:
主要区别就是即时SQL和预编译SQL的区别;

即时SQL呢,首先解析语法和语句,检验SQL是否正确,优化SQL语句,指定执行计划,之后执行返回结果;

1. 性能更⾼ 绝⼤多数情况下,某⼀条SQL语句可能会被反复调⽤执⾏,或者每次执⾏的时候只有个别的值不同(⽐ 如select的where⼦句值不同,update的set⼦句值不同,insert的values值不同).如果每次都需要 经过上⾯的语法解析,SQL优化、SQL编译等,则效率就明显不⾏了.

预编译SQL,编译⼀次之后会将编译后的SQL语句缓存起来,后⾯再次执⾏这条语句时,不会再次编译 (只是输⼊的参数不同),省去了解析优化等过程,以此来提⾼效率

1. 更安全(防⽌SQL注⼊) SQL注⼊:是通过操作输⼊的数据来修改事先定义好的SQL语句,以达到执⾏代码对服务器进⾏攻击的 ⽅法。 

这个SQL注入是很严重的,那我们还有使用$的必要了吗,当然是有的,我们可以自己处理来预防SQ注入,还有一些功能是需要使用$而#是用不了的

1,排序

    @Select("select * from book_info order by id ${sort}")List<BookInfo> selectBooInfoOrderById(String sort);
    @Testvoid selectBooInfoOrderById() {userMapper.selectBooInfoOrderById("DESC");}

查到了;

为啥只能用$呢,因为sql中这个DESC是不加''号的,但是使用#的话会把我们传入的字符串自动加引号,但是sql语法是不对的;

2,like

    @Select("select * from book_info where book_name like concat('%','${key}','%')")List<BookInfo> selectBooInfoLike(String key);
    @Testvoid selectBooInfoLike() {userMapper.selectBooInfoLike("");}

 

 

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

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

相关文章

【推荐算法】推荐算法演进史:从协同过滤到深度强化学习

推荐算法演进史&#xff1a;从协同过滤到深度强化学习 一、传统推荐时代&#xff1a;协同过滤的奠基&#xff08;1990s-2006&#xff09;1.1 算法背景&#xff1a;信息爆炸的挑战1.2 核心算法&#xff1a;协同过滤1.3 局限性 二、深度学习黎明&#xff1a;神经网络初探&#xf…

Java基于SpringBoot的校园闲置物品交易系统,附源码+文档说明

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…

Ajax Systems公司的核心产品有哪些?

Ajax Systems 是一家专注于家庭安全和智能系统的公司&#xff0c;其核心产品如下3&#xff1a; 入侵保护设备&#xff1a;如 MotionCam Outdoor 无线室外运动探测器&#xff0c;配备内置摄像头和两个红外传感器&#xff0c;可通过预装电池运行长达三年&#xff0c;能在 15 米距…

64、js 中require和import有何区别?

在 JavaScript 中&#xff0c;require 和 import 都是用于模块导入的语法&#xff0c;但它们属于不同的模块系统&#xff0c;具有显著的区别&#xff1a; 1. 模块系统不同 require 属于 CommonJS 模块系统&#xff08;Node.js 默认使用&#xff09;。 语法&#xff1a;const…

Java+Access综合测评系统源码分享:含论文、开题报告、任务书全套资料

JAVAaccess综合测评系统毕业设计 一、系统概述 本系统采用Java Swing开发前端界面&#xff0c;结合Access数据库实现数据存储&#xff0c;专为教育机构打造的综合测评解决方案。系统包含学生管理、题库管理、在线测评、成绩分析四大核心模块&#xff0c;实现了测评流程的全自…

【python】RGB to YUV and YUV to RGB

文章目录 1、YUV2、YUV vs RGB3、RGB to YUV4、YUV to RGB附录——YUV NV12 vs YUV NV21参考1、YUV YUV 颜色空间,又常被称作 YCbCr 颜色空间,是用于数字电视的颜色空间,在 ITU-R BT.601、BT.709、BT.2020 标准中被明确定义,这三种标准分别针对标清、高清、超高清数字电视…

运行示例程序和一些基本操作

欢迎 ----> 示例 --> 选择sample CTRL B 编译代码 CTRL R 运行exe 项目 中 Shadow build 表示是否 编译生成文件和 源码是否放一块 勾上不在同一个地方 已有项目情况下怎么打开项目 方法一: 左键双击 xxx.pro 方法二: 文件菜单里面 选择打开项目

计算机网络第2章(下):物理层传输介质与核心设备全面解析

目录 一、传输介质1.1 传输介质的分类1.2 导向型传输介质1.2.1 双绞线&#xff08;Twisted Pair&#xff09;1.2.2 同轴电缆&#xff08;Coaxial Cable&#xff09;1.2.3 光纤&#xff08;Optical Fiber&#xff09;1.2.4 以太网对有线传输介质的命名规则 1.3 非导向型传输介质…

PHP文件包含漏洞详解:原理、利用与防御

PHP文件包含漏洞详解&#xff1a;原理、利用与防御 什么是文件包含漏洞&#xff1f; 文件包含漏洞是PHP应用程序中常见的安全问题&#xff0c;当开发者使用包含函数引入文件时&#xff0c;如果传入的文件名参数未经严格校验&#xff0c;攻击者就可能利用这个漏洞读取敏感文件…

5.4.2 Spring Boot整合Redis

本次实战主要围绕Spring Boot与Redis的整合展开&#xff0c;首先创建了一个Spring Boot项目&#xff0c;并配置了Redis的相关属性。接着&#xff0c;定义了三个实体类&#xff1a;Address、Family和Person&#xff0c;分别表示地址、家庭成员和个人信息&#xff0c;并使用Index…

java内存模型JMM

Java 内存模型&#xff08;Java Memory Model&#xff0c;JMM&#xff09;定义了 Java 程序中的变量、线程如何和本地内存以及主内存进行交互的规则。它主要涉及到多线程环境下的共享变量可见性、指令重排等问题&#xff0c;是理解并发编程中的关键概念。 核心概念&#xff1a…

配置git命令缩写

以下是 Git 命令缩写的配置方法及常用方案&#xff0c;适用于 Linux/macOS/Windows 系统&#xff1a; &#x1f527; 一、配置方法 1. 命令行设置&#xff08;推荐&#xff09; # 基础命令缩写 git config --global alias.st status git config --global alias.co che…

准确--k8s cgroup问题排查

k8s cgroup问题排查 6月 06 17:20:39 k8s-node01 containerd[1515]: time"2025-06-06T17:20:39.42902033408:00" levelerror msg"StartContainer fo r \"46ae0ef9618b96447a1f28fd2229647fe671e8acbcec02c8c46b37051130c8c4\" failed" error&qu…

Go 中 map 的双值检测写法详解

Go 中 map 的双值检测写法详解 在 Go 中&#xff0c;if char, exists : pairs[s[i]]; exists { 是一种利用 Go 语言特性编写的优雅条件语句&#xff0c;用于检测 map 中是否存在某个键。让我们分解解释这种写法&#xff1a; 语法结构解析 if value, ok : mapVariable[key]; …

C# Wkhtmltopdf HTML转PDF碰到的问题

最近碰到一个Html转PDF的需求&#xff0c;看了一下基本上都是需要依赖Wkhtmltopdf&#xff0c;需要在Windows或者linux安装这个可以后使用。找了一下选择了HtmlToPDFCore&#xff0c;这个库是对Wkhtmltopdf.NetCore简单二次封装&#xff0c;这个库的好处就是通过NuGet安装HtmlT…

grafana 批量视图备份及恢复(含数据源)

一、grafana 批量视图备份 import requests import json import urllib3 import osfrom requests.auth import HTTPBasicAuthfilename_folders_map "folders_map.json" type_folder "dash-folder" type_dashboard "dash-db"# Grafana服务器地…

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…

露亦如电 · 时之沙 | 让遗憾在灰烬里随风而去

注&#xff1a;略作重排&#xff0c;未整理去重。 一个人最了不起的能力&#xff1a;快速翻篇 原创 十点邀约作者 棠唐 2022 年 11 月 29 日 20:12 福建 《了凡四训》有言&#xff1a;“从前种种&#xff0c;譬如昨日死&#xff1b;从后种种&#xff0c;譬如今日生。” 人生犹…

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…

FastAPI安全机制:从OAuth2到JWT的魔法通关秘籍

title: FastAPI安全机制:从OAuth2到JWT的魔法通关秘籍 date: 2025/06/07 08:40:35 updated: 2025/06/07 08:40:35 author: cmdragon excerpt: FastAPI 的安全机制基于 OAuth2 规范、JWT 和依赖注入系统三大核心组件,提供了标准化的授权框架和无状态的身份验证。OAuth2 密码流…