一、背景

1、什么是CRUD?

  • 通常我们用CRUD代表增删改查四种操作。
  • C:Create、R:Relative、U:Update、D:Delete

2、在本篇内容学习之前,需要一些准备工作:

  • 创建一个新的模块【利用Maven构建的普通Java模块】
  • 修改 pom.xml 中的一些配置信息
    • 添加一条语句,将打包方式定义为 jar 包 【因为我们当前不需要在web服务器上运行我们的项目】
    • 添加 mybatis、mysql驱动、junit、logback的依赖
 <!--打了一个jar包--><packaging>jar</packaging><dependencies><!--mybatis核心依赖--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.11</version><scope>import</scope></dependency><!--mysql驱动依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version><scope>import</scope></dependency><!--添加junit依赖--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><!--导入日志文件的依赖--><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.11</version><scope>test</scope></dependency></dependencies>
  • mybatis-config.xml、logback.xml 文件 放到根路径下

(1) mybatis-config.xml 文件的配置信息如下

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--日志配置--><settings><setting name="logImpl" value="SLF4J"/></settings><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><!--配置自己的数据库端口号和数据库--><property name="url" value="jdbc:mysql://localhost:3306/powernode"/><!--配置自己的数据库用户名和密码--><property name="username" value="root"/><property name="password" value="111111"/></dataSource></environment></environments><mappers><!--sql映射文件创建好之后,需要将该文件路径配置到这里[对应的Mapper文件]--><mapper resource="CarMapper.xml"/></mappers>
</configuration>

(2) logback.xml 文件的配置信息如下

<?xml version="1.0" encoding="UTF-8"?><configuration debug="false"><!-- 控制台输出 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern></encoder></appender><!-- 按照每天生成日志文件 --><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!--日志文件输出的文件名--><FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern><!--日志文件保留天数--><MaxHistory>30</MaxHistory></rollingPolicy><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern></encoder><!--日志文件最大的大小--><triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"><MaxFileSize>100MB</MaxFileSize></triggeringPolicy></appender><!--mybatis log configure--><logger name="com.apache.ibatis" level="TRACE"/><logger name="java.sql.Connection" level="DEBUG"/><logger name="java.sql.Statement" level="DEBUG"/><logger name="java.sql.PreparedStatement" level="DEBUG"/><!-- 日志输出级别,logback日志级别包括五个:TRACE < DEBUG < INFO < WARN < ERROR --><root level="DEBUG"><appender-ref ref="STDOUT"/><appender-ref ref="FILE"/></root></configuration>
  • 提供com.powernode.mybatis.utils.SqlSessionUtil工具类【方便创建会话】
package com.powernode.mybatis.utils;import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;import java.io.IOException;/*** @author Bonbons* @version 1.0*/
public class SqlSessionUtil {private SqlSessionUtil(){}//定义一个SqlSessionprivate static final SqlSessionFactory sqlSessionFactory;//在类加载的时候初始化SqlSessionFactorystatic {try {//此处自己的 mybatis-config.xml 文件位置要配置正确sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));} catch (IOException e) {throw new RuntimeException(e);}}//通过一个公有的方法为外部提供会话的对象public static SqlSession openSession(){return sqlSessionFactory.openSession(true);}
}
  • 最后一步就是创建测试用例

二、Insert【添加数据】

1、前情回顾:

  • 之前我们的 CarMapper.xml 文件是这样写的:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace先随便写-->
<mapper namespace="car"><insert id="insertCar">insert into t_car(car_num,brand,guide_price,produce_time,car_type) values('103', '奔驰E300L', 50.3, '2022-01-01', '燃油车')</insert>
</mapper>

插入数据的语句是固定的,如果想插入不同的数据,只能在这块自己调整参数 >> 很不方便

2、改进方法1:

