【javaWeb 第八篇】后端-Mybatis(万字详细学习)

news2024/11/27 18:33:31

Mybatis框架

  • 前言
  • Mybatis
    • Mybatis入门
    • 配置SQL提示
    • JDBC
    • 数据库连接池
    • lombok
  • Mybatis基础操作
    • 日志输出
    • Mybatis的动态SQL

前言

这篇是作者学习数据持久层框架Mybatis的学习笔记,希望对大家有所帮助,希望大家能够与作者交流讨论

Mybatis

Mybatis是一款优秀的持久层框架,用于简化JDBC的开发
Mybatis自2013年11月迁移到GitHub中,源码由GitHub管理

官网:https://mybatis.org/mybatis-3/zh/index.html
本片讲解的是基于SpringBoot整合Mybatis来进行讲解

Mybatis入门

  • 使用Mybatis查询所有的用户数据

入门基础操作:

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

Mybatis通过java访问数据库服务器,将返回回来的数据封装到实体类当中
在引入Mybatis的相关依赖的时候需要连接数据库(知道自己要访问哪一个数据库),需要Mybatis数据库连接四要素:
标记数据库驱动的全类名
数据库连接的URL
用户名
密码


spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
spring.datasource.username=root
spring.datasource.password=

在进行数据库的SQL语句编写的时候需要注意定义一个数据层接口

@Mapper
public interface UserMapper{
@select("select * from user")
public List<User> list();
}

使用注解 @Mapper来定义数据层接口,通过注解定义SQL语句, @select表示是查询操作,其中写入查询语句,当要执行次查询语句的时候调用下方的list方法就可以,这时框架会自动的执行SQL语句,并将结果封装到方法的返回值当中

如何配置mybatis,与数据库建立连接
在resources中打开application.properties文件(sping自带的默认配置文件)
在其中将连接四要素配置进去

# 驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据库连接的URL
spring.datasource.url=jdbc:mysql://localhost:3306/ mybatistest
# 连接数据库的用户名
spring.datasource.username=root
# 连接数据库的密码
spring.datasource.password=

进行测试:

@Mapper //在运行时,会自动生成该接口的实现类对象(代理对象),并且该对象交由IOC容器管理
public interface UserMapper {
    @Select("select * from user")
    public List<User> list();
}

测试通过test文件下的测试类进行测试
测试类中的注解 @SpringBootTest表示springboot整合单元测试的注解

@SpringBootTest
class MybatisTestApplicationTests {
    @Autowired
    private UserMapper userMapper;
    @Test
    void contextLoads() {
        List<User> list = userMapper.list();
        list.stream().forEach(user -> {
            System.out.println(user);
        });
    }

}

前面所说的UserMapper接口由IOC代理,所以使用依赖注入的方式在测试类中创建对象,通过stream流的方式将数据进行遍历

最后运行测试,由于此单元测试是spring整合的单元测试,在运行的时候会自动的加载整个spring环境,创建spring的IOC容器

配置SQL提示

默认在mybatis中编写SQL语句是不识别的,可以通过配置进行识别:
在这里插入图片描述
将sql语句全选右键选择
在这里插入图片描述
再次进行选择
在这里插入图片描述
选择Mysql(sql)
这个时候再次输入SQL语句就会有响应的提示,但是在输入表名的时候没有进行提示,这是因为:idea和数据库没有建立连接,不识别表信息

  • 解决方式
    在idea中配置MySQL数据库连接
    在这里插入图片描述
    配置idea连接MySQL数据库
    注意:配置完成后没有表的刷新一下就行了

JDBC

就是使用java语言操作关系型数据库的一套API



驱动
什么是驱动:
java提供一个可供操作的接口JDBC各个数据库厂商通过实现实现接口将自己的数据库操作引入到java中,提供数据库驱动jar包,这个实现的过程就称为数据库的驱动,我们通过使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类

  • 原始的JDBC操作数据库
    @Test
    public void jdbctest() throws Exception{
        //注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //获取连接对象
        String url="jdbc:mysql://localhost:3306/mybatistest";
        String username="root";
        String password="";
        Connection connection= DriverManager.getConnection(url,username,password);
        //获取执行sql的对象statement,执行SQL,返回结果
        String sql="select * from user";
        //通过connection创建一个statement对象用来将sql语句与数据库联系执行
        Statement statement = connection.createStatement();
        //通过执行查询语句返回一个ResultSet结果集,用来封装得到的数据
        ResultSet resultSet=statement.executeQuery(sql);

        //解析并封装结果数据(需要一个一个字段的继续宁解析)
        List<User> list=new ArrayList<>();
        while (resultSet.next())
        {
            //在解析的时候需要一个字段一个字段进行解析
            int id=resultSet.getInt("id");
            String name=resultSet.getString("name");
            int age=resultSet.getInt("age");
            int gender=resultSet.getInt("gender");
            String phone=resultSet.getString("phone");
            User user=new User(id,name,age,gender,phone);
            list.add(user);
        }
        //释放资源
        statement.close();
        connection.close();
    }

