String.xml中product属性使用

本文详细介绍了如何在Android的资源文件string.xml中,通过定义不同的product参数来实现动态显示不同字符串的方法,使应用能够根据不同设备类型(如智能电视或智能手机)提供定制化的用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android的资源文件string.xml会出现下面同名的字符串,如下所示

 

<string name="build_type" product="tv">"智能电视"</string>
<string name="build_type" product="phone">"智能手机"</string>

不同的product就会取不同的值。


product的值在对应的device目录下的mk文件当中有定义:PRODUCT_CHARACTERISTICS := tv

这样就能根据不同的产品显示不同的值了。

 

<think>在Java的SQL XML文件中拼接字符串通常指的是在MyBatis的mapper XML文件中动态构建SQL语句。需要特别注意避免SQL注入问题,因此不推荐直接使用字符串拼接,而应使用MyBatis提供的动态SQL标签(如`<if>`、`<choose>`、`<foreach>`等)或`<bind>`标签进行安全拼接。 ### 安全拼接方法 1. **使用`<bind>`标签**(推荐) - 用于创建一个变量并绑定值,可在SQL中重复使用 - 示例:模糊查询拼接 ```xml <select id="searchUsers" resultType="User"> <bind name="pattern" value="'%' + name + '%'" /> SELECT * FROM users WHERE username LIKE #{pattern} </select> ``` 2. **动态SQL标签组合** - 根据条件动态生成SQL片段 - 示例:多条件查询 ```xml <select id="findUsers" resultType="User"> SELECT * FROM users <where> <if test="name != null"> AND username LIKE CONCAT('%', #{name}, '%') </if> <if test="email != null"> AND email = #{email} </if> </where> </select> ``` 3. **CONCAT函数**(数据库函数) - 在SQL语句中直接使用数据库的字符串连接函数 - 示例:MySQL的CONCAT ```xml <select id="search" resultType="map"> SELECT * FROM table WHERE column LIKE CONCAT('%', #{param}, '%') </select> ``` ### 禁止直接拼接(防SQL注入) ❌ 危险示例(绝对避免): ```xml <select id="unsafeQuery" resultType="User"> SELECT * FROM users WHERE username = '${username}' </select> ``` - `${}`会直接注入原始字符串,导致SQL注入风险[^2] ### 最佳实践 1. **始终使用`#{}`占位符**:MyBatis会将其转换为预编译参数(PreparedStatement) 2. **复杂逻辑移至Java代码**:在XML中难以处理的拼接,可在Java中使用`@SelectProvider`构建SQL[^1] 3. **使用`<sql>`片段重用**:减少重复拼接 ```xml <sql id="userColumns">id, username, email</sql> <select id="selectUsers" resultType="User"> SELECT <include refid="userColumns"/> FROM users </select> ``` ### 完整示例 ```xml <!-- 安全拼接模糊查询 --> <select id="searchByDynamicCondition" resultType="User"> <bind name="namePattern" value="'%' + name + '%'"/> SELECT * FROM users <where> <if test="name != null"> username LIKE #{namePattern} </if> <if test="minAge != null"> AND age >= #{minAge} </if> </where> ORDER BY <choose> <when test="orderBy == 'name'">username</when> <otherwise>id</otherwise> </choose> </select> ``` > ⚠️ 关键点:所有用户输入必须通过`#{}`传递,XML中拼接仅用于结构动态化,而非值拼接。 通过以上方法,可在保证安全的前提下实现灵活的SQL拼接。对于极端复杂的场景,建议使用MyBatis Generator或MyBatis Dynamic SQL等工具辅助[^1][^5]。 §§相关问题§§ 1. MyBatis中`#{}`和`${}`有什么区别? 2. 如何在MyBatis中实现动态排序(ORDER BY字段动态变化)? 3. MyBatis的`<foreach>`标签如何使用? 4. 如何防止MyBatis应用中的SQL注入攻击? [^1]: MyBatis官方文档推荐使用动态SQL标签或`@SelectProvider`构建安全SQL[^1]。 [^2]: 直接拼接用户输入会导致SQL注入漏洞,应严格避免[^2]。 [^5]: 复杂SQL可通过Java代码拼接后通过`@SelectProvider`注入[^5]。</think>### Java SQL XML 文件中安全拼接字符串的方法 在 MyBatis 的 SQL XML 文件中安全地拼接字符串,需要避免直接拼接以防止 SQL 注入风险[^2]。以下是推荐的三种安全方法: #### 1. 使用 `<bind>` 标签(推荐) ```xml <select id="searchUsers" resultType="User"> <!-- 安全拼接字符串 --> <bind name="pattern" value="'%' + name + '%'" /> SELECT * FROM users WHERE username LIKE #{pattern} AND status = 'ACTIVE' </select> ``` - **优点**:在 MyBatis 内部完成拼接,自动处理特殊字符 - **原理**:创建临时变量 `pattern` 存储拼接结果[^1] #### 2. 使用 SQL 函数拼接(数据库层) ```xml <select id="findItems" resultType="Item"> SELECT * FROM products WHERE <!-- 使用数据库的字符串函数 --> product_name LIKE CONCAT('%', #{keyword}, '%') </select> ``` - **注意**:`CONCAT` 是 MySQL 函数,Oracle 用 `||`,SQL Server 用 `+` - **优势**:拼接在数据库层面执行,避免应用层风险 #### 3. 动态 SQL 标签组合 ```xml <select id="dynamicSearch" resultType="Result"> SELECT * FROM table <where> <if test="name != null"> AND fullname LIKE CONCAT(#{name}, '%') <!-- 前缀匹配 --> </if> <if test="location != null"> AND city = #{location} </if> </where> </select> ``` - **安全机制**:`#{param}` 语法会被转换为预编译参数 - **灵活性**:`<if>` 标签实现条件拼接[^1] --- ### ⚠️ 禁止的危险做法(SQL 注入风险) ```xml <!-- 危险示例:直接拼接用户输入 --> <select id="unsafeQuery"> SELECT * FROM users WHERE username = '${username}' <!-- ${} 会直接注入原始字符串 --> </select> ``` - **风险**:如果用户输入 `' OR '1'='1`,会变成 `WHERE username = '' OR '1'='1'`,返回所有数据[^2] --- ### 最佳实践 1. **始终使用 `#{}` 替代 `${}`** `#{}` 会自动参数化输入,`${}` 会直接拼接原始字符串 2. **复杂拼接移到 Java 代码** 使用 `@SelectProvider` 动态生成 SQL[^1]: ```java public class UserSqlProvider { public String searchByName(String name) { return new SQL() {{ SELECT("*"); FROM("users"); WHERE("username LIKE CONCAT('%', #{name}, '%')"); }}.toString(); } } ``` 3. **XML 中处理特殊字符** ```xml <bind name="safeValue" value="@com.example.EscapeUtils@escapeSql(value)" /> ``` 4. **使用 CDATA 区包裹复杂 SQL** ```xml <select id="complexQuery"> <![CDATA[ SELECT * FROM table WHERE date > #{startDate} AND name <> ${unsafeValue} <!-- 仍然不推荐 ${} --> ]]> </select> ``` > 关键原则:**所有用户输入必须通过 `#{}` 传递**,XML 拼接只用于固定字符串组合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值