Total Pageviews

2019/01/02

[閱讀筆記] Value Investing: From Graham to Buffett and Beyond (4/7)


  1. 計算 margin of safety (安全邊際) 的公式
Margin of safety = PV / EPV
安全邊際 = Present Value (現價) / Earning Power Value
EPV = Capital * (ROC / R)
EPV = 資金 * ( 資金報酬率 / 資金成本) = 資金 * (Return on Capital / Cost of Capital)
PV = Capital * 1 / (R - G)
PV = 資金 * 1 / (資金成本 - 成長率)

  1. 在競爭劣勢 (competitive disadvantage) 的情況下,成長會損壞你的價值;在沒有競爭優勢、大家都公平競爭的環境 (level playing field) 的成長,也無法創造太多價值
  2. 差異化投資 (diversification) 的主要任務是找出資產間沒有強烈關連性的標的,甚至是負相關的最好。投資組合包含雨傘製造商與防曬乳製造商就是這樣的觀念。但是,這就是最難的部份,如何預測資產間的關聯性。
  3. 在棒球場中,三好球就會被三振出局;但是在投資中,你不會因為站著不揮就被三振
  4. Canary(金絲雀)對瓦斯十分敏感,17世紀時,英國人發現在煤礦中養金絲雀可預測有毒氣體的信息,所以將金絲雀放到礦井裡檢測礦井裡的空氣質量,只要牠會焦躁不安,甚至金絲雀死了,表示礦井裡的空氣已達令人中毒的水平,因此,以前礦工們都會在礦坑裡放金絲雀,當作危險信號的先知者、一個預警的工具。
  5. 保持一定的現金水平 (holding cash) 是 value investors 的最基本的標準策略,如同礦坑禮的金絲雀,當接收到事情不妙的信號時,擁有足夠的資金入場、撿拾便宜貨
  6. 若你沒有足夠的資訊或知識,購買 broad-based index fund 會是你最好的選擇
  7. 直接且主動的投資是個危險遊戲,不是隨便一個在家,上網查查資料就可以當贏家的遊戲。
  8. 若你在 poker game 過了 30 分鐘還不知道誰是笨蛋,那你就可以非常確定你就是那個笨蛋
  9. 股本報酬率(又稱股權收益率、股本收益率或股東報酬率,英語:Return On Equity,縮寫:ROE),是衡量相對於股東權益的投資報酬之指標,反映公司利用資產淨值產生純利的能力。公司通常把盈利再投資以賺取更大報酬,ROE正反映了公司這方面的能力,計算辦法是把淨收益(稅後淨利扣除優先股股息和特殊溢利)後,除以股東權益。
ROE = 淨收益 / 股東權益
※ 淨收益 = 稅後淨利 - (優先股的股息 + 特殊收益)

  1. 公司的股權收益 (ROE) 高不代表盈利能力強。部分行業由於不需要太多資產投入,所以通常都有較高ROE,例如諮詢公司。有些行業需要投入大量基礎建築才能產生盈利,例如煉油廠。所以,不能單以ROE判定公司的盈利能力。一般而言,資本密集行業的進入門檻較高,競爭較少,相反高ROE但低資產的行業則較易進入,面對較大競爭。所以ROE應用作比較相同行業。
  2. Buffett 對好的的投資企業 (good businesses) 的標準有:
    1. 擁有強大的產品
    2. 高於業界平均的股權收益 (ROE, Return On Equity)
    3. 相對較小需求的資本投資 (capital investment)
    4. 手中現金持有水位
  3. 巴菲特的法則是,「不要輕易揮棒,要揮棒也不要打到壞球」。他曾經引述美國紅襪隊強棒威廉斯(Ted Williams)的話,「當個好打者,你必須選好球來打」。遇到真正的好球前,不輕易出手,「他比大多數的投資者都看得清楚,手上有大量現金,並不一定就會減損公司表現,現金是一種策略型資產,」
  4. Berkshire Hathaway Inc. 選擇投資企業的準則
① 我們了解這間企業
企業應相對簡單與穩定,若太複雜且變動性高,就難以預測其未來的現金流
② 具備正面的長期未來展望

③ 這間企業的經營者是誠實且稱職的