在JDBC原始代码中进行数据库的连接与最后释放资源都是非常繁琐且损耗效率的。

数据库连接池

数据库连接池是一个容器,负责分配,管理数据库连接(Connetion)
它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个
释放空间时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏
数据库连接池的优势:
资源重用,提示系统响应速度,避免数据库连接遗漏

数据库连接池:
由官方提供一个标准接口:DataSource,所有的数据库连接池都必须实现DataSource
官方提供的数据库连接池接口,由第三方实现此接口
现在项目中使用的最多的连接池:Druid,Hikari(springboot默认)

  • Druid(德鲁伊)
    是阿里巴巴开源的数据库连接池项目,功能强大,性能优秀,是java语言最好的数据库连接池之一

  • 如何切换连接池

  1. 首先引进Druid的依赖
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
  1. 第二步
    同上述一样通过连接四要素进行数据库连接
# 驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据库连接的URL
spring.datasource.url=jdbc:mysql://localhost:3306/ mybatistest
# 连接数据库的用户名
spring.datasource.username=root
# 连接数据库的密码
spring.datasource.password=

或者

# 驱动类名称
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据库连接的URL
spring.datasource.druid.url=jdbc:mysql://localhost:3306/ mybatistest
# 连接数据库的用户名
spring.datasource.druid.username=root
# 连接数据库的密码
spring.datasource.druid.password=

lombok

Lombok是一个实用的的java类库,能够通过注解的形式自动生成构造器,getter/setter,equals,hascode,toString等方法,并可以自动化生成日志变量,简化java开发,提高效率

注解
首先在pom.xml中提供lombok的依赖


        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

注意:这里不需要版本号,因为在父工程依赖中已经集成lombok并对其版本进行管理


/*@Getter
@Setter
@ToString
@EqualsAndHashCode*/ //这四个注解集成到一个注解当中
@Data
@NoArgsConstructor  //无参构造注解
@AllArgsConstructor  //全参构造注解
public class User {
    private Integer id;
    private String name;
    private Integer age;
    private Integer gender;
    private String phone;
}

Mybatis基础操作

  • 删除
    根据主键传回来的id进行删除

此处用到mybatis提供的参数占位符 #{}

@Mapper
public interface EmpMapper {
    @Delete("delete from emp where id=#{id}}")
    public void delete(Integer id);
}

在测试类中进行测试

@SpringBootTest
class Projecttest1ApplicationTests {
    @Autowired
    private EmpMapper empMapper;
    @Test
    void contextLoads() {
        empMapper.delete(2);
    }

}

注意:如果Mapper接口方法形参只有一个普通类型的参数,#{…}里面的属性名可以随便写,如#{id},#{value}

  • 新增

    @Insert("insert into user (username,name,gender,image,job,entrydate,dept_id,create_time,update_time) values(#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})")
    public void insert(Emp emp);

主键返回功能:
在数据添加成功后,需要获取插入数据库数据的关键
需要注解 @options(keyProperty=‘id’,useGeneratedKeys=true) (第一个参数表示获取的主键封装到哪个属性,第二个参数表示我们要返回主键值) //注解会自动生成主键值,赋值给emp对象的id属性值

  • 更新
    //更新数据
    @Update("update emp set username=#{username} ... where id=#{id}")
    public void update(Emp emp);
  • 查询(条件查询)

举例一个条件,根据输入的姓名,性别,入职时间,搜索满足条件的员工信息,其中姓名支持模糊匹配,对应的sql语句是

select * from emp where name like '%张%' and gender=1 and entrydate between '' and '' order by update_time desc;

对应的操作:


    //条件查询员工信息
    @Select("select * from emp where name like '%#{name}%' "+
            "and gender=#{gender} and entrydate between #{begin} and #{end} order by update_time desc")
    public List<Emp> list(String name, Short gender, LocalDate begin,LocalDate end);
}

