亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java emoji持久化mysql過(guò)程詳解

 更新時(shí)間:2019年07月27日 10:08:40   作者:小破孩123  
這篇文章主要介紹了Java emoji持久化mysql過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

前言

好久沒(méi)有更新博客了,今天和大家分享一個(gè)關(guān)于emoji表情持久化問(wèn)題,相信做web開(kāi)發(fā)的都遇到過(guò)這樣的問(wèn)題,因?yàn)槲覀冎續(xù)ysql的utf-8字符集保存不了保存不了表情字符,這是為什么呢?因?yàn)槠胀ǖ淖址蛘弑砬槎际钦嘉?個(gè)字節(jié),所以u(píng)tf8足夠用了,但是移動(dòng)端的表情符號(hào)占位是4個(gè)字節(jié),普通的utf8就不夠用了,為了應(yīng)對(duì)無(wú)線互聯(lián)網(wǎng)的機(jī)遇和挑戰(zhàn)、避免 emoji 表情符號(hào)帶來(lái)的問(wèn)題、涉及無(wú)線相關(guān)的 MySQL 數(shù)據(jù)庫(kù)建議都提前采用 utf8mb4 字符集,這必須要作為移動(dòng)互聯(lián)網(wǎng)行業(yè)的一個(gè)技術(shù)選型的要點(diǎn)。

好了看到上面的結(jié)果你是不是已經(jīng)去修改數(shù)據(jù)庫(kù)字符集了,如果你是個(gè)人項(xiàng)目或小項(xiàng)目上面的方法倒是一個(gè)解決方法,但是對(duì)于一個(gè)目前正在服務(wù)5000W用戶的系統(tǒng),上面的方式就有點(diǎn)不合適了,針對(duì)這種情況我這邊總結(jié)了三種處理方式,下面分享給大家:

1、既然是由于移動(dòng)端的表情符號(hào)占位是4個(gè)字節(jié),那我們直接把數(shù)據(jù)轉(zhuǎn)換后保存。

1.URLEncoder.encode(String s, String enc)

使用指定的編碼機(jī)制將字符串轉(zhuǎn)換為 application/x-www-form-urlencoded 格式

URLDecoder.decode(String s, String enc)

使用指定的編碼機(jī)制對(duì) application/x-www-form-urlencoded 字符串解碼。

2、方法一的處理太粗躁,有沒(méi)有更好的解決辦法呢?使用輕量級(jí)工具emoji-java處理emoji表情字符

github地址:https://github.com/vdurmont/emoji-java

具體使用方式,大家可以進(jìn)入git中自行查看。

3、有了上面兩種方式,你是不是已經(jīng)滿足了,最為自己最推崇的emoji處理方式,下面才是重點(diǎn),首先說(shuō)一下上面兩種方式存在的問(wèn)題:第一種方式,數(shù)據(jù)經(jīng)過(guò)轉(zhuǎn)換,相當(dāng)于加密,我們將無(wú)法直接查看到數(shù)據(jù)的原始內(nèi)容,由其對(duì)于需要進(jìn)行搜索的業(yè)務(wù)場(chǎng)景,將是一件很困難的事情;第二種方式,雖然避免了第一種方式存在的問(wèn)題,但是它基于表情的對(duì)照表進(jìn)行匹配轉(zhuǎn)換的,也就意味著對(duì)于一些新表情,無(wú)法做到轉(zhuǎn)換,這就會(huì)導(dǎo)致我們數(shù)據(jù)插入繼續(xù)出現(xiàn)問(wèn)題,這是它第一個(gè)問(wèn)題,第二點(diǎn)在于它將表情轉(zhuǎn)化為對(duì)應(yīng)的匹配規(guī)則,說(shuō)白一點(diǎn)就是轉(zhuǎn)化為英文描述,就是這個(gè)轉(zhuǎn)化,原本4個(gè)字節(jié)的表情,它可能給你轉(zhuǎn)成了10個(gè)字節(jié)甚至更多。好了說(shuō)了這么多下面我們看一下我最后的終極解決方法:

/**
 * @Author: gaoshang
 * @Description:
 * @Date: 2019/7/19
 */
public class EmojiUtil {

 /**
  * 將文本中的表情轉(zhuǎn)為十六進(jìn)制
  * <p>
  *
  * @param input
  * @return
  */
 public static String parseFromAliases(String input) {
  if (input == null) {
   return input;
  }

  return stringToUnicode(input);
 }

 /**
  * 將文本中的十六進(jìn)制轉(zhuǎn)為表情
  * <p>
  *
  * @param input
  * @return
  */
 public static String parseToAliases(String input) {
  if (input == null) {
   return input;
  }

  return unicodeToString(input);
 }

 /**
  * 字符串轉(zhuǎn)unicode
  *
  * @param str
  * @return
  */
 public static String stringToUnicode(String str) {
  StringBuilder sb = new StringBuilder();
  StringBuilder cacheSB = new StringBuilder();
  char[] c = str.toCharArray();
  for (int i = 0; i < c.length; i++) {
   if (!isEmojiCharacter(c[i])) {
    if (cacheSB.length() > 0) {
     sb.append("\\u").append(cacheSB);
     cacheSB.delete(0, cacheSB.length());
    }

    sb.append("\\u").append("[").append(Integer.toHexString(c[i])).append("]");
   } else {
    if (c[i] == '[' || c[i] == '\\' || c[i] == ']') {
     if (cacheSB.length() > 0) {
      sb.append("\\u").append(cacheSB);
      cacheSB.delete(0, cacheSB.length());
     }
     sb.append("\\u").append(c[i]);
    } else {
     cacheSB.append(c[i]);
    }
   }
  }
  if (cacheSB.length() > 0) {
   if (sb.length() > 0) {
    sb.append("\\u");
   }
   sb.append(cacheSB);
  }
  return sb.toString();
 }

