MyBatis笔记【JavaEE】

news2024/9/22 17:34:22

1.MyBatis是什么

持久层框架 【也是一个ORM框架 对象关系映射】

是一个优秀的ORM持久层框架

特点:灵活

支持自定义SQL、存储过程以及高级映射。MyBatis去除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。MyBatis可以通过简单的XML或注解来配置和映射原始类型、接口和Java POJO为数据库中的记录。

回顾JDBC操作步骤

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

对于 JDBC 来说,整个操作⾮常的繁琐,我们不但要拼接每⼀个参数,⽽且还要按照模板代码的⽅式,⼀步步的操作数据库,并且在每次操作完,还要⼿动关闭连接等,⽽所有的这些操作步骤都需要在每个⽅法中重复书写。

2.MyBatis入门

MyBatis分为两部分:

  • 配置 MyBatis 开发环境
  • 使用 MyBatis 模式和语法操作数据库

创建 MyBatis 项目

  • 创建数据库和数据表

    -- 创建数据库
    drop database if exists mycnblog;
    create database mycnblog DEFAULT CHARACTER SET utf8mb4;
    -- 使⽤数据数据
    use mycnblog;
    -- 创建表[⽤户表]
    drop table if exists userinfo;
    create table userinfo(
    id int primary key auto_increment,
    username varchar(100) not null,
    password varchar(32) not null,
    photo varchar(500) default '',
    createtime datetime default now(),
    updatetime datetime default now(),
    `state` int default 1
    ) default charset 'utf8mb4';
    -- 创建⽂章表
    drop table if exists articleinfo;
    create table articleinfo(
    id int primary key auto_increment,
    title varchar(100) not null,
    content text not null,
    createtime datetime default now(),
    updatetime datetime default now(),
    uid int not null,
    rcount int not null default 1,
    `state` int default 1
    )default charset 'utf8mb4';
    -- 创建视频表
    drop table if exists videoinfo;
    create table videoinfo(
    vid int primary key,
    `title` varchar(250),
    `url` varchar(1000),
    createtime datetime default now(),
    updatetime datetime default now(),
    uid int
    )default charset 'utf8mb4';
    -- 添加⼀个⽤户信息
    INSERT INTO `mycnblog`.`userinfo` (`id`, `username`, `password`, `photo`,
    `createtime`, `updatetime`, `state`) VALUES
    (1, 'admin', 'admin', '', '2021-12-06 17:10:48', '2021-12-06 17:10:48', 1)
    ;
    -- ⽂章添加测试数据
    insert into articleinfo(title,content,uid)
    values('Java','Java正⽂',1);
    -- 添加视频
    insert into videoinfo(vid,title,url,uid) values(1,'java title','http://ww
    w.baidu.com',1);
    
  • 一、添加 MyBatis 相关依赖

    • 新项目添加 MyBatis 依赖

      在这里插入图片描述

    在这里插入图片描述

    • 老项目添加 MyBatis 依赖

    在这里插入图片描述
    在这里插入图片描述

  • 二、配置数据库连接字符串和 MyBatis (保存的 XML 的目录)在这里插入图片描述
    如果使⽤ mysql-connector-java 是 5.x 之前的使⽤的是“com.mysql.jdbc.Driver”,如果是⼤于 5.x
    使⽤的是“com.mysql.cj.jdbc.Driver”。

    • 数据库连接

      在这里插入图片描述

    • mybatis保存的xml路径

    在这里插入图片描述

  • 三、使用 MyBatis 的操作模式操作数据库

    MyBatis 模式只包含两个部分的东西:

    1. 接口(定义方法的声明)

    2. xml 实现接口中的方法

      生成数据库可以执行sql,并且执行sql将结果映射到程序的对象中。
      在这里插入图片描述

MyBatis实现查询:

在这里插入图片描述

代码结构:
在这里插入图片描述

MyBatis 增删改查

  1. 在 mapper(interface)里面添加代码声明

    package com.example.mybatis_2023.mapper;
    
    import com.example.mybatis_2023.model.UserInfo;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Param;
    
    /**
     * @author SunYuHang
     * @date 2023-02-01 12:51
     * @ClassName : UserMapper  //类名
     */
    @Mapper // mybatis interface
    public interface UserMapper {
        //根据用户id查询用户
        public UserInfo getUserById(@Param("id") Integer id);// @Param在xml中id使用id获取
    
        // 修改方法 【根据id修改名称】
        public int update(@Param("id") Integer id,@Param("username") String username);
    
        //删除方法
        public int del(@Param("id") Integer id);
    
        // 添加用户,返回受影响的行数
        public int add(UserInfo userInfo);
    
        //添加用户,返回受影响的行数和用户自增id
        public int addGetId(UserInfo userInfo);
    
    }
    
    
  2. 在 xml 中添加相关标签和sql语句

    <?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">
    <!-- namespace 要设置是实现接口的具体包名加类名 -->
    <mapper namespace="com.example.mybatis_2023.mapper.UserMapper">
        <!-- 根据 id 查询用户 -->
        <select id="getUserById" resultType="com.example.mybatis_2023.model.UserInfo">
            select * from userinfo where id=#{id}
        </select>
    
    
        <!-- 根据用户 id 修改用户名称 -->
        <update id="update">
            update userinfo set username=#{username} where id=#{id}
        </update>
    
        <!-- 根据用户 id 删除用户 -->
        <delete id="del">
            delete from mycnblog.userinfo where id=#{id}
        </delete>
    
        <!--  添加用户,返回受影响的行数  -->
        <insert id="add">
            insert into mycnblog.userinfo (username, password) values (#{username},#{password})
        </insert>
    
    <!--    添加用户,返回受影响的行数和用户自增id-->
        <insert id="addGetId" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
            insert into mycnblog.userinfo (username, password) values (#{username},#{password})
        </insert>
    </mapper>
    
    
  3. 在 UserMapperTest 进行单元测试

    package com.example.mybatis_2023.mapper;
    
    import com.example.mybatis_2023.model.UserInfo;
    import org.apache.ibatis.logging.stdout.StdOutImpl;
    import org.junit.jupiter.api.Assertions;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.transaction.annotation.Transactional;
    
    @SpringBootTest
    //表示当前单元测试运行在 spring boot 环境中
    class UserMapperTest {
    
        @Autowired  // 属性注入
        private UserMapper userMapper;
    
        @Test
        void getUserById() {
            UserInfo userInfo = userMapper.getUserById(1);
            Assertions.assertNotNull(userInfo);
        }
    
        @Test
        @Transactional //事务 事务回滚
        void update() {
            int result = userMapper.update(2,"zmy");
            Assertions.assertEquals(1,result);
        }
    
    
        @Test
        void del() {
            int result = userMapper.del(2);
            System.out.println("受影响的行数:"+result);
            Assertions.assertEquals(1,result);
        }
    
        @Test
        void add() {
            UserInfo userInfo = new UserInfo();
            userInfo.setUsername("孙宇航");
            userInfo.setPassword("123");
            int result = userMapper.add(userInfo);
            System.out.println("受影响的行数:"+ result);
            Assertions.assertEquals(1,result);
        }
    
        @Test
        @Transactional
        void addGetId() {
            UserInfo userInfo = new UserInfo();
            userInfo.setUsername("孙");
            userInfo.setPassword("123");
            System.out.println("添加之前 user id:"+userInfo.getId());
            int result = userMapper.addGetId(userInfo);
            System.out.println("受影响的行数:"+ result);
            System.out.println("添加之后 user id:"+userInfo.getId());
            Assertions.assertEquals(1,result);
        }
    }
    

注意: ${} 和 #{} 的区别

  • 使用 #{} 得到的JDBC代码:【针对String类型的参数】

    ==>  Preparing: select * from userinfo where id=? //【预查询】预处理
    ==> Parameters: 1(Integer)
    
  • 使用 ${} 得到的JDBC代码:【针对int类型的参数】

==>  Preparing: select * from userinfo where id=1   //【即时查询】即时处理
==> Parameters: 
  1. 定义不同:

    #{} 预编译处理

    ${} 字符直接替换

  2. 使用不同:

    #{} 适用于所有类型的参数匹配

    ${} 只适用数值类型

  3. 安全性不同

    #{} 性能高,并且没有安全问题

    存在 S Q L 注入的问题【传递 S Q L 关键字或 S Q L 命令只能使用 {} 存在 SQL 注入的问题 【传递SQL关键字或SQL命令只能使用 存在SQL注入的问题【传递SQL关键字或SQL命令只能使用{}】{一定要在业务代码中对传递的值进行安全校验。}

MyBatis一对一查询【一个文章对应一个作者信息】

<!--   一对一映射属性     -->
<association property="userInfo" resultMap="com.example.mybatis_2023.mapper.UserMapper.BaseMap" 
columnPrefix="u_">
</association>

在这里插入图片描述
在这里插入图片描述

MyBatis一对多查询【一个用户多篇文章】

<!--    一对多映射属性    -->
<collection property="username" resultMap="com.example.mybatis_2023.mapper.ArticleMapper.BaseMap" 
columnPrefix="a_">
</collection>

在这里插入图片描述

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

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

相关文章

分布式缓存服务DCS-企业版性能更强,稳定性更高

背景介绍 近年来&#xff0c;随着各行业业务需求急速增加&#xff0c;数据量和并发访问量呈指数级增长&#xff0c;原来只能依附于关系型数据库的传统“缓存”逐渐难以支撑上层业务&#xff0c;开源Redis也面临着如“容量有限”、 “可靠性有限”、 “数据重复拷贝&#xff0c…

GeniE 实用教程(二)几何与网格

目 录一、前言二、Guiding Geometry2.1 Guide Point2.2 Guide Line2.3 Guide Plane2.4 Polyline三、Structure3.1 结构梁3.2 结构板3.1 结构壳四、Mesh4.1 网格属性4.2 网格划分4.3 查看网格五、参考文献一、前言 SESAM &#xff08;Super Element Structure Analysis Module&a…

操作系统(day08)内存

存储单元 内存的几个基本概念 存储单元 内存地址从0开始&#xff0c;每个地址对应一个存储单元 存储单元大小根据计算机按照什么方式编址 按字节编址 则每个存储单元大小为一字节&#xff0c;即1B&#xff0c;即8个二进制位按字编址 看这个计算的字长是多少位&#xff0c;如…

一到重要时刻就大脑空白?

很多人可能都经历过这样一幕&#xff1a;花了好多精力准备的一场考试、面试、演讲&#xff0c;到了上场的那一刻&#xff0c;之前准备的东西全都忘了&#xff0c;大脑一片空白。为什么会这样呢&#xff1f;我们所学到的东西都要经过三个步骤才能成为记忆&#xff1a;获取&#…

Leetcode 每日一题 1234. 替换子串得到平衡字符串

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…

深入解析golang几种非常主流的依赖注入框架,附实现案例及原理解析

什么是依赖注入&#xff1f; 依赖注入 &#xff0c;英文全名是 dependency injection&#xff0c;简写为 DI。 百科解释&#xff1a; 依赖注入是指程序运行过程中&#xff0c;如果需要调用另一个对象协助时&#xff0c;无须在代码中创建被调用者&#xff0c;而是依赖于外部的注…

【情人节专属】AI一键预测你和Ta的CP值

如何预测你和心仪的Ta有没有夫妻相&#xff1f;基于华为云ModelArts开发的【一键预测你和Ta的CP值】Demo帮你预测CP指数。该模型利用ssim算法综合计算五官特征相似程度&#xff0c;从而得出CP值。//夫妻相的原理在当今心理学、生物学仍有很大争议&#xff0c;夫妻相指数高并不意…

nVisual综合布线可视化管理系统解决方案

​一、综合布线管理系统的必要性 如今企事业单位办公人员变化很快&#xff0c;如果还是采用传统方式通过工程竣工图或者网络拓扑图来进行网络维护工作会非常麻烦&#xff0c;并且对管理人员的要求也会很高&#xff0c;管理人员需要清楚的知道工作区的信息点与配线架点之间的对…

java微信小程序旅游管理系统

本旅游服务软件,主要实现了管理员后端&#xff1a;首页、个人中心、旅游攻略管理、旅游资讯管理、景点信息管理、门票预定管理、用户管理、酒店信息管理、酒店预定管理、推荐路线管理、论坛管理、系统管理,用户前端&#xff1a;首页、景点信息、酒店信息、论坛中心、我的等。总…

剑指 Offer II 020. 回文子字符串的个数 马拉车算法

这里写自定义目录标题马拉车算法剑指 Offer II 020. 回文子字符串的个数马拉车算法 马拉车算法可以以接近线性时间判断计算回文串长度&#xff0c;遍历每一个中心点&#xff0c;再向两遍扩充 填充字符 其中$ ! 作为边界&#xff0c;添加#可以避开对偶数回文串的讨论&#xff…

博客系统--测试用例编写

目录一&#xff0c;整体概览1.1&#xff0c;登录页面测试用例1.2&#xff0c;注册页面测试用例1.3&#xff0c;发布博客功能测试1.4&#xff0c;删除博客功能测试二&#xff0c;具体设计2.1&#xff0c;注册页面测试--等价类法2.2&#xff0c;删除博客功能测试--判定表法一&…

【csdn首发】全网爆火的从零到一落地接口自动化测试

前段时间写了一系列自动化测试相关的文章&#xff0c;当然更多的是方法和解决问题的思路角度去阐述我的一些观点。结合我自己实践自动化测试的一些经验以及个人理解&#xff0c;这篇文章来聊聊新手如何从零到一落地实践接口自动化测试。 为什么要做接口测试 测试理念的演变 早…

热启动预示生态起航的Smart Finance,与深度赋能的SMART通证

2023年初加密市场的回暖&#xff0c;意味着各个赛道都将在新的一年里走向新的叙事。最近&#xff0c;我们看到GameFi赛道也在市场回暖的背景下&#xff0c;逐渐走出阴霾。从融资数据上看&#xff0c;1月获得融资的GameFi项目共12个&#xff0c;融资突破8000万美元&#xff0c;1…

肝一波,这个网站居然可以免费使用ChatGpt功能

一、肝一波&#xff0c;体验真爽 废话不多少&#xff0c;小码哥直接提大家感兴趣的问题&#xff0c;截图分享给大家。 问题一&#xff1a;如何在一年内赚到100万元 答&#xff1a; 一、赚钱的方式 开公司&#xff1a;在一年内开拓新业务模式&#xff0c;寻求投资&#xff…

2023软件测试工程师涨薪攻略,3年如何达到月薪30K?

1.软件测试如何实现涨薪 首先涨薪并不是从8000涨到9000这种涨薪&#xff0c;而是从8000涨到15K加到25K的涨薪。基本上三年之内就可以实现。 如果我们只是普通的有应届毕业生或者是普通本科那我们就只能从小公司开始慢慢往上走。 有些同学想去做测试&#xff0c;是希望能够日…

33、基于51单片机老人防跌倒蜂鸣器报警系统加速度检测

背景技术 老年人出门由于身体不灵活、视力较差&#xff0c;容易发生跌倒&#xff0c;现用的老年人跌倒报警装置是通过无线对讲系统研发的&#xff0c;它外观精美&#xff0c;自动化程度高&#xff0c;有很强的专业性&#xff0c;但是&#xff0c;设计者忽略了一个问题&#xf…

【项目精选】JAVAWEB校园二手平台项目

点击下载源码 JAVAWEB校园二手平台项目&#xff0c;基本功能包括&#xff1a;个人信息、商品管理&#xff1b;交易商品板块管理等。本系统结构如下&#xff1a; &#xff08;1&#xff09;本月推荐交易板块&#xff1a; 电脑及配件&#xff1a;实现对该类商品的查询、用户留言…

如何选择O2OA(翱途)开发平台的部署架构?

O2OA(翱途)开发平台[下称O2OA开发平台或者O2OA]支持公有云&#xff0c;私有云和混合云部署&#xff0c;也支持复杂的网络结构下的分布式部署。本篇主要介绍O2OA(翱途)开发平台支持的部署环境以及常用的集群部署架构。软硬件环境说明支持的云化平台&#xff1a;华为云(包括鲲鹏)…

前后端开发过程中的跨域问题总结

1.何为跨域问题 出于浏览器的同源策略限制。同源策略是一种约定&#xff0c;它是浏览器最核心也最基本的安全功能&#xff0c;如果缺少了同源策略&#xff0c;则浏览器的正常功能不能使用。可以说web是构建在同源策略基础之上的&#xff0c;浏览器只是针对同源策略的一种实现。…

面试23K字节测试开发岗被血虐,到底具有怎样的技术才算高级水平?

前几天我朋友跟我吐苦水&#xff0c;这波面试又把他打击到了&#xff0c;做了6年软件测试。。。 下面这条招聘是在腾讯招聘官网截图下来的&#xff0c;首先我们对高级水平下一个定义吧&#xff0c;那它应该是对标这个职级该有的能力 什么样的工程师才能算高级&#xff1f;至少…