软件设计之SSM(8)

news2024/11/26 5:28:52

软件设计之SSM(8)

路线图推荐:
【Java学习路线-极速版】【Java架构师技术图谱】
尚硅谷新版SSM框架全套视频教程,Spring6+SpringBoot3最新SSM企业级开发
资料可以去尚硅谷官网免费领取

学习内容:

Mybatis

  1. 数据输出
  2. 多表映射
  3. 动态语句

1、数据输出

数据输出总体上有两种形式:

  • 增删改操作返回的受影响行数:直接使用 int 或 long 类型接收即可
  • 查询操作的查询结果

单个简单类型

指定返回值类型就是指定resultType

  1. 类的全限定符号
<select id = "queryNameById" resultType ="java.lang.String">
</select>
  1. 别名简称
    mybatis 提供了72种默认别名,基于常用的数据类型
  • 基本数据类型 intdouble -> _int_double
  • 包装数据类型 IntegerDouble ->intdouble
  • 集合容器类型MapList -> maplist
  1. 自定别名
<!-- 给类单独定义别名-->
<typeAliases>
  <typeAlias alias="worker" type="com.atguigu.Employee"/>
</typeAliases>
<!-- 批量将包下的类定义别名,别名是类首字母小写-->
<typeAliases>
  <package name="com.atguigu.pojo"/>
</typeAliases>

实体对象类型

在 MyBatis 中,返回单个实体类型时,“列名与属性名一致” 是指:数据库查询结果中的列名需要与 Java 实体类(POJO)中的属性名相匹配,以便 MyBatis 能够正确地将 SQL 查询结果映射为 Java 对象。

mybatis-config.xml设置里,支持驼峰式自动映射。
即: emp_id --> empId

<!-- 在全局范围内对Mybatis进行配置 -->
<settings>
 
  <!-- 具体配置 -->
  <!-- 从org.apache.ibatis.session.Configuration类中可以查看能使用的配置项 -->
  <!-- 将mapUnderscoreToCamelCase属性配置为true,表示开启自动映射驼峰式命名规则 -->
  <!-- 规则要求数据库表字段命名方式:单词_单词 -->
  <!-- 规则要求Java实体类属性名命名方式:首字母小写的驼峰式命名 -->
  <setting name="mapUnderscoreToCamelCase" value="true"/>

</settings>

List类型

查询结果返回多个实体类对象,希望把多个实体类对象放在List集合中返回。此时不需要任何特殊处理,在resultType属性中还是设置实体类类型即可

List<Employee> selectAll();
<!-- List<Employee> selectAll(); -->
<select id="selectAll" resultType="com.atguigu.mybatis.entity.Employee">
  select emp_id empId,emp_name empName,emp_salary empSalary
  from t_emp
</select>

返回主键值

  1. 主键回显:是指在数据库执行插入操作时,数据库会自动生成并返回插入数据的主键值
  2. 自增长类型主键