注意: #{} 不能出现在引号当中,需要把此处的#换成$
但是这样就出现了性能低,不安全,存在SQL注入的问题,所以我们还可以使用mysql提供的字符串拼接函数concat
上述就可以修改为

concat('%',#{name},'%')
  • 数据封装
    实体类属性名和数据库表查询返回的字段名一致,mybatis会自动进行封装
    如果实体类属性名和数据库表查询返回的字段名不一致,不能自动封装
    如何解决?

方法一:给字段起别名,让别名与实体类属性一致
方法二:通过 @Results@Result 注解手动映射封装

@Results({@Result(column="",property="")}) //Results就是一个一个的Result注解,注解中定义映射,前一个参数时表中的字段名,后一个参数表示需要映射到的属性名

(推荐使用)方法三:开启mybatis的驼峰命名自动映射开关(下划线会自动封装到对应的驼峰命名的属性)
需要在spring配置文件中进行配置
mybatis.configuration.map-underscore-to-camel-case=true

日志输出

虽然我们使用mybatis进行数据操作,但是我们并不知道mybatis底层是如何执行操作的,我们可以在spring配置文件中打开mybatis的日志,并指定输出到控制台

配置信息:
mybatis.configuration.log-impl=org.apache.lbatis.logging.stdout.StdOutImpl
意思是要往控制台传输日志
输出结果如下:
预编译
此处是SQL预编译,在运行的时候系统将两条消息一起发送给数据库
为什么这样做:预编译SQL性能更高,更安全(防止SQL注入)
为什么性能更高:


java中sql语句执行的流程:

在这里插入图片描述java将sql语句传入数据库中,首先通过前三个内容,处理完后语句停留在缓存当中,当再次遇上相同语句的时候,将不需要前面的步骤,可以直接执行,但是如果没有预编译直接传入带有id的语句,可能每次都碰不到相同的语句,但是通过预编译采用参数占位符,这样同种语句会更方便识别,效率更高
为什么更加安全:

  • SQL注入

SQL注入是通过操作输入的数据来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法

进行SQL注入的演示:
在一个用户登录的界面,登录进入后台需要填写用户名和密码
当我们在密码栏中写入:

‘ or '1' = '1'

时发现登录成功,实际上用户的登录就是将输入的用户名和密码在数据库中进行查找,当查询到有相同数据便是登陆成功,但是输入上述数据后,查询操作就会变为:

select count(*) from emp where username='' and password='' or '1'='1';

这样查询操作永远为真,就会修改查询操作,这就是SQL注入

在mybatis开发中使用#{}下来就是预编译语句,#{}最终会被?替代掉
还存在另外一种${},这是直接将参数拼接在sql语句后,存在sql注入问题


## XML映射文件
  • 规范
  1. XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)
  2. XML映射文件的namespace属性为Mapper接口全限定名一致
  3. XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致
  • 配置XML映射文件

首先根据规范配置xml文件,在xml中配置sql语句:
在这里插入图片描述
在mybatis中文网中找到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="com.example.projecttest1.mapper.EmpMapper">
    <!--resultType :单条记录所封装的类型-->
    <select id="list" resultType="com.example.projecttest1.pojo.Emp">
        select * from emp where name like '%#{name}%'and gender=#{gender} and entrydate between #{begin} and #{end} order by update_time desc
    </select>

</mapper>

使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让你本就复杂的 SQL 语句更加混乱不堪。 因此,如果你需要做一些很复杂的操作,最好用 XML 来映射语句。

  • MybatisX

MybatisX是一款基于idea的快速开发Mybatis的插件,为效率而生
可以通过点击前面的标识快速的实现他们之间的互相定位

Mybatis的动态SQL

随着用户的输入或外部条件的变化而变化的SQL语句,我们称为动态SQL

通俗的来说,就好比我需要三个条件进行查询,我只前将三个条件固定写入sql,如果后期我只通过两个条件进行查询另一个就是null,这样就查不到数据

我们可以通过if标签进行有条件的拼接:
在这里插入图片描述

  • <if>
    进行有条件的sql语句拼接
  • <where>
    在这里插入图片描述
    会自动去除拼接后多余的and
  • <set>

使用set标签将更新字段进行包裹,动态的在首行创建set标签,可以去除多余的特殊字符
在这里插入图片描述

  • <foreach>