(1)在MyBatis中可以将数据放到Map集合中,在使用Java程序处理业务时,将Map对象作为参数传递进来。
(2)在sql语句中使用 #{map集合的key} 来完成传值,其中的 #{} 就是占位符
(3)给出改进后的 CarMapper.xml 中的配置信息【可以看出此时占位符中的参数已经替换为Map实例的key】

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace先随意写一个-->
<mapper namespace="com.powernode.CarMapperTest"><!--insert sql:保存一个汽车信息--><insert id="insertCar">insert into t_car (id,car_num,brand,guide_price,produce_time,car_type) values (null,#{car_num},#{brand},#{guide_price},#{produce_time},#{car_type})</insert>
</mapper>

(4)再看一下测试用例中的代码:

@Test
public void testInsertCar(){//利用工具类创建会话SqlSession session = SqlSessionUtil.openSession();//创建一个Map存储我们要传递的信息Map<String, Object> map = new HashMap<String, Object>();// id,car_num,brand,guide_price,produce_time,car_type// 对于key的选取应该见名知意map.put("car_num", 3);map.put("brand", "奥迪");map.put("guide_price", 50.0);map.put("produce_time", "2022-10-18");map.put("car_type", "燃油车");//调用我们的添加方法session.insert("insertCar", map);//提交事务session.commit();session.close();
}

(5)运行后可以刷新 Navicat 查看结果

3、改进方法2:
(1)设置一个普通的Java类,类的属性对应数据库中的字段,为外部提供GetSet方法【该系列将这种普通Java类称之为pojo

(2)创建一个 com.powernode.pojo.Car 类,用于封装数据

package com.powernode.mybatis.pojo;/*** @author Bonbons* @version 1.0*/
public class Car {// id,car_num,brand,guide_price,produce_time,car_type// 使用包装类,出现null时不会报错// 对于这些私有属性要与表中数据对应上private Long id;private String carNum;private String brand;private Double guidePrice;private String produceTime;private String carType;//提供构造方法public Car(){}public Car(Long id, String carNum, String brand, Double guidePrice, String produceTime, String carType) {this.id = id;this.carNum = carNum;this.brand = brand;this.guidePrice = guidePrice;this.produceTime = produceTime;this.carType = carType;}//提供get和set方法public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getCarNum() {return carNum;}public void setCarNum(String carNum) {this.carNum = carNum;}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public Double getGuidePrice() {return guidePrice;}public void setGuidePrice(Double guidePrice) {this.guidePrice = guidePrice;}public String getProduceTime() {return produceTime;}public void setProduceTime(String produceTime) {this.produceTime = produceTime;}public String getCarType() {return carType;}public void setCarType(String carType) {this.carType = carType;}//重写toString方法@Overridepublic String toString() {return "Car{" +"id=" + id +", carNum='" + carNum + '\'' +", brand='" + brand + '\'' +", guidePrice=" + guidePrice +", produceTime='" + produceTime + '\'' +", carType='" + carType + '\'' +'}';}
}

(2)要修改 CarMapper.xml 文件,更改 insert 方法中占位符中的内容

  • 这里面需要注意一个问题,占位符中的内容并不一定是Car类中的参数,它这个对应机制是这样的:

#{parameter} --> getParemeter() 【也就是说会去Car类中寻找这个get方法来获取参数】

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace先随意写一个-->
<mapper namespace="com.powernode.CarMapperTest"><!--insert sql:保存一个汽车信息--><insert id="insertCar">insert into t_car (id,car_num,brand,guide_price,produce_time,car_type) values (null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})</insert>
</mapper>

(3)原来的测试类中添加相关的的测试方法

@Test
public void testInsertCarByPOJO(){SqlSession session = SqlSessionUtil.openSession();//封装数据Car car = new Car(null, "4", "托马斯", 200.0, "2022-11-11","煤油车");//事务处理session.insert("insertCar", car);//提交事务session.commit();session.close();
}

4、总结

  • 如果采用map集合传参,#{} 里写的是map集合的key,如果key不存在不会报错,数据库表中会插入NULL
  • 如果采用POJO传参,#{} 里写的是get方法的方法名去掉get之后将剩下的单词首字母变小写【getAge对应的是 #{age}

三、delete 和 update【删除、更新数据】

  • 此处我们只涉及简单的删除和更新操作,重点在于了解基本语法
  • 我们根据 id 来完成数据的删除和更新
  • 此部分给出在 CarMapper.xml 中的配置信息以及测试类中的对应测试方法

1、通过指定 id 删除数据
(1)在CarMapper.xml 中的配置信息如下【为了看起来更简洁,只给出对应的SQL语句】

  • 有一件值得注意的事情:当只存在一个占位符时,可以自动识别,参数名不匹配也没有问题
<!--根据id删除数据-->
<delete id="deleteById">delete from t_car where id = #{id}
</delete>

