java中空字符串trim
时间: 2023-12-04 21:40:28 浏览: 113
以下是Java中空字符串trim的方法:
```java
String str1 = " hello world ";
String str2 = str1.trim();
System.out.println(str2); // 输出:hello world
```
上述代码中,我们首先定义了一个包含前后空格的字符串`str1`,然后使用`trim()`方法去除了前后空格,将结果赋值给了`str2`,最后输出`str2`的值,即为去除前后空格后的字符串。
另外,如果要删除字符串中所有的空格,可以使用`StringUtils`类中的`deleteWhitespace()`方法,如下所示:
```java
import org.apache.commons.lang3.StringUtils;
String str = " hello world ";
String str2 = StringUtils.deleteWhitespace(str);
System.out.println(str2); // 输出:helloworld
```
相关问题
oracle mysql pgsql 插入空字符串和null的区别
<think>嗯,用户现在想了解在SSM框架中使用不同数据库(Oracle、MySQL、PostgreSQL)时插入空字符串和NULL的区别及注意事项。这个问题看起来涉及到不同数据库对空值和空字符串的处理方式,以及如何在SSM框架中正确配置以避免问题。首先,我需要回顾一下各个数据库在这方面的特性。
首先,用户提到的三个数据库:Oracle、MySQL、PostgreSQL。我需要分别分析它们对空字符串和NULL的处理。根据之前的知识,Oracle会把空字符串当作NULL处理,而MySQL和PostgreSQL则区分空字符串和NULL。但需要确认这一点是否正确,特别是PostgreSQL的最新版本是否有变化。比如,我记得PostgreSQL确实允许空字符串和NULL共存,而Oracle确实在隐式转换中将空字符串转为NULL。
接下来,需要考虑在SSM框架中,特别是MyBatis,如何处理这些差异。例如,当Java中的字段为空字符串时,MyBatis在生成SQL语句时,是插入空字符串还是NULL?这可能涉及到MyBatis的配置以及数据库驱动程序的设置。比如,MySQL的驱动可能有参数来控制是否将空字符串转换为NULL,比如jdbc:mysql://...?emptyStringsConvertToZero=false。
然后,用户提到使用SSM框架,即Spring、Spring MVC、MyBatis。需要考虑到各个层中的处理,例如Controller层接收到的参数可能包含空字符串,Service层处理业务逻辑,DAO层通过MyBatis与数据库交互。此时,如何确保数据在不同层之间正确传递,并且最终生成正确的SQL语句是关键。
另外,用户提供的引用中有提到MyBatis-Plus不能解决所有问题,可能需要手动编写SQL,这时候需要特别注意SQL语句中空字符串和NULL的正确使用。例如,在Oracle中插入空字符串会被转为NULL,那么在编写插入语句时,如果希望插入NULL,可以直接插入空字符串,但若需要明确插入NULL,可能需要特别处理。
接下来,需要总结各个数据库的区别:
1. Oracle:空字符串视为NULL,插入空字符串会存储为NULL,查询空字符串需要使用IS NULL。
2. MySQL:严格模式下,空字符串和NULL是不同的,非严格模式下可能允许某些字段为空字符串即使定义为NOT NULL。
3. PostgreSQL:明确区分空字符串和NULL,字段是否允许空字符串或NULL取决于表定义。
然后,注意事项方面,需要考虑字段的约束(如NOT NULL)、默认值、索引的影响。例如,在Oracle中,如果字段设置为NOT NULL,尝试插入空字符串会报错,因为空字符串被转为NULL,而NULL违反NOT NULL约束。
在SSM框架中的配置,比如MyBatis的映射文件中,如何处理空字符串。例如,使用<if test="field != null">或者<if test="field != ''">来判断是否插入值,或者使用动态SQL标签来避免插入不必要的NULL或空字符串。
另外,前端传递的数据可能包含空字符串,需要后端验证和处理,确保符合数据库的约束。例如,在Spring MVC中,可以使用@NotBlank或@NotNull注解来验证参数,避免将无效数据传递到DAO层。
还需要考虑数据库驱动的配置参数,例如MySQL的jdbc参数,如allowMultiQueries、zeroDateTimeBehavior等,是否影响空字符串的处理。
可能还需要提到测试的重要性,尤其是在不同数据库环境下测试插入操作,确保行为一致。例如,使用JUnit测试用例,针对不同数据库运行,验证空字符串和NULL的处理是否符合预期。
最后,总结最佳实践,比如在设计表结构时明确字段是否允许NULL或空字符串,统一框架层的处理逻辑,使用数据库约束和校验注解,以及进行充分的测试。</think>---
### SSM框架中插入空字符串与NULL的差异及注意事项(Oracle/MySQL/PostgreSQL)
---
#### 一、核心差异对比
| **行为** | Oracle 12c+ | MySQL 8.0 | PostgreSQL 15 |
|-------------------|--------------------------|--------------------------|--------------------------|
| **空字符串存储** | 自动转换为NULL | 存储为真实空字符串 | 存储为真实空字符串 |
| **NULL比较** | `'' IS NULL`返回true | `'' IS NULL`返回false | `'' IS NULL`返回false |
| **字段约束冲突** | NOT NULL字段不能插入空串 | NOT NULL字段允许空字符串 | NOT NULL字段允许空字符串 |
---
#### 二、各数据库具体表现
1. **Oracle**
- **特性**:所有空字符串(`''`)会被隐式转换为NULL[^1]
- **插入示例**:
```sql
INSERT INTO users(name) VALUES ('') -- 实际存储为NULL
```
- **查询陷阱**:
```sql
SELECT * FROM users WHERE name = '' -- 无结果返回(需用IS NULL)
```
2. **MySQL**
- **模式影响**:
```sql
-- 严格模式下(默认开启):
CREATE TABLE test (col VARCHAR(10) NOT NULL);
INSERT INTO test VALUES('') -- 成功(空字符串≠NULL)
INSERT INTO test VALUES(NULL) -- 违反约束
```
3. **PostgreSQL**
- **明确区分**:
```sql
CREATE TABLE demo (
id SERIAL PRIMARY KEY,
empty_str VARCHAR(10) CHECK(empty_str != '') -- 禁止空字符串但允许NULL
)
```
---
#### 三、SSM框架处理要点
1. **MyBatis映射控制**
- **动态SQL处理**:
```xml
<insert id="insertUser">
INSERT INTO users
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="name != null">name,</if> <!-- 同时过滤NULL和空字符串 -->
<if test="name != null and name != ''">name,</if> <!-- 精确控制 -->
</trim>
VALUES (...)
</insert>
```
- **类型处理器**:
```java
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) {
ps.setString(i, "".equals(parameter) ? null : parameter); // Oracle专用处理
}
```
2. **Spring数据校验**
- **DTO层验证**:
```java
public class UserDTO {
@NotBlank(message = "名称不能为空") // 禁止空字符串和NULL
private String name;
@Nullable // 允许NULL但禁止空字符串(需自定义校验器)
private String description;
}
```
3. **驱动配置差异**
- **MySQL连接参数**:
```properties
# 关闭空字符串转NULL(默认true)
jdbc.url=jdbc:mysql://host/db?emptyStringsConvertToZero=false
```
- **Oracle特殊处理**:
```java
// 插入前强制转换
if (StringUtils.isEmpty(entity.getRemark())) {
entity.setRemark(null); // 避免Oracle的空字符串转NULL冲突
}
```
---
#### 四、跨数据库兼容方案
1. **统一字段设计规范**
- 重要业务字段使用`NOT NULL DEFAULT ''`(MySQL/PostgreSQL)
- 禁用Oracle的`VARCHAR2(0)`特殊类型[^3]
2. **SSM框架层抽象**
```java
public abstract class BaseDao {
protected void preProcessEmptyString(BaseEntity entity) {
// Oracle环境专用处理
if (isOracleDB()) {
Field[] fields = entity.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.getType() == String.class) {
field.setAccessible(true);
String value = (String) field.get(entity);
if ("".equals(value)) field.set(entity, null);
}
}
}
}
}
```
3. **测试策略**
- 边界测试用例:
```java
@Test
public void testInsertEmptyString() {
User user = new User();
user.setName(""); // 空字符串
userMapper.insert(user); // 验证不同数据库的实际存储值
assertThat(user.getName()).isEqualTo(isOracle ? null : "");
}
```
---
#### 五、典型问题解决方案
**场景1:Oracle中需要存储真实空字符串**
```sql
-- 使用特殊占位符(需应用层转换)
ALTER TABLE products ADD (remark VARCHAR2(10) DEFAULT '[[EMPTY]]');
-- Java层处理
public String getRemark() {
return "[[EMPTY]]".equals(this.remark) ? "" : this.remark;
}
```
**场景2:MySQL严格模式下的历史数据迁移**
```sql
-- 临时关闭约束
SET SESSION sql_mode = '';
INSERT INTO archive SELECT * FROM old_table WHERE col = '';
SET SESSION sql_mode = 'STRICT_TRANS_TABLES';
```
---
#### 六、最佳实践总结
1. **设计阶段**明确字段是否需要区分`''`和`NULL`
2. **框架层**实现数据库类型自适应的空值处理
3. **持久层**使用MyBatis的`<choose>`处理多数据库差异
4. **验证环节**增加数据库类型识别标记(通过`jdbcTemplate.getMetaData()`)
5. **文档标注**在字段注释中注明特殊处理要求
---
使用poi getstringvalue的时候字符串的空占位符没有了
### 解决使用Apache POI `GetStringValue` 方法时保留字符串中空占位符的问题
当处理文档中的占位符并希望即使这些占位符为空也能被保留下来而不消失,可以通过自定义逻辑来实现这一需求。通常情况下,`GetStringValue` 方法会返回单元格的内容作为字符串形式,但如果遇到未填充的占位符,默认行为可能会将其忽略或删除。
为了确保空占位符不被移除,可以在读取和写入数据的过程中加入额外的检查机制:
#### 自定义解析器
创建一个自定义的方法用于获取单元格值,并在此方法内部添加对于特定占位符模式的支持。这样即便实际内容为空也可以通过预设的方式显示出来,比如保持原始占位符不变或是替换成其他提示性的文字[^1]。
```java
public static String getCellValueWithPlaceHolder(Cell cell, Map<String, Object> params) {
if (cell == null || cell.getCellType() != Cell.CELL_TYPE_STRING) {
return "";
}
String content = cell.getStringCellValue();
// 正则表达式匹配 ${param_name}
Pattern pattern = Pattern.compile("\\$\\{([a-zA-Z_]+)\\}");
Matcher matcher = pattern.matcher(content);
StringBuffer sb = new StringBuffer();
while(matcher.find()){
String paramName = matcher.group(1);
Object paramValue = params.get(paramName);
if (paramValue != null && !"".equals(paramValue.toString().trim())) {
matcher.appendReplacement(sb, paramValue.toString());
} else {
// 如果参数不存在或者为空,则保留原样
matcher.appendReplacement(sb, "${" + paramName + "}");
}
}
matcher.appendTail(sb);
return sb.toString();
}
```
此函数接收一个 `Cell` 对象以及包含键值对映射关系的地图结构(即公共参数),遍历整个字符串查找所有的 `${}` 形式的占位符,并根据传入的数据源决定是否替换它们;如果没有找到对应的值或者是空串,则维持原有的占位符格式。
另外,在设置新的值到 Excel 单元格之前也应当采取类似的策略以防止覆盖掉现有的占位符标记[^3]。
阅读全文
相关推荐