属性:
collection:要遍历的集合
item:遍历出来的元素
separator:分隔符
open:遍历开始前拼接的sql片段
close:遍历结束之后拼接的sql片段

  • <sql><include>标签

当程序中sql语句出现大量重复的时候,为了提高程序的可复用性,我们可以采取sql和include标签将重复的sql语句进行抽取和复用

通过<sql>进行抽取,在sql属性id给定一个唯一的id值
例如:

<sql id="commonSelect">
select ....
</sql>

然后通过<include>标签进行复用,在需要sql语句的地方:

<include refid="commonSelect"/>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

书生·浦语大模型实战营之轻松玩转书生·浦语大模型趣味案例

书生浦语大模型实战营 为了帮助社区用户高效掌握和广泛应用大模型技术&#xff0c;我们重磅推出书生浦语大模型实战营系列活动&#xff0c;旨在为开发者们提供全面而系统的大模型技术学习课程。加入我们&#xff0c;一起深入大模型全流程&#xff0c;从零搭建 RAG、多模态和智…

23种设计模式之创建型模式 - 单例模式

文章目录 一、单例模式1.1单例模式定义1.2 单例模式的特点 二、实现单例模式的方式2.1 饿汉式2.2 懒汉式2.3 双重检查锁&#xff1a;2.4 静态内部类2.5 枚举实现&#xff08;防止反射攻击&#xff09;&#xff1a; 一、单例模式 1.1单例模式定义 单例模式确保系统中某个类只有…

基于SSM汽车交易系统

基于SSM汽车交易系统的设计与实现 摘要 电子商务的兴起不仅仅是带来了更多的就业行业。同样也给我们的生活带来了丰富多彩的变化。多姿多彩的世界带来了美好的生活&#xff0c;行业的发展也是形形色色的离不开技术的发展。作为时代进步的发展方面&#xff0c;信息技术至始至终…

Geoserver中CQL_FILTER的使用

概述 在Geoserver中可通过CQL_FILTER对要素进行过滤&#xff0c;CQL_FILTER即支持属性过滤也支持空间过滤&#xff0c;本文通过实际的例子演示如何使用CQL_FILTER。 简介 CQL(Common Query Language)是为OGC目录规范创建的纯文本语言。GeoServer对其进行了调整&#xff0c;使…

批量爬取招聘网站【Boss直聘】上工作岗位的招聘信息

不管是学生还是工作的小伙伴&#xff0c;估计都对不同岗位工作几年的薪酬水平比较感兴趣。本文提供爬取招聘网站&#xff0c;获取某类工作招聘信息的实现逻辑和代码。具体的实施步骤是&#xff1a;明确爬取的招聘网站—确定爬取的工作城市—确定爬取的岗位—获取岗位的招聘子链…

前端学习<二>CSS基础——13-CSS3属性:Flex布局图文详解

前言 CSS3中的 flex 属性&#xff0c;在布局方面做了非常大的改进&#xff0c;使得我们对多个元素之间的布局排列变得十分灵活&#xff0c;适应性非常强。其强大的伸缩性和自适应性&#xff0c;在网页开中可以发挥极大的作用。 flex 初体验 我们先来看看下面这个最简单的布局…

【蓝桥杯嵌入式】六、真题演练(一)-1演练篇:第 届真题

温馨提示&#xff1a; 真题演练分为模拟篇和研究篇。本专栏的主要作用是记录我的备赛过程&#xff0c;我打算先自己做一遍&#xff0c;把遇到的问题和不同之处记录到演练篇&#xff0c;然后再返回来仔细研究一下&#xff0c;找到最佳的解题方法记录到研究篇。 解题记录&#x…

了解 LoadRunner 性能测试软件及其基础使用

目录 一、了解LoadRunner 1、什么是Loadrunner&#xff1f; 2、Loadrunner包括什么组件&#xff1f; &#xff08;1&#xff09;前台组件 &#xff08;2&#xff09;后台组件 二、LoadRunner三大组件 1、VuGen&#xff08;虚拟用户脚本生成器&#xff09; &#xff08;…

2024全开源小狐狸ai付费创作系统V2.8.0

源码介绍 小狐狸GPT付费体验系统的开发基于国外很火的ChatGPT&#xff0c;这是一种基于人工智能技术的问答系统&#xff0c;可以实现智能回答用户提出的问题。相比传统的问答系统&#xff0c;ChatGPT可以更加准确地理解用户的意图&#xff0c;提供更加精准的答案。同时&#x…

算法---动态规划练习-10(删除并获得点数)

