fixed NPE in ArrayTypeHandler.setNonNullParameter

This commit is contained in:
开源海哥 2023-06-28 13:53:50 +08:00
parent 15cad2ad88
commit 581007e1da
6 changed files with 243 additions and 12 deletions

View File

@ -25,10 +25,7 @@ import java.lang.reflect.Proxy;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* SQL 审计详细消息
@ -189,14 +186,17 @@ public class AuditMessage implements Serializable {
}
private void doAddParam(Statement statement, Object object) {
if (object instanceof TypeHandlerObject) {
try {
try {
if (object instanceof TypeHandlerObject) {
((TypeHandlerObject) object).setParameter(createPreparedStatement(statement), 0);
} catch (SQLException e) {
//ignore
} else if (object instanceof java.sql.Array) {
Object array = ((java.sql.Array) object).getArray();
queryParams.add(array);
} else {
queryParams.add(object);
}
} else {
queryParams.add(object);
} catch (SQLException e) {
//ignore
}
}

View File

@ -15,8 +15,10 @@
*/
package com.mybatisflex.core.util;
import java.lang.reflect.Array;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.StringJoiner;
import java.util.regex.Matcher;
public class SqlUtil {
@ -81,7 +83,8 @@ public class SqlUtil {
/**
* 替换 sql 中的问号
* @param sql sql 内容
*
* @param sql sql 内容
* @param params 参数
* @return 完整的 sql
*/
@ -96,6 +99,14 @@ public class SqlUtil {
else if (value instanceof Number || value instanceof Boolean) {
sql = sql.replaceFirst("\\?", value.toString());
}
// array
else if (ClassUtil.isArray(value.getClass())) {
StringJoiner joiner = new StringJoiner(",");
for (int i = 0; i < Array.getLength(value); i++) {
joiner.add(String.valueOf(Array.get(value, i)));
}
sql = sql.replaceFirst("\\?", "[" + joiner + "]");
}
// other
else {
StringBuilder sb = new StringBuilder();
@ -116,5 +127,4 @@ public class SqlUtil {
}
}

View File

@ -0,0 +1,128 @@
package com.mybatisflex.test;
import com.mybatisflex.annotation.*;
import com.mybatisflex.core.handler.Fastjson2TypeHandler;
import com.mybatisflex.core.mask.Masks;
import org.apache.ibatis.type.ArrayTypeHandler;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Table(value = "tb_account", dataSource = "ds2", onSet = AccountOnSetListener.class)
public class Account05 extends BaseEntity implements Serializable, AgeAware {
private static final long serialVersionUID = 1L;
@Id(keyType = KeyType.Auto)
private Long id;
@ColumnMask(Masks.CHINESE_NAME)
private String userName;
private int age;
@NotBlank
private Date birthday;
@Column(typeHandler = Fastjson2TypeHandler.class, isLarge = true)
private Map<String, Object> options;
@Column(isLogicDelete = true)
private Boolean isDelete;
private List<Article> articles;
@Column(typeHandler = ArrayTypeHandler.class)
private Long[] dataScope;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Override
public int getAge() {
return age;
}
@Override
public void setAge(int age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Map<String, Object> getOptions() {
return options;
}
public void setOptions(Map<String, Object> options) {
this.options = options;
}
public void addOption(String key, Object value) {
if (options == null) {
options = new HashMap<>();
}
options.put(key, value);
}
public Boolean getDelete() {
return isDelete;
}
public void setDelete(Boolean delete) {
isDelete = delete;
}
public List<Article> getArticles() {
return articles;
}
public void setArticles(List<Article> articles) {
this.articles = articles;
}
public Long[] getDataScope() {
return dataScope;
}
public void setDataScope(Long[] dataScope) {
this.dataScope = dataScope;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", userName='" + userName + '\'' +
", age=" + age +
", birthday=" + birthday +
", options=" + options +
", isDelete=" + isDelete +
", articles=" + articles +
'}';
}
}

View File

@ -0,0 +1,63 @@
/**
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.test;
import com.mybatisflex.core.MybatisFlexBootstrap;
import com.mybatisflex.core.audit.AuditManager;
import com.mybatisflex.core.audit.ConsoleMessageCollector;
import com.mybatisflex.core.audit.MessageCollector;
import com.mybatisflex.mapper.Account05Mapper;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import javax.sql.DataSource;
public class AccountInsertWithArrayAttrTestStarter {
public static void main(String[] args) {
DataSource dataSource = new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("schema05.sql")
.addScript("data05.sql")
.build();
MybatisFlexBootstrap bootstrap = MybatisFlexBootstrap.getInstance()
.setDataSource(dataSource)
.addMapper(Account05Mapper.class)
.start();
//开启审计功能
AuditManager.setAuditEnable(true);
//设置 SQL 审计收集器
MessageCollector collector = new ConsoleMessageCollector();
AuditManager.setMessageCollector(collector);
//
// String insertSql = "INSERT INTO `tb_account`(`id`,`user_name`, `age`, `birthday`, `options`, `is_delete`, `data_scope`) VALUES (?, ?, ?, ?, ?, ?, ?)";
// Db.insertBySql(insertSql,null,"lisi",null,null,null,null,null);
Account05Mapper accountMapper = bootstrap.getMapper(Account05Mapper.class);
Account05 account = new Account05();
account.setId(3L);
account.setUserName("lisi");
account.setDataScope(new Long[]{1L,2L});
accountMapper.insertWithPk(account,false);
}
}

View File

@ -0,0 +1,9 @@
INSERT INTO tb_account
VALUES (1, '张三', 18, 0,'2020-01-11', null,null,0),
(2, '王麻子叔叔', 19, 1, '2021-03-21', null,null,0);
INSERT INTO tb_article
VALUES (1, 1,'标题1', '内容1',0),
(2, 2,'标题2', '内容2',0),
(3, 1,'标题3', '内容3',0);

View File

@ -0,0 +1,21 @@
CREATE TABLE IF NOT EXISTS `tb_account`
(
`id` INTEGER PRIMARY KEY auto_increment,
`user_name` VARCHAR(100),
`age` Integer,
`sex` Integer,
`birthday` DATETIME,
`options` VARCHAR(1024),
`data_scope` VARCHAR(1024),
`is_delete` Integer
);
CREATE TABLE IF NOT EXISTS `tb_article`
(
`id` INTEGER PRIMARY KEY auto_increment,
`account_id` Integer,
`title` VARCHAR(100),
`content` text,
`is_delete` Integer
);