④ 目前的價格是迷人的 (attractive price, 即 value < price)
我們秉持著 Graham 的安全邊際原則 (margin-of-safety principle),不具備足夠的安全邊際不會購買

  1. 低股價淨值比 (price to book value)、低本益比 (price-earnings ratio) 或高殖利率 (dividen yield) ,都不是價值投資 (value investing)。企業的成長率,也無法告訴我們什麼價值 (value),別忘了,對於某些公司,成長卻會摧毀他 (即 Return On Capitals < Cost of Capital ),當所賺得錢小於投入的成本,成長越多,賠得就越多,形成惡性循環。
  2. High-return 企業的成長才能讓投資人獲益,換句話說,在財務上每成長一元能夠超過長期市場價值 (market value) 的一元,成長才是有意義的。low-return 的企業需要更多的資金讓企業成長,但是其能貢獻的回報卻低於所投入的資金,這樣的成長是有害的
  3. 對於大部分投資來說,最重要的不是他們懂多少,而是真的知道自己什麼不懂。投資人其實只要避免犯下大錯,要做正確的事情的機會不多。
  4. 在「字典」裡面,風險 (risk) 代表「損失或受傷的可能性」。在「投資」的領域,風險代表股票相對於市場的波動性 (volatility),通常以一個稱為 β (Beta, 貝他值) 的數值來表示,即市場報酬變動時,個別資產之預期報酬率同時發生變動的程度,亦為投資該資產所須承擔的系統風險。Beta值就是衡量你所投資的個別股票,受到系統風險(如九二一大地震、貨幣供給)影響的程度。Beta值 > 1,表示你所投資的個股的報酬率(風險值)波動幅度,比市場波動幅度大;反之,Beta值 < 1,表示你所投資的個股的報酬率(風險值)波動幅度,比市場波動的幅度小。但是這種評估風險的方式,是正確的嗎? β 數值分析是一種「近似的正確好過精確的錯誤」(It's better to be approximately right than precisely wrong)
  5. 依照 beta-based theory,當一個高價股大幅下跌,將會比目前還在高價的股票還更具風險,因為波動大 = 風險大。事實上,投資人反而應該歡迎波動性 (volatility),當股市發生巨大波動,投資人恐慌賣出時,對於你來說,反而是絕佳的買進機會
  6. beta-based theory 不去檢視這間企業生產什麼產品或服務,企業的競爭對手在做什麼或企業借了多少錢並怎麼使用這筆錢,甚至不知道這間企業的名字。此分析方法只重視這檔股票的歷史價格
  7. Buffett 認為,投資人該分析的風險有
    1. 企業的長期競爭力
    2. 管理階層的經營能力與運用現金的能力
    3. 管理階層能將利益確實回報給股東而非中飽私囊
    4. 買進這間公司的價格
    5. 稅率與通膨率會決定你最後的投資毛利
  8. 如果你什麼都不懂,那就買 ETF。但如果你對於某些產業有些了解,你就應該投資5~10家股價合理且有長期競爭力的好公司。為什麼要把你的錢放在排名第20名的股票呢?專注在前幾名就好了!
  9. 凡是值得去做的,就值得努力做好 (What is worth doing is worth doing well);如果某件事不值得去做,那就不值得做好 (If something’s not worth doing at all, it’s not worth doing well)
  10. 併購的決策著重於把實質的經濟利益而非管理版圖或會計數字極大化,(長期而言,若管理當局過度注重會計數字而乎略經濟實質的話,通常最後兩者都顧不好),不管對帳面盈餘有何影響,Berkshire Hathaway Inc. 寧願以 X 價格買下一家好公司 10% 股權,而非以 2X 價格買下那家好公司 100% 股權,但大部份的公司經營階層偏好後者,而且對此行為總是找得到藉口。對於這種行為,我們歸納出三種動機
① 領導階層很少有缺少動物天性的,且時時散發出過動與戰鬥的意念
相對地在波克夏,即使是併購成功在望,管理當局心跳也不會加快一下。
② 大部份的公司或企業與其經營階層,多以 “規模”而非 “獲利”,作為衡量自己或別人的標準
問問那些名列 Fortune 500 大企業的負責人,他們可能從來都不知道他們的公司若以獲利能力來排的話,會落在第幾位
③ 大部份的經營階層很明顯的過度沉浸於小時候所聽到的,一個變成蟾蜍的王子因美麗的公主深深一吻而被救的童話故事,而認為只要被他們優異的管理能力一吻,被併購的公司便能脫胎換骨
如此的樂觀是必要的,否則公司的股東怎麼會甘心以二倍的價錢買下那家好公司,而非以一倍的價格自己從市場上買進。換言之,投資人永遠可以以蟾蜍的價格買到蟾蜍,而若投資人願意用雙倍的代價資助公主去親吻蟾蜍的話,最好保佑奇蹟會發生,許多公主依然堅信她們的吻有使蟾蜍變成王子的魔力,即使在她的後院早已養滿了一大堆的蟾蜍。

  1. Berkshire Hathaway Inc. 認為有兩種情況的併購是會成功的
① 第一類是你買到的是那種特別能夠適應通貨膨脹的公司
通常它們又具備了兩種特徵,一是很容易去調漲價格 (即使是當產品需求平緩,而產能未充份利用也一樣) 且不怕會失去市場佔有率或銷貨量;一種是只要增加額外少量的資本支出,便可以使營業額大幅增加 (雖然增加的原因,大部份是因為通貨膨脹而非實際增加產出的緣故),近十幾年來,只要符合以上兩種條件,雖然這種情況不多,即使是能力普通的經理人也能使這項併購案圓滿成功。
② 第二類是那些經營奇才
他們具有洞悉少數裹著蟾蜍外衣的王子



2019/01/01

[閱讀筆記] Antifragile: Things That Gain from Disorder (8/10)

  1. 蘇格拉底經常走到市場上與人討論哲學。他討論的方法十分獨特,人稱「蘇格拉底式對話」。他常常謙恭地(不知是裝的還是真的)問別人一個看似十分幼稚的問題如「甚麼是勇敢」,然後順著對對方的回答繼續追問下去,不消幾個來回,必定使其答案破綻百出。他不像其他哲學家一般希望正面地提出一套關於某議題的看法,與之相反,他的哲學旨在以詰問與難題使人自覺到自己的無知
  2. 蘇格拉底有一句名言足以總結他的哲學態度︰「我所知道的一切就是我對一切皆無所知。」因此,我們可以看到,他的謙恭其實來自於對無知的自覺,而他在別人眼中的「狂傲」亦來自於坦白揭露別人的無知。
  3. 知道自己實際上一無所知、其智慧實際上毫無價值的人,才是具有智慧的開始
  4. 要認識到自己或他人的德性,蘇格拉底認為人首先要「自知自己無知」,這個重要的概念又稱為「無知之知」。蘇格拉底借用刻在德爾斐神廟上的箴言:「認識你自己」來表達研究人自身的意義,而要認識自己的前提就首先要承認自己的無知。為了強調這點的重要性,蘇格拉底喜歡以公開的問答對話來傳授知識,比如當他的弟子或是民眾嘗試回答「什麼是善」,「什麼是美」等問題時,蘇格拉底總會找出他們答案中的漏洞,比如論證缺乏基礎與邏輯矛盾等,繼續追問下去,直到回答者無可爭辯,繼而承認自己的「無知」。這一套對答的教授方式,被蘇格拉底自己稱為是「助產法」,這也是西方哲學史上辯證法的起源。蘇格拉底認為通過問答的形式,特別是在回答者陷入難題時,承認其無知,從而可以引發更深的思考,這才能慢慢接近真理,好像助產士幫助孕婦接生一般。
  5. 黑格爾曾經如此闡述蘇格拉底,「幫助已經包藏於每一個人的意識中的思想出世」,而蘇格拉底通過揭露問答者的思維矛盾來刺激人們的思考,使得回答者能夠探尋到更為完整的答案。
  6. 生活中的差別不在於真或假,而是在於冤大頭或非冤大頭 (the distinction in life isn’t True or False, but rather sucker or nonsucker)
  7. 報償 / 代價 (payoff),也就是發生在你身上的事 (利益或者傷害),是最重要的事;事件本身不是最重要的。
  8. 哲學家愛談真與假。真正過生活的人談的是報償 (payoff)、曝險程度 (exposure) 和後果(consequence, 風險與獎酬),因此談的是脆弱與反脆弱。
  9. 企業如欲維繫卓越不墜並常保競爭力,絕對必須採行不連續性及創造性破壞的動態策略。企業若是抱持以連續性為基礎、恆久不變的假設等管理哲學來經營的話,長期下來,必然無法以市場的速度及規模來進行改變或是創造價值。
  10. 尼采認為:「盲目的樂觀,只會使人感覺膚淺;過度的悲觀,則會使人走向毀滅。唯有悲觀後的樂觀,才是精神上的強者!」
  11. 脆弱的東西都是非線性的。生活中削足適履的典範就是莫過於簡化非線性事物,使之呈現出線性,這種簡化扭曲了事實。金融風險管理就是其中的典型。銀行所謂的壓力測試是最愚蠢的,因為超過某臨界點時,事物會呈現急劇變化的非線性特徵。所以金融危機前,美國銀行都通過壓力測試,但危機一來,要不是政府救助,通通都要倒閉。
  12. 我們都熟知供應和需求曲線,但供需曲線很多時候並不是兩條斜線交叉,而是呈現極大的非線性。比如石油價格的波動、小麥價格的波動。塔勒布在書中舉了一個極端的例子:2004年-2007年,世界對小麥的需求量僅僅上升了1%,而價格卻上升了兩倍。最近幾年的國內煤價,和波羅的海乾散貨指數等,都是呈現明顯的非線性特徵。
  13. 如果一個人在變化面前是脆弱的,那麼平均數意義不大。平均數的概念,人們常用來簡化問題和事物的。比如,你如果對溫度很敏感,將要去一個地方旅行,告知你那邊平均溫度是20度,這對你一點意義都沒有。它有可能是半天六十度,而半夜零下二十度,你可能就回不來了。
  14. 對於脆弱來說,當強度增強時,將會帶來更嚴重的傷害。如被一整塊大石頭砸到的傷害,遠大被總重相同的一千顆小石子打到1000次;又如車速 50 公里車禍的傷害程度遠大於車速 5 公里的車禍 (脆弱程度普遍呈現非線性,即凹性);又如從 10 公尺的高度一躍而下所受的傷害,遠大於從 1 公尺的高度一躍而下
  15. 一個大的機構,假如出問題,對於市場會有龐大的影響。但假如市場上有很多個小機構,損失會小很多,或者根本不會是太大的問題。這是一種非線性結構,十次70億美金的股票出售所造成的影響,遠遠小於一次700億美金的股票售出。
  16. 脆弱代表著不對稱性 (asymmetry) ,就是非線性 (nonlinearity),受到的傷害大於益處,當強度增強時,所造成的傷害程度成非線性的方式增加
  1. 對於 fragile 來說,許多小的影響所累積起來的效應會小於整個小影響的總和所造成的影響。例如在地球上,每天都有一級、二級的小地震,但是這不會對你造成任何影響,但是若是六級以上的地震,一定是傷亡慘重,造成非線性的影響
  2. ​對於 antifragile 來說,當強度增強時 (但有其極限),反而對帶來有益的幫助。例如在健身房,一次舉起 100 磅所帶來的好處勝過舉兩次 50 磅。
  3. Convex (凸性) 就是 antifragile,convex 喜歡變動 (variation),若你可以從價格變動 (fluctuations) 中得利 (gain more than pain),你就會想要更多的價格變動
  1. Travel cost 對於高速公路的車輛數量的變動是脆弱的 (curving inward, concave, 不是件好事情);其變動不是根據平均車輛數量來決定,當車輛越多,你的車速會不成比例的快速下降,你所花費的開車時間也會不成比例的拉長

  1. 對於幾乎健康的人,我們不應該冒險;但對於處在危險中的人,則應該冒高出很多的風險。
  2. 城市並非較大的村莊,企業也非較大的小型企業。隨著治理與管理的範圍變大,整體複雜會呈現非線性 (nonlinear) 的提升,而不是線性 (linear)
  3. 脆弱常源自於 size,size 越大反而越容易脆弱。兩間公司合併,常常未必會看到預期的運作效率、經濟規模或一加一大於二的效果;專案的規模越大,通常會得到較差的結果、較多的預算超支 (overrun) 等
  4. 當人們在電影散場後要從出口離開戲院,同樣的人數,半小時內離場與發生火警要一分鐘以內離場的擠壓成本 (costs of squeeze) 是不同的。當今的經濟學家常將我們的生活過度最佳化,建造更大的戲院,卻只留相同數目的逃生門,並沒有考量到人數越多越會產生越大的擠壓成本。
  5. 經濟學家常認為供需之間是一條線性的線,這就是忽略了真實世界非線性的風險。以2004 ~ 2007 年的小麥價格為例,淨需求量只有小小增加約 1%,價格卻在這期間漲了三倍之多
  6. 「規劃謬誤」(planning fallacy)是指對計畫完成所需的時間一貫抱持不切實際的樂觀態度。任何人只要雇用過承包商都知道,所有的工作都會比你預期的時間拖更久,即使你早已知道規劃謬誤也無法避免。這都是忽略了 nonlinear 所造成的後果與風險
  7. 飛機旅途常會有很多未知的因素造成延遲,飛行時間不可能是 0 或是負數,即便是提早抵達也頂多是提前幾分鐘,但是延遲就可能是數小時,這就是一種不對稱性 (asymmetry)。做專案也是如此,工期不可能是 0或 負數,即便提早完成也是提早一點點時間,但是專案延誤就有可能是數個月的時間,這也是一種不對稱性 (asymmetry)。會造成這些不對稱性,都是因為 uncertainty 與 nonlinear 的緣故
  8. Fragility 存在於任何一個領域,如政治系統、公司規模、班機延誤、專案費用超支等,這一切的脆弱性源自於 nonlinear。你該思考的是如何從 uncertainty 中獲利,不要憎恨隨機,不要討厭 uncertainty,對付不確定性的最好辦法是槓鈴策略 (barbell strategy) 。槓鈴策略意味著關注兩個極端而不是中間地帶,兩個極端並不需要對稱。
  9. 平均值的數字意義不大,因為其忽略了數字的變異,而變異的程度就是脆弱的來源。當所在的世界更加 nonlinear,與平均值的數字關係就越不相關。以空氣汙染 PM2.5 來說,以全國平均值27來看,空汙似乎不嚴重,一旦分成冬季跟夏季,就會發現問題不小,尤以中南部民眾感受最強烈。2014年的10月至隔年4月,北部平均值微升至18.8,空氣還算不錯,中部則大幅增至31.7、雲嘉南飆升至40.2,是夏天的2.68倍,高屏也高達39.4,是夏天的3.18倍。
  10. 很多模型的錯誤與脆弱之處在於,將機率與後果嚴重度視為線性與對稱,使用計量經濟的方程式,通常只會低估黑天鵝事件的機率與嚴重度


2018/12/15

[Java] [MapStruct] How to convert Enumeration to String in MapStruct?

Problem
Assume I have an Employee POJO:
package com.example.demo.vo;

import com.example.demo.enumeration.Gender;
import com.example.demo.enumeration.YesOrNoType;

import lombok.Data;
import lombok.ToString;

@Data
@ToString
public class Employee {

    /**
     * 員工編號
     */
    private Integer id;

    /**
     * 員工姓名
     */
    private String name;

    /**
     * 員工性別
     */
    private Gender gender;

    /**
     * 是否離職
     */
    private YesOrNoType quit;
    

}

and an EmployeeDto POJO:
package com.example.demo.vo;

import lombok.Data;

@Data
public class EmployeeDto {

    /**
     * 員工編號
     */
    private String id;

    /**
     * 員工姓名
     */
    private String name;

    /**
     * 員工性別
     */
    private String gender;

    /**
     * 是否離職
     */
    private String quit; 
    
}

Gender Enumeration:
package com.example.demo.enumeration;

public enum Gender {
    
    MALE("M", "男"), FEMALE("F", "女");

    private final String value;

    private final String description;

    Gender(String value, String description) {
        this.value = value;
        this.description = description;
    }

    public String getValue() {
        return value;
    }

    public String getDescription() {
        return description;
    }

}


YesOrNoType Enumeration:
package com.example.demo.enumeration;

public enum YesOrNoType {
    
    YES("Y", "是"), NO("N", "否");

    private final String value;

    private final String description;

    YesOrNoType(String value, String description) {
        this.value = value;
        this.description = description;
    }

    public String getValue() {
        return value;
    }

    public String getDescription() {
        return description;
    }
}


If I would like to convert Employee to EmployeeDTO, and convert gender and quit attributes to description, how to do it?

How-To
Add the following configurations in your pom.xml
    <properties>
        <org.mapstruct.version>1.2.0.Final</org.mapstruct.version>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
            <version>${org.mapstruct.version}</version>
        </dependency>
 </dependencies>
 
  <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source> <!-- or higher, depending on your project -->
                    <target>1.8</target> <!-- or higher, depending on your project -->
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>


Create an EmployeeMapper:
package com.example.demo.mapStruct;

import org.mapstruct.DecoratedWith;
import org.mapstruct.Mapper;

import com.example.demo.vo.Employee;
import com.example.demo.vo.EmployeeDto;

@Mapper
@DecoratedWith(EmployeeDecorator.class)
public interface EmployeeMapper {

    EmployeeDto toDto(Employee employee);
    
}


Create an EmployeeDecorator:
package com.example.demo.mapStruct;

import com.example.demo.vo.Employee;
import com.example.demo.vo.EmployeeDto;

public class EmployeeDecorator implements EmployeeMapper {

    private EmployeeMapper delegate;

    public EmployeeDecorator(EmployeeMapper delegate) {
        super();
        this.delegate = delegate;
    }

    @Override
    public EmployeeDto toDto(Employee employee) {
        EmployeeDto dto = delegate.toDto(employee);
        dto.setId(employee.getId().toString());
        dto.setGender(employee.getGender().getDescription());
        dto.setQuit(employee.getQuit().getDescription());

        return dto;
    }

}


Create a test class:
package com.example.demo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.mapstruct.factory.Mappers;

import com.example.demo.enumeration.Gender;
import com.example.demo.enumeration.YesOrNoType;
import com.example.demo.mapStruct.EmployeeMapper;
import com.example.demo.vo.Employee;
import com.example.demo.vo.EmployeeDto;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MapStructTest {

    private static List<Employee> employees = new ArrayList<>();

    static {
        Employee albert = new Employee();
        albert.setId(1);
        albert.setName("Albert");
        albert.setGender(Gender.MALE);
        albert.setQuit(YesOrNoType.NO);

        Employee mandy = new Employee();
        mandy.setId(2);
        mandy.setName("Mandy");
        mandy.setGender(Gender.FEMALE);
        mandy.setQuit(YesOrNoType.NO);

        Employee peter = new Employee();
        peter.setId(3);
        peter.setName("Peter");
        peter.setGender(Gender.MALE);
        peter.setQuit(YesOrNoType.YES);

        employees = Arrays.asList(albert, mandy, peter);

    }

    public static void main(String[] args) {
        EmployeeMapper mapper = Mappers.getMapper(EmployeeMapper.class);
        for (Employee employee : employees) {
            EmployeeDto dto = mapper.toDto(employee);
            log.debug("employee: " + employee.toString() + ", dto : " + dto.toString());
        }
    }

}



10:51:10.018 [main] DEBUG com.example.demo.MapStructTest - employee: Employee(id=1, name=Albert, gender=MALE, quit=NO), dto : EmployeeDto(id=1, name=Albert, gender=男, quit=否)
10:51:10.020 [main] DEBUG com.example.demo.MapStructTest - employee: Employee(id=1, name=Mandy, gender=FEMALE, quit=NO), dto : EmployeeDto(id=2, name=Mandy, gender=女, quit=否)
10:51:10.020 [main] DEBUG com.example.demo.MapStructTest - employee: Employee(id=3, name=Peter, gender=MALE, quit=YES), dto : EmployeeDto(id=3, name=Peter, gender=男, quit=是)




2018/12/14

[SQL Developer] How to configure SQL Developer to connect to Sybase database?

Problem
How to configure SQL Developer to connect to Sybase database?


How-To
1. Download jTDS from https://sourceforge.net/projects/jtds/files/

2. Launch SQL Devloper, Tools => Preferences

3. Choose Database => Third Party JDBC Drivers, and add jTDS jar file


4. Close and re-launch SQL Developer. Then you can see SQLServer and Sybase tab in New Database Connection dialog.





2018/12/13

[SQL Developer] How to change language to English in SQL Developer?

Problem
I downloaded SQL Developer from http://www.oracle.com/technetwork/developer-tools/sql-developer/downloads/index.html

As I launch SQL Developer, the default language is Traditional Chinese:



How-To
Close SQL Developer and edit ide.conf which will be found in \sqldeveloper\ide\bin

Add the following configuration at the end of ide.conf and save it.
# Set language to en
AddVMOption -Duser.language=en

Launch SQL Developer again


Reference
[1] https://stackoverflow.com/questions/7768313/how-can-i-change-the-language-to-english-in-oracle-sql-developer