做APP好还是建设网站好/视频广告联盟平台

做APP好还是建设网站好,视频广告联盟平台,响应式网站和不响应式,wordpress网站做成app6一、SQL 映射文件核心元素 MyBatis 映射文件的顶级元素(按定义顺序): cache:命名空间的缓存配置。cache-ref:引用其他命名空间的缓存。resultMap:自定义结果集映射。sql:可重用的 SQL 片段。i…

一、SQL 映射文件核心元素

MyBatis 映射文件的顶级元素(按定义顺序):

  1. cache:命名空间的缓存配置。
  2. cache-ref:引用其他命名空间的缓存。
  3. resultMap:自定义结果集映射。
  4. sql:可重用的 SQL 片段。
  5. insertupdatedelete:数据操作语句。
  6. select:查询语句。

二、参数传递与处理

1. 单参数

-基础类型/字符串

<select id="selectUser" resultType="User" parameterType="int">SELECT * FROM user WHERE id = #{id}
</select>

-POJO 对象

<insert id="insertUser" parameterType="User">INSERT INTO user (name, email) VALUES (#{name}, #{email})
</insert>

2. 多参数

- 默认 param1, param2(不推荐):

<select id="selectUser" resultType="User">SELECT * FROM user WHERE id = #{param1} AND name = #{param2}
</select>

- @Param 注解(推荐):

User selectUser(@Param("id") int id, @Param("name") String name);
<select id="selectUser" resultType="User">SELECT * FROM user WHERE id = #{id} AND name = #{name}
</select>

3. 复杂参数

- Map 类型

<select id="selectUserByMap" resultType="User" parameterType="map">SELECT * FROM user WHERE name = #{name} AND age = #{age}
</select>

- 混合参数(POJO + @Param):

List<User> selectUsers(@Param("role") String role, User user);
<select id="selectUsers" resultType="User">SELECT * FROM user WHERE role = #{role} AND age = #{user.age}
</select>

三、主键生成与回填

1. 自增主键(如 MySQL)

<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">INSERT INTO user (name, email) VALUES (#{name}, #{email})
</insert>
  • useGeneratedKeys="true":启用 JDBC 的自动生成主键。
  • keyProperty="id":将生成的主键赋值给对象的 id 属性。

2. 非自增主键(如 Oracle)

<insert id="insertUser"><selectKey keyProperty="id" resultType="int" order="BEFORE">SELECT MAX(id) + 1 FROM user</selectKey>INSERT INTO user (id, name) VALUES (#{id}, #{name})
</insert>
  • order="BEFORE":先执行 selectKey 生成主键,再插入数据。

四、结果映射(resultMap

1. 基础映射

<resultMap id="userResultMap" type="User"><id property="id" column="user_id" /><result property="name" column="user_name" />
</resultMap>

2. 关联对象(一对一)

<resultMap id="userWithRoleMap" type="User"><association property="role" javaType="Role"><id property="roleId" column="role_id" /><result property="roleName" column="role_name" /></association>
</resultMap>

3. 集合映射(一对多)

<resultMap id="userWithOrdersMap" type="User"><collection property="orders" ofType="Order"><id property="orderId" column="order_id" /><result property="orderNo" column="order_no" /></collection>
</resultMap>

五、动态 SQL

1. 条件查询(<if> + <where>

<select id="selectUser" resultType="User">SELECT * FROM user<where><if test="name != null">AND name = #{name}</if><if test="age != null">AND age = #{age}</if></where>
</select>

2. 循环遍历(<foreach>

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

1. 参数是 List

当方法参数直接传递一个 List 时,MyBatis 默认将其封装为 Map,键为 list

示例代码:
// DAO 方法
List<User> selectUsersByIds(@Param("ids") List<Integer> ids);
<!-- XML 映射 -->
<select id="selectUsersByIds" resultType="User">SELECT * FROM user WHERE id IN<foreach collection="ids" item="id" open="(" separator="," close=")">#{id}</foreach>
</select>
关键点:
  • collection="ids":对应 @Param("ids") 注解的参数名。
  • item="id":遍历的每个元素变量名。
  • open="("close=")":包裹生成的 SQL 片段。
  • separator=",":元素之间的分隔符。

2. 参数是 Set

Set 的处理方式与 List 类似,MyBatis 会自动将其转换为 List 处理。

示例代码:
// DAO 方法
List<User> selectUsersByNames(@Param("names") Set<String> names);
<!-- XML 映射 -->
<select id="selectUsersByNames" resultType="User">SELECT * FROM user WHERE name IN<foreach collection="names" item="name" open="(" separator="," close=")">#{name}</foreach>
</select>

3. 参数是数组

当直接传递数组时,collection 属性需指定为 array

示例代码:
// DAO 方法
List<User> selectUsersByIds(int[] ids);
<!-- XML 映射 -->
<select id="selectUsersByIds" resultType="User">SELECT * FROM user WHERE id IN<foreach collection="array" item="id" open="(" separator="," close=")">#{id}</foreach>
</select>

4. 参数是 Map 中的集合

如果参数是 Map,需通过 @Param 指定键名。

示例代码:
// DAO 方法
List<User> selectUsers(@Param("data") Map<String, Object> data);
<!-- XML 映射 -->
<select id="selectUsers" resultType="User">SELECT * FROM user WHERE id IN<foreach collection="data.ids" item="id" open="(" separator="," close=")">#{id}</foreach>AND name IN<foreach collection="data.names" item="name" open="(" separator="," close=")">#{name}</foreach>
</select>

5. 批量插入示例

使用 <foreach> 实现批量插入:

// DAO 方法
void batchInsertUsers(@Param("users") List<User> users);
<!-- XML 映射 -->
<insert id="batchInsertUsers">INSERT INTO user (name, email) VALUES<foreach collection="users" item="user" separator=",">(#{user.name}, #{user.email})</foreach>
</insert>

6. 遍历 Map 类型

当集合元素是 Map 时,indexitem 分别代表键和值。

示例代码:
// DAO 方法
void insertUserRoles(@Param("roles") Map<Integer, String> roles);
<!-- XML 映射 -->
<insert id="insertUserRoles">INSERT INTO role (user_id, role_name) VALUES<foreach collection="roles" index="userId" item="roleName" separator=",">(#{userId}, #{roleName})</foreach>
</insert>

7.关键注意事项

  1. 参数类型匹配

    • 单参数集合需通过 @Param 显式命名。
    • 多参数需用 @Param 避免混淆。
  2. 安全与性能

    • 始终使用 #{} 占位符(防止 SQL 注入)。
    • 批量操作时,注意数据库的 SQL 语句长度限制。
  3. 动态 SQL 灵活性

    • 结合 <if> 标签实现条件遍历:
      <foreach collection="ids" item="id"><if test="id != null">#{id}</if>
      </foreach>
      

8.总结

参数类型collection示例场景
List@Param 指定的名称IN 查询、批量插入
Set@Param 指定的名称去重后的 IN 查询
数组array原生数组参数的 IN 查询
Mapmap.key@Param复杂参数组合的动态查询

通过合理使用 <foreach>,可以高效处理集合类参数,简化批量操作和动态 SQL 的编写。

3. 分支选择(<choose>

<select id="selectUserByChoose" resultType="User">SELECT * FROM user<where><choose><when test="id != null">id = #{id}</when><otherwise>status = 1</otherwise></choose></where>
</select>

六、高级特性

1. 分步查询与延迟加载

  • 分步查询
    <resultMap id="catMap" type="Cat"><association property="owner" select="selectOwnerById" column="owner_id" />
    </resultMap>
    
  • 延迟加载配置
    <settings><setting name="lazyLoadingEnabled" value="true" /><setting name="aggressiveLazyLoading" value="false" />
    </settings>
    

2. SQL 片段复用(<sql>

<sql id="userColumns">id, name, email</sql>
<select id="selectUser" resultType="User">SELECT <include refid="userColumns" /> FROM user
</select>

七、特殊处理

1. #{}${}

以下是 #{}${} 的核心区别及使用场景总结,结合动态表名/字段的示例说明:


1. #{}${} 的核心区别

特性#{}${}
原理预编译(PreparedStatement)字符串直接拼接(SQL 注入风险)
安全性防 SQL 注入(推荐)不安全(需严格校验输入)
适用场景参数值(如 WHERE 条件)动态表名、列名、排序字段等
示例WHERE id = #{id}ORDER BY ${columnName}

2. 动态表名与字段的示例

场景 1:动态表名(如多租户系统)
<!-- 根据传入的表名查询数据 -->
<select id="selectByDynamicTable" resultType="User">SELECT * FROM ${tableName} WHERE id = #{id}
</select>
  • 调用方式
    List<User> users = userDao.selectByDynamicTable("user_2023", 1001);
    
  • 生成 SQL
    SELECT * FROM user_2023 WHERE id = ?
    
场景 2:动态排序字段
<!-- 根据传入的排序字段动态排序 -->
<select id="selectUsersOrderBy" resultType="User">SELECT * FROM user ORDER BY ${orderByColumn} ${sortDirection}
</select>
  • 调用方式
    List<User> users = userDao.selectUsersOrderBy("age", "DESC");
    
  • 生成 SQL
    SELECT * FROM user ORDER BY age DESC
    
场景 3:动态列名(如选择特定字段)
<!-- 选择动态列 -->
<select id="selectDynamicColumns" resultType="map">SELECT ${columns} FROM user WHERE id = #{id}
</select>
  • 调用方式
    Map<String, Object> result = userDao.selectDynamicColumns("name, email", 1001);
    
  • 生成 SQL
    SELECT name, email FROM user WHERE id = ?
    

3. 安全注意事项

  • 风险场景:如果用户输入未经校验,直接使用 ${} 可能导致 SQL 注入。

    // 危险示例:用户输入恶意表名
    String tableName = "user; DROP TABLE user; --";
    userDao.selectByDynamicTable(tableName, 1001); 
    

    生成 SQL

    SELECT * FROM user; DROP TABLE user; -- WHERE id = ?
    
  • 防御措施

    1. 白名单校验:限制动态值的范围。
      // 只允许特定表名
      if (!Arrays.asList("user", "employee").contains(tableName)) {throw new IllegalArgumentException("非法表名");
      }
      
    2. 转义特殊字符:过滤或转义输入中的特殊符号(如 ', ;)。

4. 总结

场景占位符示例安全性
参数值(如 id#{}WHERE id = #{id}安全(推荐)
动态表名${}FROM ${tableName}需校验输入(风险)
动态列名/排序字段${}ORDER BY ${column}需校验输入(风险)

原则

  • 优先使用 #{},确保安全性。
  • 仅在必要时使用 ${},并严格校验输入值。

2. 返回类型

1. 单对象:resultType="User"

  • 作用:将单条数据库记录映射到一个 Java 对象(如 User)。
  • 规则
    • 数据库列名需与 Java 对象属性名一致(或通过别名匹配),否则需使用 resultMap
    • 若查询结果为多条记录,会抛出异常(TooManyResultsException)。
  • 示例
    <select id="selectUserById" resultType="User">SELECT * FROM user WHERE id = #{id}
    </select>
    
    • 返回类型:User 对象。
    • 若未查询到数据,返回 null

2. 集合:resultType="User"

  • 作用:将多条数据库记录映射为 List<User>
  • 规则
    • MyBatis 自动将多行结果封装为 List,无需额外配置。
    • 若查询结果为空,返回空列表(非 null)。
  • 示例
    <select id="selectAllUsers" resultType="User">SELECT * FROM user
    </select>
    
    • 返回类型:List<User>
    • 即使结果为空,返回 Collections.emptyList()

3. Map 类型

3.1 直接返回 MapresultType="map"
  • 作用:将单条记录映射为 Map<String, Object>,键为列名,值为对应数据。
  • 示例
    <select id="selectUserAsMap" resultType="map">SELECT id, name FROM user WHERE id = #{id}
    </select>
    
    • 返回类型:Map<String, Object>,如 {"id": 1, "name": "Alice"}
3.2 使用 @MapKey 注解返回 Map<K, V>
  • 作用:将多条记录映射为 Map<K, V>,其中:
    • 键(K):由 @MapKey 指定的属性值(如 id)。
    • 值(V):对应的 Java 对象。
  • 规则
    • 需在 DAO 接口方法上添加 @MapKey("属性名")
    • 查询结果中指定的属性值必须唯一,否则会覆盖或抛出异常。
  • 示例
    @MapKey("id")
    Map<Integer, User> selectAllUsersAsMap();
    
    <select id="selectAllUsersAsMap" resultType="User">SELECT * FROM user
    </select>
    
    • 返回类型:Map<Integer, User>,键为 Userid,值为对应的 User 对象。

4.关键区别与注意事项

类型resultType返回值类型适用场景
单对象UserUser查询单条记录
集合UserList<User>查询多条记录
单条记录的 MapmapMap<String, Object>需要灵活访问列名/值的场景
多条记录的 MapUser + @MapKeyMap<K, User>以特定属性为键,对象为值的映射

5.常见问题

  1. 字段名与属性名不一致

    • 使用 resultMap 或 SQL 别名(AS)解决:
      <select id="selectUser" resultType="User">SELECT user_id AS id, user_name AS name FROM user
      </select>
      
  2. 集合返回类型为 null

    • MyBatis 默认返回空集合(Collections.emptyList()),而非 null
  3. @MapKey 的唯一性

    • 若指定的键属性(如 id)存在重复值,MyBatis 会保留最后一个匹配的对象,可能导致数据丢失。

6.总结

  • 单对象:直接使用 resultType="User"
  • 集合:同样使用 resultType="User",MyBatis 自动封装为 List
  • Map
    • 单条记录:resultType="map"
    • 多条记录:结合 @MapKey 注解,指定键属性。

合理选择 resultType 可简化结果映射,提升开发效率。


八、总结

场景解决方案示例
自增主键useGeneratedKeys="true" + keyProperty="id"插入后自动填充 id
多参数查询@Param 注解#{id} + #{name}
字段名与属性名映射resultMap<result property="userName" column="user_name" />
动态条件查询<if> + <where>按条件拼接 WHERE 子句
批量操作<foreach>IN (1, 2, 3)

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

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

相关文章

【计算机网络】计算机网络协议、接口与服务全面解析——结合生活化案例与图文详解

协议、接口与服务 导读一、协议1.1 定义1.2 组成 二、接口三、服务3.1 定义3.2 服务与协议的区别3.3 分类3.3.1 面向连接服务于无连接服务3.3.2 可靠服务和不可靠服务3.3.3 有应答服务和无应答服务 结语 导读 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;…

vue数字公式篇 Tinymce结合使用(二)

继上一篇的数字公式 &#xff0c; 这次的功能是将公式能插入编辑器以及修改 1、Tinymce 自定义 LateX 按钮&#xff0c;打开公式编辑器窗口 LateX.vue window.tinymce.init({...//基础配置这里我就不写了setup(ed) {//自定义 LateX 按钮ed.ui.registry.addButton(LateX, {text:…

数据结构初阶-二叉树链式

目录 1.概念与结构 2.二叉数链式的实现 2.1遍历规则 2.2申请内存空间 2.3手动构建一棵二叉树 2.4二叉树结点的个数 2.5二叉树叶子结点的个数 2.6二叉树第K层结点个数 2.7二叉树的高度 2.8二叉树中查找值为x的结点 2.9二叉树的销毁 3.层序遍历 3.1概念 3.2层序遍历…

鸿蒙HarmonyOS NEXT之无感监听

鸿蒙中存在一些无感监听&#xff0c;这些监听经过系统API封装使用很简单&#xff0c;但是对实际业务开发中有很重要&#xff0c;例如埋点业务、数据统计、行为上报、切面拦截等。 Navigation的页面切换 在鸿蒙中Navigation被用来作为路由栈进行页面跳转&#xff0c;如果你想知…

批量处理word里面表格的空白行

1&#xff0c;随便打开一个word文档。 2&#xff0c;按下Alt F11 VBA编辑器,在左侧的「工程资源管理器」窗口中找到Normal 项目,右键选择插入->模块。 弹出一下弹窗 3&#xff0c;输入一下代码 代码&#xff1a; Sub RemoveEmptyTableRows()Dim tbl As TableDim row As R…

3ds Max 2026 新功能全面解析

一、视口性能与交互体验升级 1. Hydra 2.0 视口渲染引擎 3ds Max 2026 引入了 Hydra 2.0&#xff0c;大幅优化了视口渲染性能&#xff0c;尤其是在处理复杂场景和高质量实时预览时&#xff0c;流畅度提升显著。 支持USD&#xff08;通用场景描述&#xff09;格式&#xff0c…

JVM垃圾回收笔记02-垃圾回收器

文章目录 前言1.串行(Serial 收集器/Serial Old 收集器)Serial 收集器Serial Old 收集器相关参数-XX:UseSerialGC 2.吞吐量优先(Parallel Scavenge 收集器/Parallel Old 收集器)Parallel Scavenge 收集器Parallel Old 收集器相关参数-XX:UseParallelGC ~ -XX:UseParallelOldGC-…

使用AI一步一步实现若依(26)

功能26&#xff1a;新增一个新员工培训页面 功能25&#xff1a;角色管理 功能24&#xff1a;菜单管理 功能23&#xff1a;从后端获取路由/菜单数据 功能22&#xff1a;用户管理 功能21&#xff1a;使用axios发送请求 功能20&#xff1a;使用分页插件 功能19&#xff1a;集成My…

vue响应式原理剖析

一、什么是响应式? 我们先来看一下响应式意味着什么?我们来看一段代码: m有一个初始化的值,有一段代码使用了这个值; 那么在m有一个新的值时,这段代码可以自动重新执行; let m = 20 console.log(m) console.log(m * 2)m = 40上面的这样一种可以自动响应数据变量的代码机…

无人机航电系统电池技术解析!

1. 常用电池类型 锂聚合物电池&#xff08;LiPo&#xff09; 特点&#xff1a;高能量密度、轻量化、放电效率高&#xff0c;是目前主流选择。 缺点&#xff1a;对过充/过放敏感&#xff0c;需严格管理&#xff0c;存在轻微膨胀或起火风险。 锂离子电池&#xff08;Li-ion…

ubuntu下终端打不开的排查思路和解决方法

问题现象描述&#xff1a;ubuntu开机后系统桌面显示正常&#xff0c;其他图形化的app也都能打开无异常&#xff0c;唯独只有terminal终端打不开&#xff0c;无论是鼠标点击终端软件&#xff0c;还是ctrlaltt&#xff0c;还是altF2后输入gnome-terminal后按回车&#xff0c;这三…

Maven入门

1、简介 Apache Maven是一个项目管理及自动构建工具&#xff0c;由Apache软件基金会所提供。基于项目对象模型&#xff08;缩写&#xff1a;POM&#xff09;概念&#xff0c;Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。 2、作用 1&#xff09;依赖导…

Rk3588,Opencv读取Gmsl相机,Rga yuv422转换rgb (降低CPU使用率)

RK3588, 使用OpenCv 读取 gmsl 相机,获得yuv422格式图像, 使用 rga 转换 rgb 图像。减少cpu占用率. 查看相机信息 v4l2-ctl --all -d /dev/cam0 , 查看自己相机分辨率,输出格式等信息,对应修改后续代码测试… Driver Info:Driver name : rkcifCard type : rkc…

【NLP 49、提示工程 prompt engineering】

目录 一、基本介绍 语言模型生成文本的基本特点 提示工程 prompt engineering 提示工程的优势 使用注意事项 ① 安全问题 ② 可信度问题 ③ 时效性与专业性 二、应用场景 能 ≠ 适合 应用场景 —— 百科知识 应用场景 —— 写文案 应用场景 —— 解释 / 编写…

SpringCould微服务架构之Docker(3)

1&#xff09;什么是镜像和容器&#xff1f; 2&#xff09;DockerHub&#xff1a; 3&#xff09;docker的架构如下&#xff1a;

智慧高速,安全护航:视频监控平台助力高速公路高效运营

随着我国高速公路里程的不断增长&#xff0c;交通安全和运营效率面临着前所未有的挑战。传统的监控方式已难以满足现代化高速公路管理的需求&#xff0c;而监控视频平台的出现&#xff0c;则为高速公路的安全运营提供了强有力的技术支撑。高速公路视频监控联网解决方案 高速公路…

AI 在测试中的应用:从自动化到智能化的未来

阅读原文 在上一篇中&#xff0c;我们探讨了测试左移与右移如何构建质量保障的全流程闭环。现在&#xff0c;我们将目光投向更前沿的领域——AI在测试中的应用。这不仅是技术的演进&#xff0c;更是测试理念的革命&#xff1a;从"自动化执行"到"智能决策"…

# 使用自定义Shell脚本hello快速配置Linux用户账户

使用自定义Shell脚本快速配置Linux用户账户 在学校实验室管理Linux服务器&#xff0c;或者公司小团队管理服务器时&#xff0c;大家需要一个能隔离自己服务&#xff0c;但是自己又需要对服务器的完整权限的情形。创建和配置用户账户是一项常见但繁琐的任务。特别是当你需要频繁…

Unity Animation的其中一种运用方式

Animation是Unity的旧的动画系统&#xff0c;先说目的&#xff0c;其使用是为了在UI中播放动效&#xff0c;并且在动效播放结束后接自定义事件而设计的 设计的关键点在于&#xff0c;这个脚本不是通过Animation直接播放动画片段&#xff0c;而是通过修改AnimationState的nor…

matplotlib——南丁格尔玫瑰

南丁格尔玫瑰图&#xff08;Nightingale Rose Chart&#xff09;&#xff0c;是一种特殊形式的柱状图&#xff0c;它以南丁格尔&#xff08;Florence Nightingale&#xff09;命名&#xff0c;她在1858年首次使用这种图表来展示战争期间士兵死亡原因的数据。 它将数据绘制在极坐…