一文彻底搞懂Mybatis系列(三)之mybatis完成增删改查CURD功能超级详细

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 一文彻底搞懂Mybatis系列(三)之mybatis完成增删改查CURD功能超级详细

一、准备工作

1、引入maven依赖

<dependencies>
    <!--junit测试类-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!--mybatis依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.10</version>
    </dependency>
    <!--数据库驱动-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.30</version>
    </dependency>
    <!--引入logback日志框架依赖,这个日志框架实现了slf4j规范-->
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.11</version>
    </dependency>
  </dependencies>

2、开发工具类 SqlSessionUtil

作用:
1、SqlSessionUtil,方便用来获取SqlSession对象
2、避免多次重复创建SqlSessionFactory 对象,
因为一个环境下,只需要创建一个SqlSessionFactory 
package com.powernode.util;
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;
public class SqlSessionUtil {
    private SqlSessionUtil(){};
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取会话对象,
     * @return
     */
    public static SqlSession openSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

3、准备 mybatis-config.xml文件

在resources目录下,添加mybatis-config.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <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?useUnicode=true&amp;characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/CarMapper.xml"/>
    </mappers>
</configuration>

4、准备日志文件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">
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>
    <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"/>
    <root level="DEBUG">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    </root>
</configuration>

二、INSERT 功能

1、JDBC和mybatis占位符对比

JDBC的代码是怎么写的?
string sql ="insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,?,?,?,?,?)"; ps.setstring(1,xxx); ps.setstring(2, yyy);
....
在JDBC当中占位符采用的是?
在mybatis当中不能使用?占位符,必须使用 #{} 来代替JDBC当中的 ?#{} 和 JDBC当中的 ? 是等效的。

2、java程序中使用Map可以给SQL语句的占位符传值:

Map<String, Object> map = new HashMap<>(); 
map.put("k1","1111"); 
map.put("k2","比亚迪汉"); 
map.put("k3",10.0);
map.put("k4","2020-11-11"); 
map.put("k5","电车");

xml文件写法

insert into t car(id.car_num.brandquide priceproduce_timecartype)values(null,#{k1},#{k2}.#{k3}.#{k4}.#{k5})

注意:#{这里写什么?写map集合的key,如果key不存在,获取的是null}

一般map集合的key起名的时候要见名知意。

map.put("carNum","1111");
 map.put("brand","比亚迪汉2"); 
 map.put("guidePrice",10.0);
map.put("produceTime","2020-11-11"); 
map.put("carType","电车");
insert into t car(id,car_num,brand,guide_price,produce_time,car_type 
values(null,#{carNum},#{brand},#fauidePrice},#{produceTime},#{carType})

3、java程序中使用POJO类给SQL语句的占位符传值

java程序中使用POJO类给SQL语句的占位符传值:

Car car =new Car(null,“3333”,“比亚迪秦”,30.0,“2020-11-11”,“新能源”);

注意:占位符#{},大括号里面写:pojo类的属性名

insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)

values(null.#{carNum}.#{brand}.#{quidePrice}.#{produceTime},#{carType}

把SQL语句写成这个德行:

insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)

values(null,#{xyz},#{brand},#{guidePrice},#{produceTime},#{carType})

出现了什么问题呢?

There is no getter for property named 'xyz’ in 'class com.powernode.mybatis.pojo.Car mybatis去找:Car类中的getXyz()方法去了。没找到。报错了。

怎么解决的?

可以在Car类中提供一个getxyz()方法。这样问题就解决了。

通过这个测试,得出一个结论:

严格意义上来说:如果使用POJO对象传递值的话,#{}这个大括号中到底写什么?
写的是get方法的方法名去掉get,然后将剩下的单词首字母小写,然后放进去。
例如:getUsername() --> #{username}例如:getEmail() --> #{email}
也就是说mybatis在底层给?传值的时候,先要获取值,怎么获取的?
调用了pojo对象的get方法。例如:car.getCarNum(),car.getCarType(),car.getBrand()

完整的代码:

pojo实体类 Car
package com.powernode.pojo;
public class Car {
    private Long id;
    private String carNum;
    private String brand;
    private Double guidePrice;
    private String produceTime;
    private String carType;
    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;
    }
    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;
    }
}
CarMapper.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="jskdlf">
    <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>
测试类
@Test
    public void testInsertPojo(){
        SqlSession sqlSession = SqlSessionUtil.openSqlSession();
        Car car = new Car(null,"333","比亚迪秦",30.0,"220-10-09","新能源");
        int count = sqlSession.insert("insertCar",car);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    }

三、delete 功能

需求:根据id删除记录
1、pojo实体类同上
2、CarMapper.xml文件sql语句配置
<delete id="deleteById">
        delete from t_car where id = #{id}
    </delete>
3、测试类
@Test
    public void testDelete(){
        SqlSession sqlSession = SqlSessionUtil.openSqlSession();
        int count = sqlSession.delete("deleteById",15);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    }

注意:如果占位符只有一个,那么#{}的大括号里可以随意写,但是最好是见名知意

四、update 功能

需求:根据id修改记录
1、pojo实体类同上
2、CarMapper.xml文件sql语句配置
<update id="updateById">
        update t_car set car_num=#{carNum},brand=#{brand} where id=#{id}
    </update>
3、测试类
@Test
    public void testUpdateById(){
        SqlSession sqlSession = SqlSessionUtil.openSqlSession();
        Car car = new Car();
        car.setId(14L);
        car .setCarNum("999");
        car.setBrand("GTR");
        int count = sqlSession.update("updateById",car);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    }

五、select查询功能

需求:根据id查询,返回一个目标对象

1、pojo实体类同上
2、CarMapper.xml文件sql语句配置
<select id="selectById" resultType="com.powernode.pojo.Car">
        select * from t_car where id = #{id}
    </select>
3、测试类
@Test
    public void testSelectOne(){
        SqlSession sqlSession = SqlSessionUtil.openSqlSession();
        Car car = sqlSession.selectOne("selectById",12);
        System.out.println(car.toString());
        sqlSession.commit();
        sqlSession.close();
    }
运行结果

发现问题:
Car{id=12, carNum='null', brand='auto', guidePrice=null, produceTime='null', carType='null'}
为什么只有id和brand有值,其他字段都没有查询到值?
原理是因为数据库的列名和pojo实体类的名字不一致,造成的

解决办法

可以使用mysql的as关键字起别名
sql文件修改成这样:
<select id="selectById" resultType="com.powernode.pojo.Car">
        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>
运行测试类结果,

需求:查询所有对象

1、pojo实体类同上
2、CarMapper.xml文件sql语句配置
<select id="selectAll" resultType="com.powernode.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>
3、测试类
@Test
    public void testSelectAll(){
        SqlSession sqlSession = SqlSessionUtil.openSqlSession();
        List<Car> carList = sqlSession.selectList("selectAll");
        carList.forEach(c-> System.out.println(c));
        sqlSession.commit();
        sqlSession.close();
    }
运行结果

注意:

如果查询的结果为List,那么resultType还是指定要封装的结果集的类型,不是指定list类型,是指定list集合中元素的类型
selectList方法:mybatis通过这个方法就可以得知你需要一个list集合  ,他会自动给你返回一个List集合


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
20天前
|
SQL Java 数据库连接
深入 MyBatis-Plus 插件:解锁高级数据库功能
Mybatis-Plus 提供了丰富的插件机制,这些插件可以帮助开发者更方便地扩展 Mybatis 的功能,提升开发效率、优化性能和实现一些常用的功能。
115 26
深入 MyBatis-Plus 插件:解锁高级数据库功能
|
1月前
|
Java 数据库连接 容器
Mybatis-Plus核心功能
Mybatis-Plus核心功能
|
2月前
|
SQL XML Java
mybatis复习02,简单的增删改查,@Param注解多个参数,resultType与resultMap的区别,#{}预编译参数
文章介绍了MyBatis的简单增删改查操作,包括创建数据表、实体类、配置文件、Mapper接口及其XML文件,并解释了`#{}`预编译参数和`@Param`注解的使用。同时,还涵盖了resultType与resultMap的区别,并提供了完整的代码实例和测试用例。
mybatis复习02,简单的增删改查,@Param注解多个参数,resultType与resultMap的区别,#{}预编译参数
|
2月前
|
SQL 存储 Java
原生JDBC简单实现Mybatis核心功能
本文介绍了在Vertx项目中使用Tdengine时,因缺乏异步JDBC驱动而采用同步驱动结合`vertx.executeBlocking`实现异步查询的方法。文中详细描述了自行开发的一个简易JDBC工具,该工具实现了SQL参数绑定与返回值映射至实体类的功能,简化了原生JDBC的繁琐操作。通过具体示例展示了其实现过程及代码细节,并与原生JDBC进行了对比,突显了其便捷性和实用性。
|
2月前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
48 1
|
3月前
|
供应链 前端开发 Java
服装库存管理系统 Mybatis+Layui+MVC+JSP【完整功能介绍+实现详情+源码】
该博客文章介绍了一个使用Mybatis、Layui、MVC和JSP技术栈开发的服装库存管理系统,包括注册登录、权限管理、用户和货号管理、库存管理等功能,并提供了源码下载链接。
服装库存管理系统 Mybatis+Layui+MVC+JSP【完整功能介绍+实现详情+源码】
|
4月前
|
Java 数据库连接 数据库
mybatis plus 中增删改查及Wrapper的使用
mybatis plus 中增删改查及Wrapper的使用
217 3
|
3月前
|
druid Java 数据库连接
SpringBoot项目整合MybatisPlus持久层框架+Druid数据库连接池,以及实现增删改查功能
SpringBoot项目整合MybatisPlus和Druid数据库连接池,实现基本的增删改查功能。
356 0
|
5月前
|
SQL Java 数据库连接
2万字实操案例之在Springboot框架下基于注解用Mybatis开发实现基础操作MySQL之预编译SQL主键返回增删改查
2万字实操案例之在Springboot框架下基于注解用Mybatis开发实现基础操作MySQL之预编译SQL主键返回增删改查
77 2
MybatisPlus介绍新增用户,根据id查询,引入MybatisPlus的起步依赖,增删改查最简单的写法
MybatisPlus介绍新增用户,根据id查询,引入MybatisPlus的起步依赖,增删改查最简单的写法