03MyBatis完成CRUD+命名空间

准备工作
○ 创建module(Maven的普通Java模块):mybatis-002-crud
○ pom.xml
■ 打包方式jar
■ 依赖:
● mybatis依赖
● mysql驱动依赖
● junit依赖
● logback依赖
○ mybatis-config.xml放在类的根路径下
○ CarMapper.xml放在类的根路径下(一张表对应一个Mapper)
○ logback.xml放在类的根路径下
○ 提供com.sunsplanter.mybatis.utils.SqlSessionUtil工具类
○ 创建测试用例:com.sunsplanter.mybatis.CarMapperTest


1.insert(Create)

1.1使用map传参完成insert

在第一个mybatis程序中的CarMapper.xml文件中,Sql语句是写死的:

  <insert id="insertCar">
  //插入的东西全部写死了,但实际使用中,我们不可能预知用户需要insert的数据
  //一定是通过某种方法留空,然后前端的form表单传来数据,再将数据与sql语句结合提交
        insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
        values(null,'1003','toyota',30.00,'2000-10-11','燃油车')
    </insert>

在JDBC中,我们是这样留空的:

// JDBC中使用 ? 作为占位符。
String sql = "insert into t_car(car_num,brand,guide_price,produce_time,car_type) values(?,?,?,?,?)";

在MyBatis中,我们这样做:
在Java程序中,将数据放到Map集合中
在sql语句中使用 #{map集合的key} 来完成传值,#{} 等同于JDBC中的 ? ,#{}就是占位符

package com.sunsplanter.mybatis;

import com.sunsplanter.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;

public class CarMapperTest {
    @Test
    public void testInsertCar() {
        //前端传来数据了,用map将这些数据封装起来
        Map<String, Object> map = new HashMap<>();
        map.put("k1", "103");
        map.put("k2", "奔驰E300L");
        map.put("k3", 50.3);
        map.put("k4", "2020-10-01");
        map.put("k5", "燃油车");
        //调用封装好的方法获取SqlSession对象
        SqlSession sqlSession = SqlSessionUtil.openSession();
// 执行SQL语句,第一个参数是sql段的id,第二参数是要传入的对象(使用map集合给sql语句传递数据)
        int count = sqlSession.insert("insertCar", map);
        System.out.println("插入了几条记录:" + count);
    }
}
<?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="TBD
">
    <insert id="insertCar">