题目 1. 题目解析2. 讲解算法原理3. 编写代码 1. 题目解析 题目地址&#xff1a;点这里 2. 讲解算法原理 rob_s函数&#xff1a;这个函数实现了经典的"打家劫舍"问题的算法。使用动态规划的思想&#xff0c;通过填表的方式计算在给定范围内能够获取的最大点数。 f和…

Windows入侵排查

目录 0x00 前言 0x01 入侵排查思路 1.1 检查系统账号安全 1.2 检查异常端口、进程 1.3 检查启动项、计划任务、服务 0x00 前言 当企业发生黑客入侵、系统崩溃或其它影响业务正常运行的安全事件时&#xff0c;急需第一时间进行处理&#xff0c;使企业的网络信息系统在最短时…

PAT(多路复用)配置

PAT&#xff08;多路复用&#xff09; 核心&#xff1a;多个内网IP对应一个公共IP 如下图&#xff1a; 配置命令&#xff1a; 第一步&#xff08;定义访问控制列表&#xff09; access-list 编号 permit 网络地址 反掩码 第二步&#xff08;定义合法的外部IP&#xff09; ip …

杰发科技——Jlink插件使用

0. 简介 杰发自带的烧录工具是ATCLink&#xff0c;基于DapLink适配。个人不太喜欢ATCLink&#xff0c;推荐使用Jlink&#xff0c;毕竟自己买&#xff0c;不用问原厂要&#xff0c;而且带Jlink&#xff0c;至少5Mhz以上。 V9烧录器使用7.50以下版本驱动。 V11烧录器可以使用7…

JavaSE:继承和多态(下篇)

目录 一、前言 二、多态 &#xff08;一&#xff09;多态的概念 &#xff08;二&#xff09;多态实现条件 &#xff08;三&#xff09;多态的优缺点 三、重写 &#xff08;一&#xff09;重写的概念 &#xff08;二&#xff09;重写的规则 &#xff08;三&#xff09;重…

AtCoder+ABC129_Typical Stairs

题目描述 有一个有 N 级台阶的楼梯。高桥现在站在楼梯的脚下&#xff0c;也就是第0个台阶上。他可以一次爬上一个或两个台阶。 但是&#xff0c;编号为a[1] ~ a[m]台阶的踏板都坏了&#xff0c;所以踏上这些台阶很危险。 在不踏上坏掉的台阶的情况下&#xff0c;有多少中方案…

《书生·浦语大模型全链路开源开放体系》学习笔记

书生浦语大模型全链路开源开放体系-学习笔记 大模型成为发展通用人工智能的重要途径专用模型通用大模型 书生大模型开源历程InternLM2回归语言建模的本质主要亮点性能全方位提升强大的内生计算能力 从模型到应用典型流程全链条开源开放体系数据数据集获取预训练微调XTuner 评测…

unipush 2.0流程及踩坑记录(后端调用接口,前端推送)

unipush 在线离线示例 在DCLOUD开发者中心里面创建unipush的应用 如果遇到选择Android 包名后没有自动生成Android 应用签名的话&#xff0c;就是下图这样的。 这个情况多半就是通过直接创建云端证书造成的&#xff0c;没有编辑应用信息 没有云端证书的看这里 在我的应用&…

62岁「御用变态佬」近况曝光。

现年62岁的吴毅将于90年代活跃于香港影坛&#xff0c;因经常扮演黑社会大佬、变态色魔等角色&#xff0c;而被封为影坛御用恶人&#xff0c;其反派形象亦深入民心。北上发展多年的吴毅将&#xff0c;近年不时在内地登台&#xff0c;不过日前却有一段他在台上发恶闹观众的片段被…

作业 二维数组-定位问题

图形相似度 描述 给出两幅相同大小的黑白图像&#xff08;用0-1矩阵&#xff09;表示&#xff0c;求它们的相似度。 说明&#xff1a;若两幅图像在相同位置上的像素点颜色相同&#xff0c;则称它们在该位置具有相同的像素点。 两幅图像的相似度定义为相同像素点数占总像素点数…

Linux下开发调试C++代码的三种方法

目录 准备程序配置vscode的json文件调试使用GDB命令行调试使用core文件调试 一般来说&#xff0c;Linux下做C开发都是用vscode远程连接的方式&#xff0c;这时候调试有三种方式&#xff1a;配置vscode的json文件调试、GDB命令行调试、通过core文件调试。 关于这三种调试方法的…