它的外部代码是这样的

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="balabala">
<!--在这部分写我们的SQL语句-->
</mapper>

(2)测试方法如下【也是只给出了完整方法,没去写类名】

@Test
public void testDeleteCarById(){SqlSession sqlSession = SqlSessionUtil.openSession();// count会记录操作实际影响数据库表中数据的条数int count = sqlSession.delete("deleteById", 15);//通过变量名.sout 可以快速生成输出指定变量的语句[在IDEA中]System.out.println(count);sqlSession.commit();sqlSession.close();
}

(3)成功运行,删除了原来 id = 15 的数据

2、通过指定 id 更新数据
(1)在CarMapper.xml 中的配置信息如下

<!--根据id修改数据-->
<update id="updateById">update t_car set car_num = #{carNum}, brand = #{brand}, guide_price = #{guidePrice}, produce_time = #{produceTime},car_type = #{carType} where id = #{id}
</update>

(2)测试方法如下

@Test
public void testUpdateCarById(){SqlSession sqlSession = SqlSessionUtil.openSession();Car car = new Car(17L, "1111", "奔驰大G", 200.0, "2020-01-01", "汽油越野车");int count = sqlSession.update("updateById", car);System.out.println(count);sqlSession.commit();sqlSession.close();
}

(3)成功运行,修改了原来 id = 17 的数据


四、Select【查询数据】

  • 查询语句的重点在于:对于查询结果集的处理以及类属性名与数据库字段名的对应
  • 此处分别以查询一条数据和查询全部数据为例,来说明MyBatis中是如何完成数据查询的

1、 根据 id 查询一条数据:

(1)CarMapper中的配置信息

<select id="selectById" resultType="com.powernode.mybatis.pojo.Car"><!--select * from t_car where id = #{id}-->select id, car_num as carNum, brand, guide_price as guidePrice, produce_time as produceTime, car_type as carType from t_car where id = #{id}
</select>

细心的盆友不难发现,查询语句与其他数据操作SQL语句不同:

第一,多了resultType;第二为查询的字段设置了别名

  • 使用 resultType 是为了告诉 MyBatis 我们查询结果集是一个什么类型的数据【使用的是全限定类名(类的完整地址)】
  • 设置别名,是因为如果类属性与数据库表中字段对应不上,就无法正确传递参数值

(2)测试方法

@Test
public void testSelectById(){SqlSession sqlSession = SqlSessionUtil.openSession();//用Car的实例接收返回值Car car = sqlSession.selectOne("selectById",1);//打印查询结果[之所以此处可以输出属性和值,是因为在Car类中重写了toString方法]System.out.println(car);//查询语句不需要提交事务sqlSession.close();
}

2、查询全部的数据

  • 与前者的区别在于:查询时不需要设置条件、返回的是一个结果的集合

(1)CarMapper中的配置信息

<!--查询数据库表中全部数据-->
<select id="selectAll" resultType="com.powernode.mybatis.pojo.Car">select id, car_num as carNum, brand, guide_price as guidePrice, produce_time as produceTime, car_type as carType from t_car
</select>

(2)测试方法

@Test
public void testSelectAll(){SqlSession sqlSession = SqlSessionUtil.openSession();List<Car> cars = sqlSession.selectList("selectAll");//使用Lamda表达式+forEach输出cars.forEach(car -> System.out.println(car));sqlSession.close();
}


3、namespace 用法说明

  • 当出现两个 XxxMapper.xml 文件中出现同IDSQL语句时,可能会出现问题
  • 我们可以通过 namespace.SQL语句id 来指定使用哪个Mapper中的 SQL 方法
  • 简言之,命名空间 >> 防止 id 冲突
  • PS:如果设置了多个Mapper.xml 文件,要记得添加到核心配置文件中