<!--t_car后接的参数指明要插入表中的哪个单元,而#{} 的里面必须填写map集合的key,以正确获取map的value-->
        insert into t_car(car_num,brand,guide_price,produce_time,car_type) values(#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})
    </insert>
</mapper>

1.2使用POJO传参完成insert

如果采用POJO传参,#{} 里写的是get方法的方法名去掉get之后将剩下的单词首字母变小写(例如:getAge对应的是#{age},getUserName对应的是#{userName}),如果这样的get方法不存在会报错。

● 第一步:新建一个pojo包,包下定义一个pojo类Car,提供相关属性。

package com.sunsplanter.mybatis.pojo;

public class Car {
//long还是Long?若使用包装类,其提供了更多的方法可供调用,并且支持值为null的情况。
    private Long id;
    private String carNum;
    private String brand;
    private Double guidePrice;
    private String produceTime;
    private String carType;

    @Override
    public String toString() {
        return "Car{" +
                "id=" + id +
                ", carNum='" + carNum + '\'' +
                ", brand='" + brand + '\'' +
                ", guidePrice=" + guidePrice +
                ", produceTime='" + produceTime + '\'' +
                ", carType='" + 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;
    }

    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;
    }
}
@Test
public void testInsertCarByPOJO(){
	    // 创建POJO,封装数据
	    Car car = new Car();
	//前端传来数据了,用set方法将这些数据传入POJO属性
	    car.setCarNum("103");
	    car.setBrand("奔驰C200");
	    car.setGuidePrice(33.23);
	    car.setProduceTime("2020-10-11");
	    car.setCarType("燃油车");
	    //调用封装好的方法获取SqlSession对象
	    SqlSession sqlSession = SqlSessionUtil.openSession();
	// 执行SQL语句。第一个参数是sql段的id,第二参数是要传入的对象(使用POJO对象给sql语句传递数据)
	    int count = sqlSession.insert("insertCarByPOJO", car);
	    System.out.println("插入了几条记录" + count);
}
<insert id="insertCarByPOJO">
  <!--#{} 里写的是POJO的属性名-->
  insert into t_car(car_num,brand,guide_price,produce_time,car_type) values(#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})
</insert>

2.Delete

需求:根据car_num进行删除。

@Test
public void testDeleteByCarNum(){
    //调用封装好的方法获取SqlSession对象
    SqlSession sqlSession = SqlSessionUtil.openSession();
    // 执行SQL语句。第一个参数是sql段的id,第二个参数是要删除的“car_num”
    int count = sqlSession.delete("deleteByCarNum", "102");
    System.out.println("删除了几条记录:" + count);
}
<delete id="deleteByCarNum">
<!--当占位符只有一个的时候,${} 里面的内容可以随便写。-->
  delete from t_car where car_num = #{SuiBianXie}
</delete>

2.1用POJO传参Update

需求:修改id=34的Car信息,car_num为102,brand为比亚迪汉,guide_price为30.23,produce_time为2018-09-10,car_type为电车

<update id="updateCarByPOJO">
  update t_car set 
    car_num = #{carNum}, brand = #{brand}, 
    guide_price = #{guidePrice}, produce_time = #{produceTime}, 
    car_type = #{carType} 
  where id = #{id}
</update>
  @Test
    public void testUpdateCarById_POJO(){
        // 准备数据
        Car car = new Car();
        car.setId(5L);
        car.setCarNum("102");
        car.setBrand("比亚迪汉");
        car.setGuidePrice(30.23);
        car.setProduceTime("2018-09-10");
        car.setCarType("电车");
        // 获取SqlSession对象
        SqlSession sqlSession = SqlSessionUtil.openSession();
        // 执行SQL语句
        int count = sqlSession.update("updateCarById_Map", car);
        System.out.println("更新了几条记录:" + count);
    }

2.2用Map传参Update

需求一致,XML代码也一致,仅仅是java代码改为用Map传参

    @Test
    public void testUpdateCarById_Map(){
        //前端传来数据了,用map将这些数据封装起来
        Map<String, Object> map = new HashMap<>();
        map.put("id", 5L);
        map.put("carNum", "104");
        map.put("brand", "XiaomiSU7");
        map.put("guidePrice", 18.9);
        map.put("produceTime", "2024-04-01");
        map.put("carType", "电动车");
        //调用封装好的方法获取SqlSession对象
        SqlSession sqlSession = SqlSessionUtil.openSession();
        // 执行SQL语句
        int count = sqlSession.update("updateCarById_Map",map);
        System.out.println("更新了几条记录:" + count);
    }

3.1select(Retrieve)一条

select语句和其它语句不同的是:查询会返回一个结果集ResultSet。,然而,语句是:

Object car = sqlSession.selectOne("selectCarById", 1);

因此,必须将ResultSet转化成成一个Java对象。mybatis查询之后返回一个Java对象的话,至少你要告诉mybatis返回一个什么类型的Java对象,可以在标签中添加resultType属性,用来指定查询要转换的类型:


<select id="selectCarById" resultType="com.powernode.mybatis.pojo.Car">
  select * from t_car where id = #{id}
</select>
    @Test
    public void testSelectCarById(){
        // 获取SqlSession对象
        SqlSession sqlSession = SqlSessionUtil.openSession();
        //查一条记录用selectOne方法
        Car car = sqlSession.selectOne("selectCarById", 1);
        System.out.println(car);
    }

然而,这样输出的结果是:
在这里插入图片描述

原因是:例如对于汽车编号这个字段,在POJO类和mapper文件中为carNum,但在数据库表中为car_num,这样当然查不到。
改为:

<!--虽然结果是List集合,但是resultType属性需要指定的是List集合中元素的类型。-->
<select id="selectCarById" resultType="com.sunsplanter.mybatis.pojo.Car">
  select 
   <!--记得使用as起别名,让查询结果的字段名和java类的属性名对应上。
       方法是:数据库中字段名 as Java中属性名-->
    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>

3.1select(Retrieve)多条

  • 取一条时,用selectOne方法返回ResultSet,转化成一个指定对象,这个指定对象只要定义个Car car接受即可。
    取多条时,用selectList方法返回多个ResultSet转换成多个指定对象,这多个对象定义一个List来接受,否则要定义Car car1 car2…
<!--虽然结果是List集合,但是resultType属性需要指定的是List集合中元素的类型。-->
<select id="selectCarAll" resultType="com.sunsplanter.mybatis.pojo.Car">
  <!--记得使用as起别名,让查询结果的字段名和java类的属性名对应上。-->
  select
    id, car_num as carNum, brand, guide_price as guidePrice, produce_time as produceTime, car_type as carType
  from
    t_car
</select>
@Test
public void testSelectCarAll(){
    // 获取SqlSession对象
    SqlSession sqlSession = SqlSessionUtil.openSession();
    // 执行SQL语句
    List<Object> cars = sqlSession.selectList("selectCarAll");
    // 输出结果
    cars.forEach(car -> System.out.println(car));
}

4命名空间

在SQL Mapper配置文件中标签的namespace属性可以翻译为命名空间,这个命名空间主要是为了防止sqlId冲突的。
我们知道一张表对应一个Mapper.xml,而在程序中,仅仅以语句块的id作为辨识符,决定执行哪个语句。例如:
CarMapper1.xml:

<mapper namespace="car1">
<select id="selectCarAll" resultType="com.sunsplanter.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>
</mapper>

此时如有CarMapper2.xml:

<mapper namespace="car2">
<select id="selectCarAll" resultType="com.sunsplanter.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>
</mapper>

而代码为:

@Test
public void testNamespace(){
    // 获取SqlSession对象
    SqlSession sqlSession = SqlSessionUtil.openSession();
    // 执行SQL语句
    List<Object> cars = sqlSession.selectList("selectCarAll");
    // 输出结果
    cars.forEach(car -> System.out.println(car));
}

就会报错,因为两个Mapper中都有id为“selectCarAll”的Sql语句段,系统无法分辨执行哪一段。
解决办法:“namespace.id”

   List<Object> cars = sqlSession.selectList("car2.selectCarAll");

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

gem5学习(11):将缓存添加到配置脚本中——Adding cache to the configuration script

目录 一、Creating cache objects 1、Classic caches and Ruby 二、Cache 1、导入SimObject(s) 2、创建L1Cache 3、创建L1Cache子类 4、创建L2Cache 5、L1Cache添加连接函数 6、为L1ICache和L1DCache添加连接函数 7、为L2Cache添加内存侧和CPU侧的连接函数 完整代码…

【书生大模型Demo-2】

书生大模型Demo 1 大模型InternLM介绍2 Demo2.1 InternLM-Chat-7B智能对话Demo2.1.1 环境配置2.1.2 模型下载2.1.3 代码准备2.1.4 运行Demo 2.2 Lagent智能体工具调用Demo2.3 浦语 灵笔图文创作理解Demo 3 作业 实践是最好的老师&#xff1b; 1 大模型InternLM介绍 大模型&…

【占用网络】SurroundOcc:基于环视相机实现3D语义占用预测 ICCV 2023

前言 本文分享“占用网络”方案中&#xff0c;来自ICCV 2023的SurroundOcc&#xff0c;它基于环视相机实现3D语义占用预测。 使用空间交叉注意力将多相机图像信息提升到3D体素特征&#xff0c;即3D体素Query到2D图像中查询融合特征的思想。 然后使用3D卷积逐步对体素特征进行…

Python爬虫---Scrapy项目的创建及运行

Scrapy是一个为了爬取网站数据&#xff0c;提取结构性数据而编写的应用框架。 可以应用在包括数据挖 掘&#xff0c;信息处理或存储历史数据等一系列的程序中。 1. 安装scrapy&#xff1a; pip install scrapy 注意&#xff1a;需要安装在python解释器相同的位置,例如&#xf…

【conda】pip安装报错,网络延时问题解决记录(亲测有效)

【conda】pip安装报错&#xff0c;网络延时问题解决记录 1. pip install 报错如下所示2. 解决方案&#xff1a; 1. pip install 报错如下所示 pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(hostfiles.pythonhosted.org, port443): Read timed out.…

爱情视频相册怎么做?2.14情人节表白/活动视频模板PR剪辑素材

美好爱情故事&#xff0c;情人节表白视频相册怎么做&#xff1f;粉色浪漫的PR情人节表白/活动视频模板剪辑素材mogrt下载。 特征&#xff1a;可编辑文字和调整颜色&#xff0c;通过智能对象替换图像&#xff0c;RGB颜色模式&#xff0c;易于自定义&#xff0c;无需插件&#xf…

Django报错处理

django.template.exceptions.TemplateDoesNotExist: django/forms/widgets/text.html django.template.exceptions.TemplateDoesNotExist: django/forms/widgets/number.html以上报错是pycharm中创建虚拟环境之后把原本自带的templates文件删除&#xff0c;重新在app01下面创建…

Windows RPC运行时漏洞事后总结

2022年4月前后&#xff0c;Windows RPC运行时被曝出存在远程代码执行漏洞&#xff0c;当时曾引起很多人广泛关注。微软很快做出反应&#xff0c;发布补丁程序进行修补。这次事件中&#xff0c;Windows远程过程调用&#xff08;RPC&#xff09;运行时共出现三个关键漏洞&#xf…

HMM算法(Hidden Markov Models)揭秘

序列数据 机器学习的数据通常有两类&#xff0c;最常见的是独立同分布数据&#xff0c;其次就是序列数据。对于前者&#xff0c;一般出现在各种分类/回归问题中&#xff0c;其最大似然估计是所有数据点的概率分布乘积。对于后者&#xff0c;一般出现在各种时间序列问题中&…

详细讲解MybatisPlus实现逻辑删除

目录 前言1. 基本知识2. 实战Demo3. 拓展 前言 对于MybatisPlus的相关知识可在我的博客进行搜索 对应的CRUD相关知识也可看我这篇文章&#xff1a;【Java项目】实战CRUD的功能整理&#xff08;持续更新&#xff09; 在讲述逻辑删除这个概念时&#xff0c;先引入另外一个概念&…

企业用WhatsApp营销的好处有哪些?

1.建立良好的客户关系 WhatsApp是全球用户喜爱的即时通信软件&#xff0c;使用WhatsApp与客户沟通&#xff0c;可拉进企业和客户双方的距离。使用WhatsApp会话和消息推送功能&#xff0c;企业和用户可实时开展消息对话&#xff0c;及时解决客户咨询与疑虑&#xff0c;构建便捷…

解决 ubuntu 下编译文件的时候与 YAML 相关的的报错

输入&#xff1a; catkin build -DCMAKE_C_COMPILERgcc-8 -DCMAKE_CXX_COMPILERg-8 或 catkin build airsim_tutorial_pkgs -DCMAKE_C_COMPILERgcc-8 -DCMAKE_CXX_COMPILERg-8 报错如下&#xff1a; 可能是缺少 yaml-cpp 文件&#xff0c;然后操作&#xff1a; sudo apt-g…

【添加墨水注意事项]