<!-- int insertEmployee(Employee employee); -->
<!-- useGeneratedKeys属性字面意思就是“使用生成的主键” -->
<!-- keyProperty属性可以指定主键在实体类对象中对应的属性名,Mybatis会将拿到的主键值存入这个属性 -->
<insert id="insertEmployee" useGeneratedKeys="true" keyProperty="empId">
  insert into t_emp(emp_name,emp_salary)
  values(#{empName},#{empSalary})
</insert>
  1. 非自增长类型主键
    插入 UUID 作为字符串类型主键
<insert id="insertUser" parameterType="User">
    <selectKey keyProperty="id" resultType="java.lang.String"
        order="BEFORE">
        SELECT UUID() as id
    </selectKey>
    INSERT INTO user (id, username, password) 
    VALUES (
        #{id},
        #{username},
        #{password}
    )
</insert>

ResultMap自定义映射

实体类属性和数据库字段对应
使用resultMap标签定义对应关系,再在后面的SQL语句中引用这个对应关系

<!-- 专门声明一个resultMap设定column到property之间的对应关系 -->
<resultMap id="selectEmployeeByRMResultMap" type="com.atguigu.mybatis.entity.Employee">

  <!-- 使用id标签设置主键列和主键属性之间的对应关系 -->
  <!-- column属性用于指定字段名;property属性用于指定Java实体类属性名 -->
  <id column="emp_id" property="empId"/>

  <!-- 使用result标签设置普通字段和Java实体类属性之间的关系 -->
  <result column="emp_name" property="empName"/>

  <result column="emp_salary" property="empSalary"/>

</resultMap>

<!-- Employee selectEmployeeByRM(Integer empId); -->
<select id="selectEmployeeByRM" resultMap="selectEmployeeByRMResultMap">

  select emp_id,emp_name,emp_salary from t_emp where emp_id=#{empId}

</select>

2、多表映射

实体类设计

对一,属性中包含对方对象

对多,属性中包含对方对象集合

只有真实发生多表查询时,才需要设计和修改实体类,否则不提前设计和修改实体类!

无论多少张表联查,实体类设计都是两两考虑!

在查询映射的时候,只需要关注本次查询相关的属性!例如:查询订单和对应的客户,就不要关注客户中的订单集合!

public class Customer {

  private Integer customerId;
  private String customerName;
  private List<Order> orderList;// 体现的是对多的关系
}

public class Order {

  private Integer orderId;
  private String orderName;
  private Customer customer;// 体现的是对一的关系
  
}

//查询客户和客户对应的订单集合  不要管!

对一映射

在MyBatis中实现多表映射时,常见的场景之一是对一映射,即一个实体类关联另一个实体类的情况。这通常用于像“用户-地址”这样的关系。实现步骤主要包括:

假设有两个表 User 和 Address,用户表(User)地址表(Address)之间存在一对一的关系。
流程:
在这里插入图片描述
UserMapper.xml:

<mapper namespace="com.example.mapper.UserMapper">
    <resultMap id="UserResultMap" type="com.example.domain.User">
        <id property="id" column="user_id"/>
        <result property="name" column="user_name"/>
        
        <!-- 对一映射 -->
        <association property="address" javaType="com.example.domain.Address">
            <id property="id" column="address_id"/>
            <result property="street" column="street"/>
            <result property="city" column="city"/>
        </association>
    </resultMap>

    <!-- 查询语句 -->
    <select id="selectUserById" resultMap="UserResultMap">
        SELECT u.id AS user_id, u.name AS user_name, a.id AS address_id, a.street, a.city
        FROM User u
        JOIN Address a ON u.address_id = a.id
        WHERE u.id = #{id};
    </select>
</mapper>

对多映射

在MyBatis中,对多映射(一对多)通常用于表示“一个实体类包含多个子类”的关系,比如“一个用户有多个订单”的场景。MyBatis 提供了collection标签来处理这种一对多映射。

假设有两个表:User 和 Order,用户(User)订单(Order)之间是一对多的关系。
流程:
在这里插入图片描述
UserMapper.xml:

<mapper namespace="com.example.mapper.UserMapper">
    <!-- 配置 UserResultMap -->
    <resultMap id="UserResultMap" type="com.example.domain.User">
        <id property="id" column="user_id"/>
        <result property="name" column="user_name"/>

        <!-- 一对多映射 -->
        <collection property="orders" ofType="com.example.domain.Order">
            <id property="id" column="order_id"/>
            <result property="orderNumber" column="order_number"/>
            <result property="userId" column="user_id"/>
        </collection>
    </resultMap>

    <!-- 查询语句 -->
    <select id="selectUserById" resultMap="UserResultMap">
        SELECT u.id AS user_id, u.name AS user_name, o.id AS order_id, o.order_number, o.user_id
        FROM User u
        LEFT JOIN `Order` o ON u.id = o.user_id
        WHERE u.id = #{id};
    </select>
</mapper>

3、动态语句

JDBC字符串拼接

繁琐: 随着查询条件的增加,SQL 语句的拼接会变得复杂,代码不易维护。
易错: 手动拼接容易遗漏空格、标点等,导致语法错误。
安全问题: 手动拼接 SQL 会引发 SQL 注入风险,如果参数未经正确处理,攻击者可以插入恶意 SQL。

String sql = "SELECT * FROM User WHERE 1=1";
if (name != null) {
    sql += " AND name = '" + name + "'";  // 手动拼接参数,易引发 SQL 注入风险
}
if (age != null) {
    sql += " AND age = " + age;
}
PreparedStatement ps = conn.prepareStatement(sql);

if和where标签

<if> 标签用于根据传入的参数或条件决定是否生成某段 SQL 语句。它通常与条件判断结合使用,能够根据不同的输入动态调整查询、插入或更新的 SQL 逻辑。

<where> 标签主要用于动态构建 WHERE 子句,它不仅能动态生成条件,还能自动处理 SQL 语句开头的逻辑连接符(如 AND、OR 等)。如果在没有任何条件时,<where> 标签会去除 SQL 中无效的 WHERE 子句。

<!-- List<Employee> selectEmployeeByCondition(Employee employee); -->
<select id="selectEmployeeByCondition" resultType="employee">
    select emp_id,emp_name,emp_salary from t_emp
    <!-- where标签会自动去掉“标签体内前面多余的and/or” -->
    <where>
        <!-- 使用if标签,让我们可以有选择的加入SQL语句的片段。这个SQL语句片段是否要加入整个SQL语句,就看if标签判断的结果是否为true -->
        <!-- 在if标签的test属性中,可以访问实体类的属性,不可以访问数据库表的字段 -->
        <if test="empName != null">
            <!-- 在if标签内部,需要访问接口的参数时还是正常写#{} -->
            or emp_name=#{empName}
        </if>
        <if test="empSalary &gt; 2000">
            or emp_salary>#{empSalary}
        </if>
        <!--
         第一种情况:所有条件都满足 WHERE emp_name=? or emp_salary>?
         第二种情况:部分条件满足 WHERE emp_salary>?
         第三种情况:所有条件都不满足 没有where子句
         -->
    </where>
</select>

foreach标签

在 MyBatis 中,<foreach> 标签用于处理 SQL 语句中的批量操作,例如批量插入、批量更新或者在 IN 子句中传递多个参数。它能够遍历集合或数组,并动态生成 SQL 语句,避免手动拼接多个参数,代码更加简洁、可维护。

<select id="selectUsersByIds" resultType="User">
    SELECT * FROM User WHERE id IN
    <foreach collection="list" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>
</select>

参数传递:

List<Integer> ids = Arrays.asList(1, 2, 3, 4);
List<User> users = userMapper.selectUsersByIds(ids);

生成的 SQL 语句为:

SELECT * FROM User WHERE id IN (1, 2, 3, 4);

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

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

相关文章

【Linux】基础IO(文件描述符、缓冲区、重定向)

&#x1f308;个人主页&#xff1a;秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343&#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/qinjh_/category_12625432.html 目录 前言 C文件IO相关操作 系统文件I/O open open函数返回值 文件描述符fd re…

Rspamd:开源垃圾邮件过滤系统

Rspamd 是一个开源垃圾邮件过滤和电子邮件处理框架&#xff0c;旨在根据各种规则评估消息&#xff0c;包括正则表达式、统计分析以及与 URL 黑名单等自定义服务的集成。 系统会分析每封邮件并做出判定&#xff0c;MTA可据此采取进一步行动&#xff0c;例如拒绝邮件或添加垃圾邮…

【GeekBand】C++设计模式笔记7_Bridge_桥接模式

1. “单一职责”模式 在软件组件的设计中&#xff0c;如果责任划分的不清晰&#xff0c;使用继承得到的结果往往是随着需求的变化&#xff0c;子类急剧膨胀&#xff0c;同时充斥着重复代码&#xff0c;这时候的关键是划清责任。典型模式 DecoratorBridge 2. Bridge 桥接模式…

UE5+ChatGPT实现3D AI虚拟人综合实战

第11章 综合实战&#xff1a;UE5ChatGPT实现3D AI虚拟人 通过结合Unreal Engine 5&#xff08;UE5&#xff09;的强大渲染能力和ChatGPT的自然语言处理能力&#xff0c;我们可以实现一个高度交互性的AI虚拟人。本文将详细介绍如何在UE5中安装必要的插件&#xff0c;配置OpenAI…

trans-cinnamate 4-monooxygenase肉桂酸4-羟化酶C4H的克隆和功能鉴定-文献精读62

Cloning and functional characterization of two cinnamate 4-hydroxylase genes from Pyrus bretschneideri 两种从白梨&#xff08;Pyrus bretschneideri&#xff09;中克隆和功能鉴定的肉桂酸4-羟化酶基因 摘要 肉桂酸4-羟化酶&#xff08;C4H&#xff09;是植物苯丙素类…

安装Spark-单机部署,Standalone集群部署,Spark on Yarn实现

目录 单机部署spark本地模式部署 Anaconda部署Python(3台机器都需要) Spark本地模式部署 Spark Python Shell Spark的Standalone集群部署 Standalone集群架构 Standalone集群部署 Standalone集群启动 Standalone集群测试 Spark on YARN的实现 Spark on YARN&#xf…

解决java: 无法访问java.lang.Record

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 错误描述 项目在编译期间报错&#xff1a;java: 无法访问java.lang.Record&#xff0c; 找不到java.lang.Record的类文件&#xff1b;图示如下&#xff1a; 解决方案 请在…

力扣203.移除链表元素

题目链接&#xff1a;203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6…

57.对称二叉树

迭代 class Solution {public boolean isSymmetric(TreeNode root) {if(rootnull){return true;}Deque<TreeNode> denew LinkedList<>();TreeNode l,r;int le;de.offer(root.left);de.offer(root.right);while(!de.isEmpty()){lde.pollFirst();rde.pollLast();if(…

如何使用MATLAB代码生成器生成ADRC跟踪微分器(TD) PLC源代码(ST)

ADRC线性跟踪微分器TD详细测试 ADRC线性跟踪微分器TD详细测试(Simulink 算法框图+CODESYS ST+博途SCL完整源代码)-CSDN博客文章浏览阅读383次。ADRC线性跟踪微分器(ST+SCL语言)_adrc算法在博途编程中scl语言-CSDN博客文章浏览阅读784次。本文介绍了ADRC线性跟踪微分器的算法和…

P3197 [HNOI2008] 越狱

题目传送门 题面 [HNOI2008] 越狱 题目描述 监狱有 n n n 个房间&#xff0c;每个房间关押一个犯人&#xff0c;有 m m m 种宗教&#xff0c;每个犯人会信仰其中一种。如果相邻房间的犯人的宗教相同&#xff0c;就可能发生越狱&#xff0c;求有多少种状态可能发生越狱。 …

js操作元素的其他操作(4个案例+效果图+代码)

目录 1. 获取元素的位置和大小 案例:获取元素的位置和大小 1.代码 2.效果 2. 获取元素的可视区域 案例:获取元素的可视区域 1.代码 2.效果 3. 元素的滚动操作 案例:元素的滚动操作 1.代码 2.效果 4. 获取鼠标指针位置 案例:时刻获取鼠标位置 1.代码 2.效果 案例:拖动的小球 1.代…

第一个Flutter应用(一)

1、创建项目 1.1 新建 1.2 选择Flutter SDK的位置 1.3 项目名称 英文单词加下划线起名规范&#xff0c;其他默认即可。 1.4 点击运行 发生报错显示我们的JAVA版本不符合 1.5 更改版本设置 1.6 再次启动项目 2、分析页面代码 以下是lib/main.dart的源代码&#xff08;为了阅…

为什么一定要用大模型,为什么说AI大模型开发人人必备?

AI 大模型技术经过2023年的狂飙&#xff0c;2024年迎来应用的落地&#xff0c;对 IT 同学来讲&#xff0c;这里蕴含着大量的技术机会&#xff0c;人人必备开发技能。 文讨论 AI 大模型开发技术大师的修炼之道&#xff0c;试图找到一个共同的速成模式&#xff0c;希望对 IT 同学…

数据结构(7.4_2)——B树的插入删除

B树的插入 B树的删除 对非终端结点的删除 对终端结点的删除 终端结点关键字低于下限时&#xff1a; 借后继结点&#xff1a; 借前驱结点&#xff1a; 结点合并&#xff1a; 总结 &#xff1a;

图像分割恢复方法

传统的图像分割方法主要依赖于图像的灰度值、纹理、颜色等特征&#xff0c;通过不同的算法将图像分割成多个区域。这些方法通常可以分为以下几类&#xff1a; 1.基于阈值的方法 2.基于边缘的方法 3.基于区域的方法 4.基于聚类的方法 下面详细介绍这些方法及其示例代码。 1. 基…

论文翻译 | Dynamic Prompting: A Unified Framework for Prompt Tuning

摘要 已经证明&#xff0c;在从预训练的基础模型中高效提取知识方面&#xff0c;提示调整&#xff08;prompt tuning&#xff09;技术是非常有效的&#xff0c;这些基础模型包括预训练的语言模型&#xff08;PLMs&#xff09;、视觉预训练模型以及视觉-语言&#xff08;V-L&…

【进阶OpenCV】 (7)--视频处理 - 之 - 背景建模及目标跟踪

文章目录 一、背景建模1. 目的2. 方法3. 帧差法4. 光流估计 二、代码步骤1. 读取视频2. 构建卷积核3. 背景建模 总结 一、背景建模 指在计算机视觉中&#xff0c;从视频序列中提取出静态背景的一种技术。在视频中&#xff0c;背景通常被定义为相对稳定的部分&#xff0c;例如墙…

vue2中 vue-count-to组件让数字从某个数字动态的显示到某个数字(后附vue3的用法)

1、首先安装 npm install vue-count-to2、使用 2.1、先导入组件 import countTo from ‘vue-count-to’2.2、注册组件 components: { countTo },2.3、使用组件 <countTo> <template><div class"home"><countTo class"count-to&qu…

【查找算法概念】与【线性表的相关查找算法】

1.知识回顾 2.查找算法相关问题汇总 2.1在哪里查找 查找表 2.2通过什么进行查找 关键字的对应 主关键字&#xff1a;比如我们可以通过一个学号来唯一确定一名学生 这里的学号就是一种主关键字。 次关键字&#xff1a;而通过一个名字李华&#xff0c;我们可能会确定不止一名…