版本号: 4.1.1
报错:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1
经过万能的排除法后,发现当insert操作时,属性里包含emoji的话会报错,然后进而影响之后的所有update操作也会跟着报错
但是如果没有insert操作的话,直接update操作是不会报错的
目前社区已经有人提bug了,下一版应该会修复这个问题
目前有几种解决方案的思路
优点: 不用自己写代码
缺点:需要等
优点: 简单暴力且不用对历史数据进行处理
缺点: 无法存入emoji表情,需要emoji-java的jar包
com.vdurmont
emoji-java
4.0.0
优点: 能保存emoji表情
缺点: 所有出库的地方都需要进行emoji转码,涉及面比较广,如果数据库本身就使用utf8mb4的话,这样处理就会有点多此一举,因为utf8mb4本身就支持emoji表情,那出库的地方就肯定需要对字符串进行emoji转码,不然就得对历史数据进行处理,才能去掉转码代码块,工作量也挺大的
优点: 冇
缺点: 要写代码,到时候还要删代码,同样需要emoji-java包,两次数据库操作
我这边的对象都继承自MybatisPlus的Model对象,所以可以直接用Model的持久化方法 -> updateById()
核心注解:
@Async: 异步注解,需要@EnableAsync支持
@Transactional: spring事务注解
@EventListener: 事件监听注解
@TransactionalEventListener: 事务事件监听注解
Demo:
import com.baomidou.mybatisplus.extension.activerecord.Model;
import org.springframework.context.ApplicationEvent;
/**
* 事件监听对象
*/
public class EmojiEvent extends ApplicationEvent {
private T source;
public EmojiEvent(T source) {
super(source);
this.source = source;
}
@Override
public T getSource() {
return source;
}
}
import com.baomidou.mybatisplus.extension.activerecord.Model;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 监听
*/
@Component
public class EmojiListen {
@Async("emojiPool") // 设置线程池
@Order
@EventListener(EmojiEvent.class) // 监听事件对象
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) // 监听事务提交后执行
public void run(EmojiEvent emojiEvent) {
Model model = emojiEvent.getSource();
model.updateById(); // Pojo对象继承自MybatisPlus的Model对象,所以可以使用Model.updateById();
}
/**
* 线程池
*/
@Bean
public Executor emojiPool() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(200);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("emojiExecutor-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}
@Service
public class test() {
@Autoware
private ApplicationEventPublisher publisher;
@Transactional(rollbackFor = Throwable.class)
public void save() {
String emoji = ""; // emoji苹果表情
// 伪代码
Pojo pojo = new Pojo();
pojo.setEmoji(EmojiUtil.removeAllEmojis(emoji)); // 先去掉emoji表情
pojo.insert(); // 执行插入
// 回写emoji表情并推入事件监听
pojo.setEmoji(emoji);
publisher.publishEvent(new EmojiEvent<>(pojo));
}
}
之后它就会在事务提交后进行修改持久化操作
如果帮到你,请点个赞吧 O(∩_∩)O~