添加墨水注意事项 当液位灯亮起时请添加墨水&#xff0c;添加墨水应时戴好护目镜和手套.注意墨水不要洒在设备注意墨水要避光保护防止固化 请使用本公司配套专用墨水&#xff0c;添加时注意墨水颜色 禁止儿童接触墨水及容器&#xff0c;如不慎接触眼睛或者误服应立即以大量清…

openssl3.2 - 官方dmeo学习 - server-arg.c

文章目录 openssl3.2 - 官方dmeo学习 - server-arg.c概述笔记备注END openssl3.2 - 官方dmeo学习 - server-arg.c 概述 TLS服务器, 等客户端来连接; 如果客户端断开了, 通过释放bio来释放客户端socket, 然后继续通过bio读来aceept. 笔记 对于开源工程, 不可能有作者那么熟悉…

leaflet学习笔记-带有方位角信息的圆的绘制(七)

前言 项目中有一个需求&#xff0c;就是需要绘制一个圆&#xff0c;并且绘制的时候还要设置方位角&#xff0c;最后返回圆的坐标集合和方位角。本功能使用Leaflet-GeomanTurf.jsleaflet实现。 方位角简介 在陆地导航中&#xff0c;方位角通常表示为 alpha、α&#xff0c;并定…

网络安全B模块(笔记详解)- nmap扫描渗透测试