 /**
  * unicode轉(zhuǎn)字符串
  *
  * @param unicode
  * @return
  */
 public static String unicodeToString(String unicode) {
  StringBuilder sb = new StringBuilder();
  String[] hex = unicode.split("\\\\u");
  for (int i = 0; i < hex.length; i++) {
   if (hex[i].indexOf("[") == 0 && hex[i].indexOf("]") == hex[i].length() - 1) {
    try {
     int index = Integer.parseInt(hex[i].substring(1, hex[i].length() - 1), 16);
     sb.append((char) index);
    } catch (NumberFormatException e) {
     sb.append(hex[i]);
    }
   } else {
    sb.append(hex[i]);
   }
  }
  return sb.toString();
 }

 private static boolean isEmojiCharacter(char codePoint) {
  return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA)
    || (codePoint == 0xD)
    || ((codePoint >= 0x20) && (codePoint <= 0xD7FF))
    || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
    || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
 }

}

好了就先這樣,歡迎大家提出不同的看法,已經(jīng)好的解決方案。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java多線程中的Executor詳解

    Java多線程中的Executor詳解

    這篇文章主要介紹了Java多線程中的Executor詳解,該接口提供了一種將任務(wù)提交與如何運(yùn)行每個(gè)任務(wù)的機(jī)制(包括線程使用、調(diào)度等細(xì)節(jié))解耦的方法,它通常使用預(yù)先創(chuàng)建線程而不是創(chuàng)建線程,需要的朋友可以參考下
    2023-12-12
  • JSON數(shù)據(jù)轉(zhuǎn)換成Java對(duì)象的方法

    JSON數(shù)據(jù)轉(zhuǎn)換成Java對(duì)象的方法

    就目前來(lái)講,將Java對(duì)象轉(zhuǎn)換成JSON對(duì)象還是相當(dāng)簡(jiǎn)單的,但是 將JSON對(duì)象轉(zhuǎn)換成Java對(duì)象,就相對(duì)比較復(fù)雜了些
    2014-03-03
  • 詳解SpringBoot配置連接池

    詳解SpringBoot配置連接池

    本篇文章主要詳解SpringBoot配置連接池,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04
  • Java中使用Preconditions來(lái)檢查傳入?yún)?shù)介紹

    Java中使用Preconditions來(lái)檢查傳入?yún)?shù)介紹

    這篇文章主要介紹了Java中使用Preconditions來(lái)檢查傳入?yún)?shù)介紹,本文只是作為一個(gè)簡(jiǎn)單的用法介紹,需要的朋友可以參考下
    2015-06-06
  • 深入淺析java中flyway使用簡(jiǎn)介

    深入淺析java中flyway使用簡(jiǎn)介

    Flyway是獨(dú)立于數(shù)據(jù)庫(kù)的應(yīng)用、管理并跟蹤數(shù)據(jù)庫(kù)變更的數(shù)據(jù)庫(kù)版本管理工具。這篇文章主要介紹了flyway使用簡(jiǎn)介,需要的朋友可以參考下
    2020-07-07
  • Nacos+Spring Cloud Gateway動(dòng)態(tài)路由配置實(shí)現(xiàn)步驟

    Nacos+Spring Cloud Gateway動(dòng)態(tài)路由配置實(shí)現(xiàn)步驟

    Nacos最近項(xiàng)目一直在使用,本文通過(guò)gateway、nacos-consumer、nacos-provider三個(gè)簡(jiǎn)單模塊來(lái)展示:Nacos下動(dòng)態(tài)路由配置,,感興趣的小伙伴們可以參考一下
    2021-08-08
  • java使用Rxtx實(shí)現(xiàn)串口通信調(diào)試工具

    java使用Rxtx實(shí)現(xiàn)串口通信調(diào)試工具

    這篇文章主要為大家詳細(xì)介紹了java使用Rxtx實(shí)現(xiàn)簡(jiǎn)單串口通信調(diào)試工具,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • Java判斷字符串是不是數(shù)字過(guò)程解析

    Java判斷字符串是不是數(shù)字過(guò)程解析

    這篇文章主要介紹了Java判斷字符串是不是數(shù)字過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 詳解Java中的mapstruct插件使用

    詳解Java中的mapstruct插件使用

    mapstruct 的插件是專門用來(lái)處理 domin 實(shí)體類與 model 類的屬性映射的,我們只需定義 mapper 接口,mapstruct 在編譯的時(shí)候就會(huì)自動(dòng)的幫我們實(shí)現(xiàn)這個(gè)映射接口,避免了麻煩復(fù)雜的映射實(shí)現(xiàn),對(duì)Java?mapstruct使用相關(guān)知識(shí)感興趣的朋友一起看看吧
    2022-04-04
  • 詳解java中jvm虛擬機(jī)棧的作用

    詳解java中jvm虛擬機(jī)棧的作用

    這篇文章主要介紹了jvm虛擬機(jī)棧的作用,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-08-08

最新評(píng)論