本文闡述了怎么使用DBMS存儲(chǔ)過程 闡述了使用存儲(chǔ)過程的基本的和高級(jí)特性 比如返回ResultSet 本文假設(shè)你對(duì)DBMS和JDBC已經(jīng)非常熟悉 也假設(shè)你能夠毫無障礙地閱讀其它語言寫成的代碼(即不是Java的語言) 但是 并不要求你有任何存儲(chǔ)過程的編程經(jīng)歷
創(chuàng)新互聯(lián)是一家專業(yè)的成都網(wǎng)站建設(shè)公司,我們專注成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、網(wǎng)絡(luò)營(yíng)銷、企業(yè)網(wǎng)站建設(shè),賣鏈接,廣告投放平臺(tái)為企業(yè)客戶提供一站式建站解決方案,能帶給客戶新的互聯(lián)網(wǎng)理念。從網(wǎng)站結(jié)構(gòu)的規(guī)劃UI設(shè)計(jì)到用戶體驗(yàn)提高,創(chuàng)新互聯(lián)力求做到盡善盡美。
存儲(chǔ)過程是指保存在數(shù)據(jù)豎拿庫(kù)并在數(shù)據(jù)庫(kù)端執(zhí)行的程序 你可以使用特殊的語法在Java類中調(diào)用存儲(chǔ)過程 在調(diào)用時(shí) 存儲(chǔ)過程的名稱及指定的參數(shù)通過JDBC連接發(fā)送給DBMS 執(zhí)行存儲(chǔ)過程并通過連接(如果有)返回結(jié)果
使用存儲(chǔ)過程擁有和使用基于EJB或CORBA這樣的應(yīng)用服務(wù)器一樣的好處 區(qū)別是存儲(chǔ)過程可以從很多流行的DBMS中免費(fèi)使用 而應(yīng)用服務(wù)器大都非常昂貴 這并不只是許可證費(fèi)用的問題 使用應(yīng)用服務(wù)器所需要花費(fèi)的管理 編寫代碼的費(fèi)用 以及客戶程序所增加的復(fù)雜性 都可以通過DBMS中的存儲(chǔ)過程所整個(gè)地替代
你可以使用Java Python Perl或C編寫存儲(chǔ)過程 但是通常使用你的DBMS所指定的特定語言 Oracle使用PL/SQL PostgreSQL使用pl/pgsql DB 使用Procedural SQL 這些語言都非常相似 在它們之間移植存儲(chǔ)過程并不比在Sun的EJB規(guī)范不同實(shí)現(xiàn)版本之間移植Session Bean困難 并且 存儲(chǔ)過程是為嵌入SQL所設(shè)計(jì) 這使得它們比Java或C等語言更加友好地方式表達(dá)數(shù)據(jù)庫(kù)的機(jī)制
因?yàn)榇鎯?chǔ)過程運(yùn)行在DBMS自身 這可以幫助減少應(yīng)用程序中的等待時(shí)間 不是在Java代碼中執(zhí)行 個(gè)或 個(gè)SQL語句 而只需要在服務(wù)器端執(zhí)行 個(gè)存儲(chǔ)過程 網(wǎng)絡(luò)上的數(shù)據(jù)往返次數(shù)的減少可以戲劇性地優(yōu)化性能
使用存儲(chǔ)過程
簡(jiǎn)單的老的JDBC通過CallableStatement類支持存儲(chǔ)過程的調(diào)用 該類實(shí)際上是PreparedStatement的一個(gè)子類 假設(shè)我們有一個(gè)poets數(shù)據(jù)庫(kù) 數(shù)據(jù)庫(kù)中有一個(gè)設(shè)置詩(shī)人逝世年齡的存儲(chǔ)過程 下面是對(duì)老酒鬼Dylan Thomas(old soak Dylan Thomas 不指定是否有關(guān)典故跡灶 文化 請(qǐng)批評(píng)指正 譯注)進(jìn)行調(diào)用的詳細(xì)代碼
try{ int age = ; String poetName = dylan thomas ; CallableStatement proc = connection prepareCall( { call set_death_age(? ?) } ); proc setString( poetName); proc setInt( age); cs execute();}catch (SQLException e){ // }
傳給prepareCall方法的字串是存儲(chǔ)過程調(diào)用的書寫規(guī)范 它指定了存儲(chǔ)過程的名稱 ?代表了你需要指定的參數(shù)
和JDBC集成是存儲(chǔ)過程的一個(gè)很大的便利 為了從應(yīng)用中調(diào)用存儲(chǔ)過程 不需要存根(stub)類或者配置文件 除了你的DBMS的JDBC驅(qū)動(dòng)程序外什么也不需要
當(dāng)這段代碼執(zhí)行時(shí) 數(shù)據(jù)庫(kù)的存儲(chǔ)過程就被調(diào)用 我們沒有去獲取結(jié)果 因?yàn)樵摯鎯?chǔ)過程并不返回結(jié)果 執(zhí)行成功或失敗將通過例外得知 失敗可能意味著調(diào)用存儲(chǔ)姿纖扮過程時(shí)的失?。ū热缣峁┑囊粋€(gè)參數(shù)的類型不正確) 或者一個(gè)應(yīng)用程序的失?。ū热鐠伋鲆粋€(gè)例外指示在poets數(shù)據(jù)庫(kù)中并不存在 Dylan Thomas )
結(jié)合SQL操作與存儲(chǔ)過程
映射Java對(duì)象到SQL表中的行相當(dāng)簡(jiǎn)單 但是通常需要執(zhí)行幾個(gè)SQL語句 可能是一個(gè)SELECT查找ID 然后一個(gè)INSERT插入指定ID的數(shù)據(jù) 在高度規(guī)格化(符合更高的范式 譯注)的數(shù)據(jù)庫(kù)模式中 可能需要多個(gè)表的更新 因此需要更多的語句 Java代碼會(huì)很快地膨脹 每一個(gè)語句的網(wǎng)絡(luò)開銷也迅速增加
將這些SQL語句轉(zhuǎn)移到一個(gè)存儲(chǔ)過程中將大大簡(jiǎn)化代碼 僅涉及一次網(wǎng)絡(luò)調(diào)用 所有關(guān)聯(lián)的SQL操作都可以在數(shù)據(jù)庫(kù)內(nèi)部發(fā)生 并且 存儲(chǔ)過程語言 例如PL/SQL 允許使用SQL語法 這比Java代碼更加自然 下面是我們?cè)缙诘拇鎯?chǔ)過程 使用Oracle的PL/SQL語言編寫
create procedure set_death_age(poet VARCHAR poet_age NUMBER)poet_id NUMBER;beginSELECT id INTO poet_id FROM poets WHERE name = poet;INSERT INTO deaths (mort_id age) VALUES (poet_id poet_age);end set_death_age;
很獨(dú)特?不 我打賭你一定期待看到一個(gè)poets表上的UPDATE 這也暗示了使用存儲(chǔ)過程實(shí)現(xiàn)是多么容易的一件事情 set_death_age幾乎可以肯定是一個(gè)很爛的實(shí)現(xiàn) 我們應(yīng)該在poets表中添加一列來存儲(chǔ)逝世年齡 Java代碼中并不關(guān)心數(shù)據(jù)庫(kù)模式是怎么實(shí)現(xiàn)的 因?yàn)樗鼉H調(diào)用存儲(chǔ)過程 我們以后可以改變數(shù)據(jù)庫(kù)模式以提高性能 但是我們不必修改我們代碼
下面是調(diào)用上面存儲(chǔ)過程的Java代碼
public static void setDeathAge(Poet dyingBard int age)throws SQLException{ Connection con = null; CallableStatement proc = null;
try {con = connectionPool getConnection();proc = con prepareCall( { call set_death_age(? ?) } );proc setString( dyingBard getName());proc setInt( age);proc execute(); } finally {try{ proc close();}catch (SQLException e) {}con close(); }}
為了確??删S護(hù)性 建議使用像這兒這樣的static方法 這也使得調(diào)用存儲(chǔ)過程的代碼集中在一個(gè)簡(jiǎn)單的模版代碼中 如果你用到許多存儲(chǔ)過程 就會(huì)發(fā)現(xiàn)僅需要拷貝 粘貼就可以創(chuàng)建新的方法 因?yàn)榇a的模版化 甚至也可以通過腳本自動(dòng)生產(chǎn)調(diào)用存儲(chǔ)過程的代碼
Functions
存儲(chǔ)過程可以有返回值 所以CallableStatement類有類似getResultSet這樣的方法來獲取返回值 當(dāng)存儲(chǔ)過程返回一個(gè)值時(shí) 你必須使用registerOutParameter方法告訴JDBC驅(qū)動(dòng)器該值的SQL類型是什么 你也必須調(diào)整存儲(chǔ)過程調(diào)用來指示該過程返回一個(gè)值
下面接著上面的例子 這次我們查詢Dylan Thomas逝世時(shí)的年齡 這次的存儲(chǔ)過程使用PostgreSQL的pl/pgsql
create function snuffed_it_when (VARCHAR) returns integer declarepoet_id NUMBER;poet_age NUMBER;begin first get the id associated with the poet SELECT id INTO poet_id FROM poets WHERE name = $ ; get and return the age SELECT age INTO poet_age FROM deaths WHERE mort_id = poet_id;return age;end; language pl/pgsql ;
另外 注意pl/pgsql參數(shù)名通過Unix和DOS腳本的$n語法引用 同時(shí) 也注意嵌入的注釋 這是和Java代碼相比的另一個(gè)優(yōu)越性 在Java中寫這樣的注釋當(dāng)然是可以的 但是看起來很凌亂 并且和SQL語句脫節(jié) 必須嵌入到Java String中
下面是調(diào)用這個(gè)存儲(chǔ)過程的Java代碼
connection setAutoCommit(false);CallableStatement proc =connection prepareCall( { ? = call snuffed_it_when(?) } );proc registerOutParameter( Types INTEGER);proc setString( poetName);cs execute();int age = proc getInt( );
如果指定了錯(cuò)誤的返回值類型會(huì)怎樣?那么 當(dāng)調(diào)用存儲(chǔ)過程時(shí)將拋出一個(gè)RuntimeException 正如你在ResultSet操作中使用了一個(gè)錯(cuò)誤的類型所碰到的一樣
復(fù)雜的返回值
關(guān)于存儲(chǔ)過程的知識(shí) 很多人好像就熟悉我們所討論的這些 如果這是存儲(chǔ)過程的全部功能 那么存儲(chǔ)過程就不是其它遠(yuǎn)程執(zhí)行機(jī)制的替換方案了 存儲(chǔ)過程的功能比這強(qiáng)大得多
當(dāng)你執(zhí)行一個(gè)SQL查詢時(shí) DBMS創(chuàng)建一個(gè)叫做cursor(游標(biāo))的數(shù)據(jù)庫(kù)對(duì)象 用于在返回結(jié)果中迭代每一行 ResultSet是當(dāng)前時(shí)間點(diǎn)的游標(biāo)的一個(gè)表示 這就是為什么沒有緩存或者特定數(shù)據(jù)庫(kù)的支持 你只能在ResultSet中向前移動(dòng)
某些DBMS允許從存儲(chǔ)過程中返回游標(biāo)的一個(gè)引用 JDBC并不支持這個(gè)功能 但是Oracle PostgreSQL和DB 的JDBC驅(qū)動(dòng)器都支持在ResultSet上打開到游標(biāo)的指針(pointer)
設(shè)想列出所有沒有活到退休年齡的詩(shī)人 下面是完成這個(gè)功能的存儲(chǔ)過程 返回一個(gè)打開的游標(biāo) 同樣也使用PostgreSQL的pl/pgsql語言
create procedure list_early_deaths () return refcursor as declaretoesup refcursor;beginopen toesup forSELECT poets name deaths ageFROM poets deaths all entries in deaths are for poets but the table might bee generic WHERE poets id = deaths mort_idAND deaths age ;return toesup;end; language plpgsql ;
下面是調(diào)用該存儲(chǔ)過程的Java方法 將結(jié)果輸出到PrintWriter
PrintWriter:
static void sendEarlyDeaths(PrintWriter out){ Connection con = null; CallableStatement toesUp = null; try {con = ConnectionPool getConnection();
// PostgreSQL needs a transaction to do this con setAutoCommit(false);
// Setup the call CallableStatement toesUp= connection prepareCall( { ? = call list_early_deaths () } );toesUp registerOutParameter( Types OTHER);getResults execute();
ResultSet rs = (ResultSet) getResults getObject( );while (rs next()){ String name = rs getString( ); int age = rs getInt( ); out println(name + was + age + years old );}rs close(); } catch (SQLException e) {// We should protect these calls toesUp close();con close(); }}
因?yàn)镴DBC并不直接支持從存儲(chǔ)過程中返回游標(biāo) 我們使用Types OTHER來指示存儲(chǔ)過程的返回類型 然后調(diào)用getObject()方法并對(duì)返回值進(jìn)行強(qiáng)制類型轉(zhuǎn)換
這個(gè)調(diào)用存儲(chǔ)過程的Java方法是mapping的一個(gè)好例子 Mapping是對(duì)一個(gè)集上的操作進(jìn)行抽象的方法 不是在這個(gè)過程上返回一個(gè)集 我們可以把操作傳送進(jìn)去執(zhí)行 本例中 操作就是把ResultSet打印到一個(gè)輸出流 這是一個(gè)值得舉例的很常用的例子 下面是調(diào)用同一個(gè)存儲(chǔ)過程的另外一個(gè)方法實(shí)現(xiàn)
public class ProcessPoetDeaths{ public abstract void sendDeath(String name int age);}
static void mapEarlyDeaths(ProcessPoetDeaths mapper){ Connection con = null; CallableStatement toesUp = null; try {con = ConnectionPool getConnection();con setAutoCommit(false);
CallableStatement toesUp= connection prepareCall( { ? = call list_early_deaths () } );toesUp registerOutParameter( Types OTHER);getResults execute();
ResultSet rs = (ResultSet) getResults getObject( );while (rs next()){ String name = rs getString( ); int age = rs getInt( ); mapper sendDeath(name age);}rs close(); } catch (SQLException e) {// We should protect these calls toesUp close();con close(); }}
這允許在ResultSet數(shù)據(jù)上執(zhí)行任意的處理 而不需要改變或者復(fù)制獲取ResultSet的方法
static void sendEarlyDeaths(final PrintWriter out){ ProcessPoetDeaths myMapper = new ProcessPoetDeaths() {public void sendDeath(String name int age){ out println(name + was + age + years old );} }; mapEarlyDeaths(myMapper);}
這個(gè)方法使用ProcessPoetDeaths的一個(gè)匿名實(shí)例調(diào)用mapEarlyDeaths 該實(shí)例擁有sendDeath方法的一個(gè)實(shí)現(xiàn) 和我們上面的例子一樣的方式把結(jié)果寫入到輸出流 當(dāng)然 這個(gè)技巧并不是存儲(chǔ)過程特有的 但是和存儲(chǔ)過程中返回的ResultSet結(jié)合使用 是一個(gè)非常強(qiáng)大的工具
結(jié)論
存儲(chǔ)過程可以幫助你在代碼中分離邏輯 這基本上總是有益的 這個(gè)分離的好處有
快速創(chuàng)建應(yīng)用 使用和應(yīng)用一起改變和改善的數(shù)據(jù)庫(kù)模式
數(shù)據(jù)庫(kù)模式可以在以后改變而不影響Java對(duì)象 當(dāng)我們完成應(yīng)用后 可以重新設(shè)計(jì)更好的模式
存儲(chǔ)過程通過更好的SQL嵌入使得復(fù)雜的SQL更容易理解
編寫存儲(chǔ)過程比在Java中編寫嵌入的SQL擁有更好的工具——大部分編輯器都提供語法高亮!
存儲(chǔ)過程可以在任何SQL命令行中測(cè)試 這使得調(diào)試更加容易
并不是所有的數(shù)據(jù)庫(kù)都支持存儲(chǔ)過程 但是存在許多很棒的實(shí)現(xiàn) 包括免費(fèi)/開源的和非免費(fèi)的 所以移植并不是一個(gè)問題 Oracle PostgreSQL和DB 都有類似的存儲(chǔ)過程語言 并且有在線的社區(qū)很好地支持
存儲(chǔ)過程工具很多 有像TOAD或TORA這樣的編輯器 調(diào)試器和IDE 提供了編寫 維護(hù)PL/SQL或pl/pgsql的強(qiáng)大的環(huán)境
lishixinzhi/Article/program/Java/hx/201311/25906
您可以按照以下步驟將 Eclipse 中的 Java 代碼存儲(chǔ)到 U 盤中:
打開 Eclipse 編輯器,選擇您要保存的 Java 項(xiàng)目或文件。
選擇 "液咐辯文件" 菜單,然后選擇 "導(dǎo)出"。
在彈出窗口中,選擇 "一般" 文件夾,然后選擇 "文件系統(tǒng)"。
在 "簡(jiǎn)改導(dǎo)出" 窗口中,選擇要導(dǎo)出的項(xiàng)目或文件,然后選擇您的 U 盤作為導(dǎo)出目錄。
點(diǎn)擊 "完成" 按鈕,Eclipse 將會(huì)把您的 Java 代碼導(dǎo)出到您的 U 盤中。
請(qǐng)注意,如果您在導(dǎo)出項(xiàng)目鬧缺時(shí)選擇了 "項(xiàng)目存檔文件",那么您的項(xiàng)目將以 .zip 文件的形式導(dǎo)出到您的 U 盤中,您可以將其解壓縮后在其他計(jì)算機(jī)上使用。
在接收富文純稿蠢本時(shí),數(shù)據(jù)庫(kù)接收含有圖片內(nèi)容,圖片會(huì)自動(dòng)轉(zhuǎn)換為Base64編碼保存到數(shù)據(jù)庫(kù),導(dǎo)數(shù)據(jù)庫(kù)性能降低。
解決:在接收富文本內(nèi)容時(shí),將接收到的圖片轉(zhuǎn)換為文件上傳到Minio(Minio具體使用可參考文檔),然后將base64編碼替換為圖片地址保存敬晌
用到的工具類
使用正則表達(dá)式提取接收內(nèi)容的Base64編碼工具類
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ImgBaseUtil {
public static ListString getImgStr(String htmlStr) {
ListString list = new ArrayList();
String img = "";
Pattern p_image;
Matcher m_image;
// String regEx_img = "img.*src=(.*?)[^]*?"; //圖片鏈接地址
String regEx_img = "img.*src\\s*=\\s*(.*?)[^]*?";
p_image = Pattern點(diǎn)抗 pile(regEx_img, Pattern.CASE_INSENSITIVE);
m_image = p_image.matcher(htmlStr);
while (m_image.find()) {
// 得做陪到img /數(shù)據(jù)
img = m_image.group();
// 匹配img中的src數(shù)據(jù)
Matcher m = Pattern點(diǎn)抗 pile("src\\s*=\\s*\"?(.*?)(\"||\\s+)").matcher(img);
while (m.find()) {
list.add(m.group(1));
}
}
return list;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
將Base64編碼轉(zhuǎn)換為文件流的工具類
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import java.io.*;
public class BASE64DecodedMultipartFile implements MultipartFile {
private final byte[] imgContent;
private final String header;
public BASE64DecodedMultipartFile(byte[] imgContent, String header) {
this.imgContent = imgContent;
this.header = header.split(";")[0];
}
@Override
public String getName() {
return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1];
}
@Override
public String getOriginalFilename() {
return System.currentTimeMillis() + (int) Math.random() * 10000 + "." + header.split("/")[1];
}
@Override
public String getContentType() {
return header.split(":")[1];
}
@Override
public boolean isEmpty() {
return imgContent == null || imgContent.length == 0;
}
@Override
public long getSize() {
return imgContent.length;
}
@Override
public byte[] getBytes() throws IOException {
return imgContent;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(imgContent);
}
@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
new FileOutputStream(dest).write(imgContent);
}
public static MultipartFile base64ToMultipart(String base64) {
try {
String[] baseStrs = base64.split(",");
BASE64Decoder decoder = new BASE64Decoder();
byte[] b = new byte[0];
b = decoder.decodeBuffer(baseStrs[1]);
for (int i = 0; i b.length; ++i) {
if (b[i] 0) {
b[i] += 256;
}
}
return new BASE64DecodedMultipartFile(b, baseStrs[0]);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
內(nèi)容接收并完成處理工具類
public class RichTextUtil {
/**
*
* @param text 富文本內(nèi)容
* @return 返回處理圖片后的數(shù)據(jù)
*/
public String richText(String text,MinioUtils minioUtils,MinioConfig minioConfig){
String s=new String(text);
String result=null;//返回結(jié)果
ListString imgStr = ImgBaseUtil.getImgStr(s); //每組base64編碼圖片
if (imgStr.isEmpty()){
return text;
}
for (String s1:imgStr){ //每個(gè)base64轉(zhuǎn)換并上傳
String s2= UUID.randomUUID().toString().replaceAll("-","")+".jpg"; //新的文件鏈接
//上傳
MultipartFile multipartFile = BASE64DecodedMultipartFile.base64ToMultipart(s1);
assert multipartFile != null;
minioUtils.putObject1(multipartFile,minioConfig.getBucketName(),s2);
String foreverUrl=minioConfig.getEndpoint()+":"+minioConfig.getPort()+"/"+minioConfig.getBucketName()+"/"+s2;//永久鏈接
if (Objects.isNull(result)){
result=s.replace(s1,foreverUrl); //第一次替換
}
result=result.replace(s1,foreverUrl); //前邊替換過,繼續(xù)替換
}
return result;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
配合Minio工具類使用
@GetMapping("/tss")
public String dmo(@RequestBody Entity entity) throws IOException {
String s=entity.getContent();//接收到的內(nèi)容
RichTextUtil richTextUtil = new RichTextUtil();
String s1 = richTextUtil.richText(s,minioUtils,minioConfig);
entity.setContent(s1);//最后將轉(zhuǎn)換過的內(nèi)容替換就行
//數(shù)據(jù)庫(kù)保存一下實(shí)體類內(nèi)容
return entity;
}
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
Minio使用可查詢相關(guān)資料或了解本博客SpringBoot對(duì)Minio的簡(jiǎn)單使用鏈接:
文章知識(shí)點(diǎn)與官方知識(shí)檔案匹配
Java技能樹使用JDBC操作數(shù)據(jù)庫(kù)數(shù)據(jù)庫(kù)操作
95211 人正在系統(tǒng)學(xué)習(xí)中
打開CSDN APP,看更多技術(shù)內(nèi)容
...如D:\tmp)并回顯_靜靜看大海的博客_java 富文本保存...
1、項(xiàng)目需求: 使用百度富文本編輯器實(shí)現(xiàn)“重要節(jié)假日高速出行指南內(nèi)容”編輯,功能涉及圖片、視頻上傳。 2、存在問題 百度富文本編輯器默認(rèn)將圖片、視頻上傳至項(xiàng)目里,如果使用Tomcat作為服務(wù)器的時(shí)候,如果不配置圖片保存路徑,將圖片保存在項(xiàng)...
繼續(xù)訪問
java 保存富文本_如何從Web應(yīng)用程序保存富文本并將其顯示在富文本框中...
我建議彈出打開的寫字板(開始 - 運(yùn)行... - wordpad),并亂用不同的字體樣式等 . 然后將其保存為某處的RTF文檔 . 在您選擇的純文本編輯器中打開該文檔(我使用Notepad++),這將幫助您更輕松地找出RTF . ...
繼續(xù)訪問
Bootstrap富文本組件wysiwyg數(shù)據(jù)保存到mysql的方法
Bootstrap提供了一個(gè)叫wysiwyg的富文本組件,用來顯示和編輯富文本數(shù)據(jù),但如何將編輯后的數(shù)據(jù)保存到MySQL數(shù)據(jù)庫(kù),卻不得而知。另外,如何將mysql數(shù)據(jù)庫(kù)中的數(shù)據(jù)顯示到wysiwyg也不得而知,對(duì)于這兩個(gè)問題,讓我來告訴你解決方案! 一、效果展示 首先,我們先來看看效果如何: 富文本中有一張圖片,還有一個(gè)數(shù)字列表 我們可以看到編輯后的數(shù)據(jù)保存成功,以及保存后對(duì)應(yīng)的展示。 二、富文本 度娘對(duì)于富文本的解釋如下: 富文本格式(Rich Text Format, 一般簡(jiǎn)稱為RTF)是由微軟公司開發(fā)的跨平臺(tái)文檔格式。大多數(shù)的文字處理軟件都能讀取和保存RTF文檔。RTF是Rich
富文本保存到數(shù)據(jù)庫(kù)
標(biāo)題 富文本保存到數(shù)據(jù)庫(kù) -idea String html = "p wx:nodeid='135'1.地方/pp wx:nodeid='156'2.第三方"; // 前端傳過來的富文本內(nèi)容 String temp = HtmlUtils.htmlEscapeHex(html); System.err.println("存數(shù)據(jù)庫(kù)=\r\n" + temp); resume.setExperience(temp); Strin
繼續(xù)訪問
java中使用poi如何導(dǎo)富文本,Apache的POI - 讀取和存儲(chǔ)DB富文本內(nèi)容
Using your favorite Java-to-database framework (JDBC, Hibernate, etc.), store the String value into contents in rich_text_string, and the associated FormattingRun object data into rt_formatting_runs. ...
繼續(xù)訪問
富文本保存到數(shù)據(jù)庫(kù)_黑潮之羽的博客_富文本保存到數(shù)據(jù)庫(kù)
富文本保存到數(shù)據(jù)庫(kù) String html = "1.地方2.第三方"; // 前端傳過來的富文本內(nèi)容 String temp = HtmlUtils.htmlEscapeHex(html); System.err.println("存數(shù)據(jù)庫(kù)=\r\n" + temp); resume.setExperience(temp); String returnHt...
繼續(xù)訪問
java富文本
【代碼】java富文本。
繼續(xù)訪問
富文本編輯器存MYSQL數(shù)據(jù)庫(kù)
一、MYSQL數(shù)據(jù)庫(kù)對(duì)應(yīng)數(shù)據(jù)類型選用 longtest類型,對(duì)應(yīng)java和mybatis框架類型為string。 二、富文本編輯器有特殊字符,存數(shù)據(jù)庫(kù)會(huì)轉(zhuǎn)義 在java代碼中,添加org.springframework.web.util.HtmlUtils 包下的 HtmlUtils.htmlEscapeHex(String);把html的特殊字符轉(zhuǎn)換成符合Intel HEX文件的字符串 HtmlUtils.htmlUnescape(...
繼續(xù)訪問
Java開發(fā)之富文本編輯器TinyMCE
一、題外話 最近負(fù)責(zé)了一個(gè)cms網(wǎng)站的運(yùn)維,里面存在很多和編輯器有關(guān)的問題,比如編輯一些新聞博客,論文模塊。系統(tǒng)采用的是FCKEditor,自我感覺不是很好,如下圖 特別是在用戶想插入一個(gè)圖片的話,就很麻煩,所有用戶共享一個(gè)文件目錄,這樣就不好了,于是便想到了TinyMCE編輯器,博客園默認(rèn)的也是這個(gè)編輯器,接下 來,我們開始吧 二、TinyMCE編輯器集成步驟 2.1:下載相關(guān)文件...
繼續(xù)訪問
Java實(shí)現(xiàn)多文件上傳下載,kindeditor富文本保存為word文件,文件列表分頁(yè)顯示
介紹 SpringBoot+Thymeleaf+Mybaits項(xiàng)目部分功能, 實(shí)現(xiàn)文件的多文件上傳和下載,以及將kindeditor富文本內(nèi)容保存為.doc文件 文件上傳/創(chuàng)建后以列表形式顯示,并且可以分頁(yè)顯示 提示 簡(jiǎn)單記錄,僅供參考,代碼并不完整,需要簡(jiǎn)單修改后才能使用(沒提供.css文件,需要?jiǎng)h除html中的class;另外部分變量通過session獲取,可以適當(dāng)修改) 關(guān)鍵代碼 html: !DOCTYPE html html lang="en" xmlns:th="http
繼續(xù)訪問
JAVA:富文本框截圖,將圖片的Base64轉(zhuǎn)File文件進(jìn)行保存
代碼】JAVA:富文本框截圖,將圖片的Base64轉(zhuǎn)File文件進(jìn)行保存。
繼續(xù)訪問
java 富文本框內(nèi)容 保存與恢復(fù),將富文本框內(nèi)容直接保存到文件中。(不使用savefile對(duì)話框)...
how can I save the contents of a rich text box without needing to open the save file dialog.i think its something like:richTextBox1.SaveFile(@"\Documents\save_file_here.rtf");but it cant find the file...
繼續(xù)訪問
java富文本編輯數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)簡(jiǎn)單實(shí)現(xiàn)
java富文本編輯數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)簡(jiǎn)單實(shí)現(xiàn)-小白日記 前端代碼 link rel="stylesheet" href="../themes/default/default.css" / script charset="utf-8" src="../kindeditor-all.js"/script script charset="utf-8" src="../lang/zh-CN.js"/script ...
繼續(xù)訪問
Java解析富文本
富文本Java解析
繼續(xù)訪問
java 關(guān)于處理富文本保存,查詢,更新過慢問題
java 關(guān)于處理富文本保存,查詢,更新過慢問題 首先了解為什么富文本保存,查詢,更新會(huì)過慢 數(shù)據(jù)庫(kù)富文本字段類型為:longtext 類型 假如富文本里面只保存文字的話,保存,查詢,更新都會(huì)很快 注意:只有富文本里面插入圖片或者視頻的時(shí)候才會(huì)變的很慢–因?yàn)榍岸烁晃谋窘M件會(huì)把圖片或視頻直接轉(zhuǎn)化為base64編碼,這樣保存量數(shù)據(jù)就會(huì)變的極大! 解決方案: 后端提供一個(gè)文件上傳的接口,前端富文本要插入圖片的時(shí)候直接調(diào)上傳接口,先把圖片或者視頻上傳到服務(wù)器,返回圖片的url,前端把url直接放到 im
繼續(xù)訪問
記一次富文本編輯器保存內(nèi)容到數(shù)據(jù)庫(kù)轉(zhuǎn)換內(nèi)容的問題
項(xiàng)目上要用到富文本編輯器,保存到數(shù)據(jù)庫(kù)的時(shí)候它會(huì)自動(dòng)轉(zhuǎn)換成非HTML的格式,再次從數(shù)據(jù)庫(kù)讀取到頁(yè)面后格式全亂了。如圖:如果我們要按一開始我們輸入的格式正常顯示需要對(duì)保存的內(nèi)容進(jìn)行轉(zhuǎn)換,轉(zhuǎn)換成正常的HTML的格式方法是需要用到commons-lang3-3.3.2.jar 這個(gè)jar包下面的一個(gè)工具類String qualiHtml=StringEscapeUtils.unescapeHtml4(r...
繼續(xù)訪問
java 富文本 word_Java導(dǎo)出富文本到word
源碼地址:背景最近用java開發(fā)一個(gè)中車項(xiàng)目管理系統(tǒng),里面有一個(gè)維修單word導(dǎo)出功能??捎梅桨冈诰W(wǎng)上查找資料,總結(jié)出兩種比較可行的方案。(1) 制作word模板,導(dǎo)出成mht文件(單頁(yè)面網(wǎng)頁(yè)格式),然后往模板里渲染數(shù)據(jù),最終生成word文檔。(2) 制作word模板,導(dǎo)出成xml文件,然后往模板里渲染數(shù)據(jù),最終生成word文檔。兩種都是采用模板的思想,比用poi去組織word格式簡(jiǎn)單的很多很多。...
繼續(xù)訪問
191210P4 Java富文本編輯之圖片鏈接本地化
Java富文本編輯之圖片鏈接本地化 作者:邵發(fā) 官網(wǎng): 本文介紹在圖文混編項(xiàng)目中(博客、新聞等),如何將富文本中的圖片外鏈轉(zhuǎn)為本地鏈接的問題。本文是Java學(xué)習(xí)指南系列教程的官方配套文檔,項(xiàng)目源碼在本文末尾說明。 所謂富文本Rich Text,就是以HTML形式表示的文本。在前端通常由富文本編輯器得到,比如UEditor,KindEditor,w...
繼續(xù)訪問
java 富文本框內(nèi)容 保存與恢復(fù)_使用富文本編輯器保存數(shù)據(jù)后進(jìn)行fastjson格式轉(zhuǎn)換異常及序列化處理...
最近線上的ELK日志監(jiān)控爆出幾個(gè)異常問題,jsonException的解析問題。如下:message: 2019-04-10 23:37:43,952 ERROR aop.AspectAdvice eid=410724004 not match : - ,com.alibaba.fastjson.JSONException: not match : - , atcom.alibaba.fastjs...
繼續(xù)訪問
富文本編輯器內(nèi)容存儲(chǔ)至Mysql
文章目錄概述獲取富文本編輯器內(nèi)容后端數(shù)據(jù)處理 概述 在所有的編輯器中,大概最受歡迎的就是富文本編輯器和MarkDown編輯器了,無論哪一種編輯器,我們需要知道的是,發(fā)給后端的內(nèi)容是帶著html標(biāo)簽的字符串,而我們需要把這些字符串存儲(chǔ)到數(shù)據(jù)庫(kù)中,其實(shí)原理非常簡(jiǎn)單,為了便于理解,我們首先創(chuàng)建一張表: CREATE TABLE `tb_title` ( `title_id` int(11) NOT NULL COMMENT '文章Id', `sort_id` int(11) DEFAULT NULL CO
繼續(xù)訪問
富文本數(shù)據(jù)保存
原文: Bootstrap提供了一個(gè)叫wysiwyg的富文本組件,用來顯示和編輯富文本數(shù)據(jù),但如何將編輯后的數(shù)據(jù)保存到mysql數(shù)據(jù)庫(kù),卻不得而知。另外,如何將mysql數(shù)據(jù)庫(kù)中的數(shù)據(jù)顯示到wysiwyg也不得而知,對(duì)于這兩個(gè)問題,讓我來告訴你解決方案! 一、效果展示 首先,我們先來看...
繼續(xù)訪問
最新發(fā)布 java 將富文本轉(zhuǎn)化為word,保留原本格式
通過java,將富文本轉(zhuǎn)化為word
繼續(xù)訪問
熱門推薦 Bootstrap wysiwyg,將富文本數(shù)據(jù)保存到mysql
Bootstrap提供了一個(gè)叫[wysiwyg]()的富文本組件,用來顯示和編輯富文本數(shù)據(jù),但如何將編輯后的數(shù)據(jù)保存到mysql數(shù)據(jù)庫(kù),卻不得而知
繼續(xù)訪問
java富文本框信息如何保存
java
開發(fā)語言
寫評(píng)論
評(píng)論
10
3
踩
分享
網(wǎng)頁(yè)題目:java代碼存儲(chǔ)數(shù)據(jù) java寫好的代碼怎么保存
文章網(wǎng)址:http://m.newbst.com/article30/ddpisso.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動(dòng)網(wǎng)站建設(shè)、網(wǎng)站營(yíng)銷、虛擬主機(jī)、網(wǎng)站策劃、ChatGPT、網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)