nmap扫描渗透测试 1.通过BT5对服务器场景Linux进行TCP同步扫描 (使用工具Nmap,使用参数n,使用必须要使用的参数),并将该操作使用命令中必须要使用的参数作为Flag提交; Flag:sS 2.通过BT5对服务器场景Linux进行TCP同步扫描 (使用工具Nmap,使用参数n,使用必须要使用的参数…

Python-代码雨【附源码】

Python-代码雨 运行效果&#xff1a;实现的是动态的代码雨 import sys import random import pygame from pygame.locals import *# 屏幕大小 WIDTH 800 HEIGHT 600 # 下落速度范围 SPEED [15, 30] # 字母大小范围 SIZE [5, 30] # CODE长度范围 LEN [1, 8]# 随机生成一个…

如何通过anaconda创建第一个django项目

因为python版本用的是anaconda安装的&#xff0c;但是平时呢是使用viscod来玩py的&#xff0c;本来想创建个django的项目玩玩的&#xff0c;通过anacoda的powershell prompt 的插件用 pip 命令安装了django的包 pip install django 但是不知道在哪里的命令行创建项目&#xf…

A preview error may have occurred. Switch to the Log tab to view details.

记录一下当时刚开始学习鸿蒙开发犯的错误 UIAbility内页面间的跳转内容的时候会遇到页面无法跳转的问题 并伴随标题错误 我们跳转页面需要进行注册 路由表路径&#xff1a; entry > src > main > resources > base > profile > main_pages.json 或者是页面…

PHP企业物资管理系统源码带文字安装教程

PHP企业物资管理系统源码带文字安装教程 技术架构 主要框架 : PHP7.0 laravel5.4  mysql5.5.36 composer1.3.2(依赖管理) 前端 : jquery bootstrap jstree&#xff08;树形结构&#xff09; echart&#xff08;图表&#xff09; layer&#xff08;弹出层&#xff09; 企…