【零基础入门MyBatis系列】第三篇——使用MyBatis完成CRUD相关推荐

  1. 零基础入门网络安全,收藏这篇不迷茫【2023 最新】

    零基础入门网络安全,收藏这篇不迷茫[2023 最新] 前言 最近收到不少关注朋友的私信和留言,大多数都是零基础小友入门网络安全,·需要相关资源学习.其实看过的铁粉都知道,之前的文里是有过推荐过的.新来 ...

  2. 【零基础入门前端系列】—背景属性(十二)

    [零基础入门前端系列]-背景属性(十二) 一.背景属性 CSS背景属性主要有以下几个: CSS3中可以通过background-image属性添加背景图片. 不同的背景图像和图像用逗号隔开,所有的图片 ...

  3. 视频教程-ARDUINO零基础入门教程【代码编程篇】-Arduino

    ARDUINO零基础入门教程[代码编程篇] 精通各种单片机编程,有十年以上ARDUINO,51单片机/STM32/PIC/AVR编程,硬件设计,绘图,编程经验.熟悉各种常用传感器使用和物联网通讯 赵勇 ...

  4. 生日祝福小程序_广告配音剪映零基础入门教程第二十六篇:如何给朋友制作生日祝福视频...

    经常听到小伙伴问到生日祝福视频怎么做,当然我想既然要为他人做生日祝福视频,那么这个人必定是自己身边比较重要的人,而生日又是每个人都是非常重要的,在这种充满意义的时刻,我们想给自己极其重要的人送上一份祝 ...

  5. 零基础入门STM32编程(三)

    前情回顾 通过前面两篇文章的学习,我们已经对STM32有了一定的了解,知道了STM32单片机的基本分类和不同产品间的特点等知识,今天起围绕STM32F103xx继续深入浅出地学习单片机编程. 一.总线 ...

  6. 零基础入门深度学习的五篇经典教程

    零基础入门深度学习>系列文章旨在讲帮助爱编程的你从零基础达到入门级水平.零基础意味着你不需要太多的数学知识,只要会写程序就行了,没错,这是专门为程序员写的文章.虽然文中会有很多公式你也许看不懂, ...

  7. 神仙级python入门教程(非常详细)零基础入门到精通看这篇开始

    ▌▌ Python的应用 自动化工具:自动处理数据.Excel文件.发邮件.下载.上传数据 网络爬虫:代替人工自动从下载数据,例如:商品信息.股票数据.技术文章 Web网站:开发一个网站.APP.小程 ...

  8. Vue全家桶学习笔记_零基础入门到入坑:Vue篇

    文章目录 前言 什么是Vue,什么又是框架 完善的准备 Vue 引入 npm 安装 cnpm镜像加速器 安装 Vue-Cli脚手架 安装 webpack 安装 webpack-cli 安装 axios ...

  9. 尚硅谷最新版JavaWeb全套教程,java web零基础入门完整版(三)

    EL表达式 什么是EL表达式 <%@ page contentType="text/html;charset=UTF-8" language="java" ...

  10. 零基础入门JAVAweb——前端开发html篇

最新文章

  1. Python技术分享:ndarray对象的常用属性
  2. C和指针之动态内存分配堆、栈、全局区(静态区)、常量区对比总结学习笔记
  3. Linux下文件的多进程拷贝
  4. python字符串数组_python将字符串转换成数组的方法
  5. 浏览器弹窗怎么设置显示url_谷歌浏览器Chrome76版本地址栏不显示HTTPS和WWW怎么办?...
  6. 程序员误区1:软件开发职业是青春饭
  7. 用条件运算符编写java程序_Java 编程入门课程丨第 8 单元:条件运算符和控制语句...
  8. 自定义控件常用方法总结
  9. java数组怎么添加元素_Java封装数组之添加元素操作实例分析
  10. python (continue与break)区别
  11. php生成透明png图像 无锯齿
  12. win7计算机怎么录屏,怎么用win7系统的电脑录屏
  13. Nifi从入门到精通(一)之 数据存储
  14. java实现商品的分类_Spring 商品分类
  15. 【预测师】的时间管理方法论(泰山版)
  16. 关于ZBRUSH弯折功能使用问题
  17. keep sb updated_keep me updated是什么意思
  18. 命令行窗口的解释及使用
  19. 非递归实现二叉树的遍历
  20. springcloud 项目maven依赖:Failure to find org.springframework.cloud:spring-cloud-dependencies

热门文章

  1. 翻译狗文档免费下载手册(补充版)
  2. hexo WARN No layout: index.html
  3. git、githut、码云概念和使用,md文件编辑,
  4. android 国家代码
  5. php tracert,详解路由跟踪命令(tracert)
  6. python保存对话框_python打开文件对话框的方法
  7. ThinkPHP3.2.3实现后台登录界面
  8. android 动态仿磁贴,UWP开发:给App加上动态磁贴
  9. 稻盛和夫自传读书笔记
  10. 服务器双系统快捷键,mac双系统切换快捷键