- N +

notnull注解,數(shù)據(jù)庫null和notnull

各位老鐵們,大家好,今天由我來為大家分享notnull注解,以及數(shù)據(jù)庫null和notnull的相關(guān)問題知識,希望對大家有所幫助。如果可以幫助到大家,還望關(guān)注收藏下本站,您的支持是我們最大的動力,謝謝大家了哈,下面我們開始吧!

Spring如何解決循環(huán)依賴的問題

1.由同事拋的一個問題開始

最近項目組的一個同事遇到了一個問題,問我的意見,一下子引起的我的興趣,因為這個問題我也是第一次遇到。平時自認為對spring循環(huán)依賴問題還是比較了解的,直到遇到這個和后面的幾個問題后,重新刷新了我的認識。

我們先看看當時出問題的代碼片段:

@ServicepublicclassTestService1{@AutowiredprivateTestService2testService2;@Asyncpublicvoidtest1(){}}

@ServicepublicclassTestService2{@AutowiredprivateTestService1testService1;publicvoidtest2(){}}

這兩段代碼中定義了兩個Service類:TestService1和TestService2,在TestService1中注入了TestService2的實例,同時在TestService2中注入了TestService1的實例,這里構(gòu)成了循環(huán)依賴。

只不過,這不是普通的循環(huán)依賴,因為TestService1的test1方法上加了一個@Async注解。

大家猜猜程序啟動后運行結(jié)果會怎樣?

org.springframework.beans.factory.BeanCurrentlyInCreationException:Errorcreatingbeanwithname'testService1':Beanwithname'testService1'hasbeeninjectedintootherbeans[testService2]initsrawversionaspartofacircularreference,buthaseventuallybeenwrapped.Thismeansthatsaidotherbeansdonotusethefinalversionofthebean.Thisisoftentheresultofover-eagertypematching-considerusing'getBeanNamesOfType'withthe'allowEagerInit'flagturnedoff,forexample.

報錯了。。。原因是出現(xiàn)了循環(huán)依賴。

「不科學呀,spring不是號稱能解決循環(huán)依賴問題嗎,怎么還會出現(xiàn)?」

如果把上面的代碼稍微調(diào)整一下:

@ServicepublicclassTestService1{@AutowiredprivateTestService2testService2;publicvoidtest1(){}}

把TestService1的test1方法上的@Async注解去掉,TestService1和TestService2都需要注入對方的實例,同樣構(gòu)成了循環(huán)依賴。

但是重新啟動項目,發(fā)現(xiàn)它能夠正常運行。這又是為什么?

帶著這兩個問題,讓我們一起開始spring循環(huán)依賴的探秘之旅。

2.什么是循環(huán)依賴?

循環(huán)依賴:說白是一個或多個對象實例之間存在直接或間接的依賴關(guān)系,這種依賴關(guān)系構(gòu)成了構(gòu)成一個環(huán)形調(diào)用。

第一種情況:自己依賴自己的直接依賴

第二種情況:兩個對象之間的直接依賴

第三種情況:多個對象之間的間接依賴

前面兩種情況的直接循環(huán)依賴比較直觀,非常好識別,但是第三種間接循環(huán)依賴的情況有時候因為業(yè)務代碼調(diào)用層級很深,不容易識別出來。

3.循環(huán)依賴的N種場景

spring中出現(xiàn)循環(huán)依賴主要有以下場景:

單例的setter注入

這種注入方式應該是spring用的最多的,代碼如下:

@ServicepublicclassTestService1{@AutowiredprivateTestService2testService2;publicvoidtest1(){}}

@ServicepublicclassTestService2{@AutowiredprivateTestService1testService1;publicvoidtest2(){}}

這是一個經(jīng)典的循環(huán)依賴,但是它能正常運行,得益于spring的內(nèi)部機制,讓我們根本無法感知它有問題,因為spring默默幫我們解決了。

spring內(nèi)部有三級緩存:

singletonObjects一級緩存,用于保存實例化、注入、初始化完成的bean實例earlySingletonObjects二級緩存,用于保存實例化完成的bean實例singletonFactories三級緩存,用于保存bean創(chuàng)建工廠,以便于后面擴展有機會創(chuàng)建代理對象。

下面用一張圖告訴你,spring是如何解決循環(huán)依賴的:

圖1

細心的朋友可能會發(fā)現(xiàn)在這種場景中第二級緩存作用不大。

那么問題來了,為什么要用第二級緩存呢?

試想一下,如果出現(xiàn)以下這種情況,我們要如何處理?

@ServicepublicclassTestService1{@AutowiredprivateTestService2testService2;@AutowiredprivateTestService3testService3;publicvoidtest1(){}}

@ServicepublicclassTestService2{@AutowiredprivateTestService1testService1;publicvoidtest2(){}}

@ServicepublicclassTestService3{@AutowiredprivateTestService1testService1;publicvoidtest3(){}}

TestService1依賴于TestService2和TestService3,而TestService2依賴于TestService1,同時TestService3也依賴于TestService1。

按照上圖的流程可以把TestService1注入到TestService2,并且TestService1的實例是從第三級緩存中獲取的。

假設不用第二級緩存,TestService1注入到TestService3的流程如圖:

圖2

TestService1注入到TestService3又需要從第三級緩存中獲取實例,而第三級緩存里保存的并非真正的實例對象,而是ObjectFactory對象。說白了,兩次從三級緩存中獲取都是ObjectFactory對象,而通過它創(chuàng)建的實例對象每次可能都不一樣的。

這樣不是有問題?

為了解決這個問題,spring引入的第二級緩存。上面圖1其實TestService1對象的實例已經(jīng)被添加到第二級緩存中了,而在TestService1注入到TestService3時,只用從第二級緩存中獲取該對象即可。

圖3

還有個問題,第三級緩存中為什么要添加ObjectFactory對象,直接保存實例對象不行嗎?

答:不行,因為假如你想對添加到三級緩存中的實例對象進行增強,直接用實例對象是行不通的。

針對這種場景spring是怎么做的呢?

答案就在AbstractAutowireCapableBeanFactory類doCreateBean方法的這段代碼中:

它定義了一個匿名內(nèi)部類,通過getEarlyBeanReference方法獲取代理對象,其實底層是通過AbstractAutoProxyCreator類的getEarlyBeanReference生成代理對象。

多例的setter注入

這種注入方法偶然會有,特別是在多線程的場景下,具體代碼如下:

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)@ServicepublicclassTestService1{@AutowiredprivateTestService2testService2;publicvoidtest1(){}}

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)@ServicepublicclassTestService2{@AutowiredprivateTestService1testService1;publicvoidtest2(){}}

很多人說這種情況spring容器啟動會報錯,其實是不對的,我非常負責任的告訴你程序能夠正常啟動。

為什么呢?

其實在AbstractApplicationContext類的refresh方法中告訴了我們答案,它會調(diào)用finishBeanFactoryInitialization方法,該方法的作用是為了spring容器啟動的時候提前初始化一些bean。該方法的內(nèi)部又調(diào)用了preInstantiateSingletons方法

標紅的地方明顯能夠看出:非抽象、單例并且非懶加載的類才能被提前初始bean。

而多例即SCOPE_PROTOTYPE類型的類,非單例,不會被提前初始化bean,所以程序能夠正常啟動。

如何讓他提前初始化bean呢?

只需要再定義一個單例的類,在它里面注入TestService1

@ServicepublicclassTestService3{@AutowiredprivateTestService1testService1;}

重新啟動程序,執(zhí)行結(jié)果:

Requestedbeaniscurrentlyincreation:Isthereanunresolvablecircularreference?

果然出現(xiàn)了循環(huán)依賴。

注意:這種循環(huán)依賴問題是無法解決的,因為它沒有用緩存,每次都會生成一個新對象。

構(gòu)造器注入

這種注入方式現(xiàn)在其實用的已經(jīng)非常少了,但是我們還是有必要了解一下,看看如下代碼:

@ServicepublicclassTestService1{publicTestService1(TestService2testService2){}}

@ServicepublicclassTestService2{publicTestService2(TestService1testService1){}}

運行結(jié)果:

Requestedbeaniscurrentlyincreation:Isthereanunresolvablecircularreference?

出現(xiàn)了循環(huán)依賴,為什么呢?

從圖中的流程看出構(gòu)造器注入沒能添加到三級緩存,也沒有使用緩存,所以也無法解決循環(huán)依賴問題。

單例的代理對象setter注入

這種注入方式其實也比較常用,比如平時使用:@Async注解的場景,會通過AOP自動生成代理對象。

我那位同事的問題也是這種情況。

@ServicepublicclassTestService1{@AutowiredprivateTestService2testService2;@Asyncpublicvoidtest1(){}}

@ServicepublicclassTestService2{@AutowiredprivateTestService1testService1;publicvoidtest2(){}}

從前面得知程序啟動會報錯,出現(xiàn)了循環(huán)依賴:

org.springframework.beans.factory.BeanCurrentlyInCreationException:Errorcreatingbeanwithname'testService1':Beanwithname'testService1'hasbeeninjectedintootherbeans[testService2]initsrawversionaspartofacircularreference,buthaseventuallybeenwrapped.Thismeansthatsaidotherbeansdonotusethefinalversionofthebean.Thisisoftentheresultofover-eagertypematching-considerusing'getBeanNamesOfType'withthe'allowEagerInit'flagturnedoff,forexample.

為什么會循環(huán)依賴呢?

答案就在下面這張圖中:

說白了,bean初始化完成之后,后面還有一步去檢查:第二級緩存和原始對象是否相等。由于它對前面流程來說無關(guān)緊要,所以前面的流程圖中省略了,但是在這里是關(guān)鍵點,我們重點說說:

那位同事的問題正好是走到這段代碼,發(fā)現(xiàn)第二級緩存和原始對象不相等,所以拋出了循環(huán)依賴的異常。

如果這時候把TestService1改個名字,改成:TestService6,其他的都不變。

@ServicepublicclassTestService6{@AutowiredprivateTestService2testService2;@Asyncpublicvoidtest1(){}}

再重新啟動一下程序,神奇般的好了。

what?這又是為什么?

這就要從spring的bean加載順序說起了,默認情況下,spring是按照文件完整路徑遞歸查找的,按路徑+文件名排序,排在前面的先加載。所以TestService1比TestService2先加載,而改了文件名稱之后,TestService2比TestService6先加載。

為什么TestService2比TestService6先加載就沒問題呢?

答案在下面這張圖中:

這種情況testService6中其實第二級緩存是空的,不需要跟原始對象判斷,所以不會拋出循環(huán)依賴。

DependsOn循環(huán)依賴

還有一種有些特殊的場景,比如我們需要在實例化BeanA之前,先實例化BeanB,這個時候就可以使用@DependsOn注解。

@DependsOn(value="testService2")@ServicepublicclassTestService1{@AutowiredprivateTestService2testService2;publicvoidtest1(){}}

@DependsOn(value="testService1")@ServicepublicclassTestService2{@AutowiredprivateTestService1testService1;publicvoidtest2(){}}

程序啟動之后,執(zhí)行結(jié)果:

Circulardepends-onrelationshipbetween'testService2'and'testService1'

這個例子中本來如果TestService1和TestService2都沒有加@DependsOn注解是沒問題的,反而加了這個注解會出現(xiàn)循環(huán)依賴問題。

這又是為什么?

答案在AbstractBeanFactory類的doGetBean方法的這段代碼中:

它會檢查dependsOn的實例有沒有循環(huán)依賴,如果有循環(huán)依賴則拋異常。

4.出現(xiàn)循環(huán)依賴如何解決?

項目中如果出現(xiàn)循環(huán)依賴問題,說明是spring默認無法解決的循環(huán)依賴,要看項目的打印日志,屬于哪種循環(huán)依賴。目前包含下面幾種情況:

生成代理對象產(chǎn)生的循環(huán)依賴

這類循環(huán)依賴問題解決方法很多,主要有:

使用@Lazy注解,延遲加載使用@DependsOn注解,指定加載先后關(guān)系修改文件名稱,改變循環(huán)依賴類的加載順序

使用@DependsOn產(chǎn)生的循環(huán)依賴

這類循環(huán)依賴問題要找到@DependsOn注解循環(huán)依賴的地方,迫使它不循環(huán)依賴就可以解決問題。

多例循環(huán)依賴

這類循環(huán)依賴問題可以通過把bean改成單例的解決。

構(gòu)造器循環(huán)依賴

這類循環(huán)依賴問題可以通過使用@Lazy注解解決。

最后說一句(求關(guān)注,別白嫖我)

如果這篇文章對您有所幫助,或者有所啟發(fā)的話,幫忙掃描下發(fā)二維碼關(guān)注一下,您的支持是我堅持寫作最大的動力。

求一鍵三連:點贊、轉(zhuǎn)發(fā)、在看。

在公眾號中回復:面試、代碼神器、開發(fā)手冊、時間管理有超贊的粉絲福利,另外回復:加群,可以跟很多BAT大廠的前輩交流和學習。

mysql數(shù)據(jù)類型的詳解

MySQL數(shù)據(jù)庫的表是一個二維表,由一個或多個數(shù)據(jù)列構(gòu)成。每個數(shù)據(jù)列都有它的特定類型,該類型決定了MySQL如何看待該列數(shù)據(jù),我們可以把整型數(shù)值存放到字符類型的列中,MySQL則會把它看成字符串來處理。MySQL中的列類型有三種:數(shù)值類、字符串類和日期/時間類。從大類來看列類型和數(shù)值類型一樣,都是只有三種。但每種列類型都還可細分。下面對各種列類型進行詳細介紹。

數(shù)值類的數(shù)據(jù)列類型數(shù)值型的列類型包括整型和浮點型兩大類。

TINYINT:1字節(jié)非常小的正整數(shù),帶符號:-128~127,不帶符號:0~255SMALLINT:2字節(jié)小整數(shù),帶符號:-32768~32767,不帶符號:0~65535MEDIUMINT:3字節(jié)中等大小的整數(shù),帶符號:-8388608~8388607,不帶符號:0~16777215INT:4字節(jié)標準整數(shù),帶符號:-2147483648~2147483647,不帶符號:0~4294967295BIGINT:8字節(jié)大整數(shù),帶符號:-9223372036854775808~9233372036854775807,不帶符號:0~18446744073709551615FLOAT:4字節(jié)單精度浮點數(shù),最小非零值:+-1.175494351E-38,最大非零值:+-3.402823466E+38DOUBLE:8字節(jié)雙精度浮點數(shù),最小非零值:+-2.2250738585072014E-308,最大非零值:+-1.7976931348623157E+308DECIMAL:M+2字節(jié)以字符串形式表示的浮點數(shù),它的取值范圍可變,由M和D的值決定。MYSQL支持大量的列類型,它們可以被分為3類:數(shù)字類型、日期和時間類型以及字符串(字符)類型。這個章節(jié)首先給出可用類型的概述,并且總結(jié)各類型所需的存儲需求,然后提供各類型中的類型范疇更詳細的描述。概述有意地簡化了。更詳細的說明應該參考特寫列類型的附加信息,例如你能為其指定值的允許格式。MySQL支持的列類型在下面列出。下列代碼字母用于描述中:M指出最大的顯示尺寸。最大的顯示尺寸長度為255。D適用于浮點類型。指出跟隨在十進制小數(shù)點后的數(shù)字數(shù)量。最大可能值為30,但不應大于M-2。方括號(“[”and“]”)指定可選的類型修飾部份。注意,如果為一個列指定了ZEROFILL,MySQL將自動為這個列添加UNSIGNED屬性。警告:你應該知道當在兩個整數(shù)類型值中使用減法時,如有一個為UNSIGNED類型,那么結(jié)果也是無符號的。查看章節(jié)6.3.5Cast函數(shù)。

TINYINT[(M)][UNSIGNED][ZEROFILL]-128到127。無符號的范圍是0到255。BITBOOL它們是TINYINT(1)的同義詞。

SMALLINT[(M)][UNSIGNED][ZEROFILL]一個小整數(shù)。有符號的范圍是-32768到32767。無符號的范圍是0到65535。

MEDIUMINT[(M)][UNSIGNED][ZEROFILL]一個中等大小的整數(shù)。有符號的范圍是-8388608到8388607。無符號的范圍是0到16777215。

INT[(M)][UNSIGNED][ZEROFILL]一個正常大小的整數(shù)。有符號的范圍是-2147483648到2147483647。無符號的范圍是0到4294967295。

INTEGER[(M)][UNSIGNED][ZEROFILL]INT的同義詞。

BIGINT[(M)][UNSIGNED][ZEROFILL]一個大的整數(shù)。有符號的范圍是-9223372036854775808到9223372036854775807。無符號的范圍是0到18446744073709551615。你應該知道的有關(guān)BIGINT列的一些事情:BIGINT或DOUBLE值來完成的,因此你不應該使用大于9223372036854775807(63bits)的無符號大整數(shù),除了位函數(shù)之外!如果你這樣做了,結(jié)果中的某些大數(shù)字可能會出錯,因為將BIGINT轉(zhuǎn)換成DOUBLE時產(chǎn)生了舍入錯誤。MySQL4.0在下列情況下可以處理BIGINT:在一個BIGINT列中使用整數(shù)存儲一個大的無符號值。在MIN(big_int_column)和MAX(big_int_column)中。當兩個操作數(shù)都是整數(shù)時使用操作符(+、-、*、等)。通常你可以在一個BIGINT列中以字符串方式存儲的一個精確的整數(shù)。在這種情況下,MySQL將執(zhí)行一個字符串到數(shù)字的轉(zhuǎn)換,包括無intermediate的雙精度表示法。當兩個參數(shù)均是整數(shù)值時,“-”、“+”和“*”將使用BIGINT運算!這就意味著,如果兩個大整數(shù)的乘積(或函數(shù)的結(jié)果返回整數(shù))的結(jié)果大于9223372036854775807時,你可能會得到意想不到的結(jié)果。FLOAT(precision)[UNSIGNED][ZEROFILL]一個浮點型數(shù)字。precision可以是<=24作為一個單精度的浮點數(shù)字和介于25和53之間作為一個雙精度的浮點數(shù)字。這些類型與下面描述的FLOAT和DOUBLE類型相似。FLOAT(X)有與相應的FLOAT和DOUBLE類型同樣的范圍,但是顯示尺寸和十進制小數(shù)位數(shù)是未定義的。在MySQL3.23中,它是一個真實的浮點值。而在MySQL早期的版本中,F(xiàn)LOAT(precision)通常有2小數(shù)位。注意,由于在MySQL中所有的計算都是以雙精度執(zhí)行的,所以使用FLOAT可能帶來一些意想不到的問題。查看章節(jié)A.5.6解決沒有匹配行的問題。FLOAT[(M,D)][UNSIGNED][ZEROFILL]一個小的(單精度)浮點數(shù)字。允許的值是-3.402823466E+38到-1.175494351E-38、0和1.175494351E-38到3.402823466E+38。如果UNSIGNED被指定,負值是不允許的。M是顯示寬度,D是小數(shù)位數(shù)。FLOAT沒有參數(shù)或有X<=24的FLOAT(X)代表一個單精度的浮點數(shù)字。DOUBLE[(M,D)][UNSIGNED][ZEROFILL]一個正常大小的(雙精度)浮上數(shù)字。允許的值是-1.7976931348623157E+308到-2.2250738585072014E-308、0和2.2250738585072014E-308到1.7976931348623157E+308。如果UNSIGNED被指定,負值是不允許的。M是顯示寬度,D是小數(shù)位數(shù)。DOUBLE沒胡參數(shù)或有25<=X<=53的FLOAT(X)代表一個雙精度的浮點數(shù)字。DOUBLEPRECISION[(M,D)][UNSIGNED][ZEROFILL]REAL[(M,D)][UNSIGNED][ZEROFILL]它們是DOUBLE同義詞。DECIMAL[(M[,D])][UNSIGNED][ZEROFILL]一個未壓縮(unpacked)的浮點數(shù)。運作如同一個CHAR列:“unpacked”意味著數(shù)字是以一個字符串存儲的,值的每一位將使用一個字符。小數(shù)點并且對于負數(shù),“-”符號不在M中計算(但是它們的空間是被保留的)。如果D是0,值將沒有小數(shù)點或小數(shù)部份。DECIMAL值的最大范圍與DOUBLE一致,但是對于一個給定的DECIMAL列,實際的范圍可以被所選擇的M和D限制。如果UNSIGNED被指定,負值是不允許的。如果D被忽略,缺省為0。如果M被忽略,缺省為10。在MySQL3.23以前,M參數(shù)必須包含符號與小數(shù)點所需的空間。DEC[(M[,D])][UNSIGNED][ZEROFILL]NUMERIC[(M[,D])][UNSIGNED][ZEROFILL]DECIMAL的同義詞。DATE一個日期。支持的范圍是'1000-01-01'到'9999-12-31'。MySQL以'YYYY-MM-DD'格式顯示DATE值,但是允許你以字符串或數(shù)字給一個DATE列賦值。查看章節(jié)6.2.2.2DATETIME、DATE和TIMESTAMP類型。DATETIME一個日期和時間的組合。支持的范圍是'1000-01-0100:00:00'到'9999-12-3123:59:59'。MySQL以'YYYY-MM-DDHH:MM:SS'格式顯示DATETIME值,但是允許你以字符串或數(shù)字給一個DATETIME列賦值。查看章節(jié)6.2.2.2DATETIME、DATE和TIMESTAMP類型。TIMESTAMP[(M)]一個時間戳。范圍是'1970-01-0100:00:00'到2037年間的任意時刻。MySQL4.0和更早版本中,TIMESTAMP值是以YYYYMMDDHHMMSS、YYMMDDHHMMSS、YYYYMMDD或YYMMDD格式顯示的,它取決于M是否是14(或省略)、12、8或6,但是允許你以字符串或數(shù)字給一個TIMESTAMP列賦值。從MySQL4.1開始,TIMESTAMP以'YYYY-MM-DDHH:MM:DD'格式作為字符返回。如果你你希望以數(shù)字形式返回則必須在該時間戳字段后加上+0。不同的時間戳長度是不支持的。從MySQL4.0.12開始,選項--new可以被用來使服務器與4.1一樣運作。TIMESTAMP列有益于記錄一個INSERT或UPDATE操作的日期和時間,因為如果你自己沒有給它賦值,它將被自動地設置為最近一次操作的日期和時間。也可以通過給它賦一個NULL而使它設置為當前的日期和時間。查看章節(jié)6.2.2Date和Time類型。參數(shù)M只影響一個TIMESTAMP列的顯示格式;它的值總是占用4個字節(jié)存儲。注意,當TIMESTAMP(M)列的M是8或14時,它返回的是數(shù)字而其它的TIMESTAMP(M)列返回的是字符串。這僅僅是為了可以可靠地轉(zhuǎn)儲并恢復到其它格式的表中。查看章節(jié)6.2.2.2DATETIME、DATE和TIMESTAMP類型。TIME一個時間。范圍是'-838:59:59'到'838:59:59'。MySQL以'HH:MM:SS'格式顯示TIME值,但是允許你使用字符串或數(shù)字來給TIME列賦值。查看章節(jié)6.2.2.3TIME類型。YEAR[(2|4)]一個2或4位數(shù)字格式的年(缺省為4位)。允許的值是1901到2155、0000(4位年格式)以及使用2位格式的1970-2069(70-69)。MySQL以YYYY格式顯示YEAR值,但是允許你使用字符串或數(shù)字來給YEAR列賦值。(YEAR類型在MySQL3.22之前不支持。)查看章節(jié)6.2.2.4YEAR類型。[NATIONAL]CHAR(M)[BINARY]一個定長的字符串,當存儲時,總是以空格填滿右邊到指定的長度。M的范圍是0到255(在MySQL3.23版本之前為1到255)。當該值被檢索時,尾部空格將被刪除。CHAR值根據(jù)缺省的字符集進行忽略大小寫的排索與比較,除非指定了關(guān)鍵詞BINARY。NATIONALCHAR(或短形式NCHAR)是以ANSISQL方式定義一個CHAR列,它將使用缺省的字符集。這在MySQL中是默認的。CHAR是CHARACTER的縮寫。MySQL允許以CHAR(0)類型建立一個列。一些老程序運行時必需一個列,卻又并不使用這個列的值,你就不得不為了適應它而建立該列,在這情況下,CHAR(0)將是很有益的。當需要一個列僅保存兩個值時:一個為CHAR(0)(該列沒有定義為NOTNULL),這將僅占用一個比特位來存儲2個值:NULL或""。查看章節(jié)6.2.3.1CHAR和VARCHAR類型。CHAR這是CHAR(1)的同義詞。[NATIONAL]VARCHAR(M)[BINARY]一個變長的字符串。注意:尾部的空格在存儲時將會被刪除(這與ANSISQL約規(guī)不同)。M的范圍是0到255(在MySQL4.0.2之前的版本中是1到255)。VARCHAR值以大小寫忽略方式進行排索與比較,除非關(guān)鍵詞BINARY被指定。查看章節(jié)6.5.3.1隱式的列定義變化。VARCHAR是CHARACTERVARYING的縮寫。查看章節(jié)6.2.3.1CHAR和VARCHAR類型。TINYBLOBTINYTEXT一個BLOB或TEXT列,最大長度為255(2^8-1)個字符。查看章節(jié)6.5.3.1隱式的列定義變化。查看章節(jié)6.2.3.2BLOB和TEXT類型。BLOBTEXT一個BLOB或TEXT列,最大長度為65535(2^16-1)個字符。查看章節(jié)6.5.3.1隱式的列定義變化。查看章節(jié)6.2.3.2BLOB和TEXT類型。MEDIUMBLOBMEDIUMTEXT一個BLOB或TEXT列,最大長度為16777215(2^24-1)個字符。查看章節(jié)6.5.3.1隱式的列定義變化。查看章節(jié)6.2.3.2BLOB和TEXT類型。LONGBLOBLONGTEXT一個BLOB或TEXT列,最大長度為4294967295(2^32-1)個字符。查看章節(jié)6.5.3.1隱式的列定義變化。注意,由于服務器/客戶端的協(xié)議以及MyISAM表通常有一個16M每通信包/表行的限制,你仍然不能使用這個類型的整個范圍。查看章節(jié)6.2.3.2BLOB和TEXT類型。ENUM('value1','value2',...)一個枚舉類型。一個僅能有一個值的字符串對象,這個值選自值列'value1'、'value2'、...、NULL或特殊的""出錯值。一個ENUM列可以有最大65535不同的值。查看章節(jié)6.2.3.3ENUM類型。SET('value1','value2',...)一個集合。一個能有零個或更多個值的字符串對象,其中每個值必須選自值列'value1'、'value2'、...。一個SET列可以有最大64個成員。查看章節(jié)6.2.3.4SET類型。MySQL支持所有的ANSI/ISOSQL92數(shù)字類型。這些類型包括準確數(shù)字的數(shù)據(jù)類型(NUMERIC、DECIMAL、INTEGER和SMALLINT),也包括近似數(shù)字的數(shù)據(jù)類型(FLOAT、REAL和DOUBLEPRECISION)。關(guān)鍵詞INT是INTEGER的同義詞,關(guān)鍵詞DEC是DECIMAL的同義詞。NUMERIC和DECIMAL類型被MySQL以同樣的類型實現(xiàn),這在SQL92標準中是允許的。他們用于保存對準確精度有重要要求的值,例如與金錢有關(guān)的數(shù)據(jù)。當以它們中的之一聲明一個列時,精度和數(shù)值范圍可以(通常是)被指定;例如:salaryDECIMAL(5,2)在這個例子中,5(精度(precision))代表重要的十進制數(shù)字的數(shù)目,2(數(shù)據(jù)范圍(scale))代表在小數(shù)點后的數(shù)字位數(shù)。在這種情況下,因此,salary列可以存儲的值范圍是從-99.99到99.99。(實際上MySQL在這個列中可以存儲的數(shù)值可以一直到999.99,因為它沒有存儲正數(shù)的符號)。譯者注:M與D對DECIMAL(M,D)取值范圍的影響類型說明取值范圍(MySQL<3.23)取值范圍(MySQL>=3.23)DECIMAL(4,1)-9.9到99.9-999.9到9999.9DECIMAL(5,1)-99.9到999.9-9999.9到99999.9DECIMAL(6,1)-999.9到9999.9-99999.9到999999.9DECIMAL(6,2)-99.99到999.99-9999.99到99999.99DECIMAL(6,3)-9.999到99.999-999.999到9999.999#在MySQL3.23及以后的版本中,DECIMAL(M,D)的取值范圍等于早期版本中的DECIMAL(M+2,D)的取值范圍。注釋結(jié)束:在ANSI/ISOSQL92中,句法DECIMAL(p)等價于DECIMAL(p,0)。同樣的,在執(zhí)行被允許決定值p的地方,句法DECIMAL等價于DECIMAL(p,0)。MySQL目前還不支持DECIMAL/NUMERIC數(shù)據(jù)類型的這些變體形式中的任一種。一般來說這并不是一個嚴重的問題,通過明確地控制精度和數(shù)值范圍可以得到這些類型的主要功能益處。DECIMAL和NUMERIC值是作為字符串存儲的,而不是作為二進制浮點數(shù),以便保護這些值的十進制精確度。一個字符用于數(shù)值的每一位、小數(shù)點(如果scale>0)和“-”符號(對于負值)。如果scale是0,DECIMAL和NUMERIC值不包含小數(shù)點或小數(shù)部分。DECIMAL和NUMERIC值的最大范圍與DOUBLE一致,但是對于一個給定的DECIMAL或NUMERIC列,它的實際范圍可制定該列時的precision或scale限制。當這樣的列被賦給了小數(shù)點的位數(shù)超過scale所指定的值時,該將根據(jù)scale進行四舍五入。當一個DECIMAL或NUMERIC列被賦與一個大小超過指定(或缺省)的precisionandscale的限止范圍時,MySQL以該列范圍的端點值存儲該值。

java nullpointexception這個是什么情況

這個是空指針異常.首先我們要了解一下什么是Java異常.

什么是Java異常?

異常就是有異于常態(tài),和正常情況不一樣,程序出現(xiàn)了非正常情況需要讓操作的人知道。并在Java中阻止當前方法或作用域繼續(xù)之情的情況,稱之為異常。

看一下源碼怎么說?

注釋翻譯:

當應用程序在訪問對象屬性或者方法的情況下嘗試使用null值時拋出。這些包括:

調(diào)用null對象的實例方法。

訪問或修改空對象的字段。

將數(shù)組的長度視為null。

就是一句話,你操作的對象沒有實例化,或者沒有初始化數(shù)據(jù).然后你又操作了它,就會出現(xiàn)該異常.

怎么避免這個情況?

在操作對象的時候,使用對象的默認值,方法或者屬性不設置null.就可以避免大多數(shù)的情況.

多測試編寫的代碼.

小沐學學學,為你手打編寫,感謝您的閱讀.加油,共勉.

oracle有數(shù)據(jù)怎么改變字段類型

你好。

用sql語句或是客戶端圖形界面都可以,

語法是這樣的:ALTERTABLE表名MODIFYCOLUMN字段名新數(shù)據(jù)類型新類型長度新默認值新注釋

例子:altertabletable1modifycolumncolumn1decimal(10,1)DEFAULTNULLCOMMENT'注釋';

如何獲取oracle字段注釋

oracle使用如下sql語句可以查詢表字段的注釋:

select*fromuser_col_commentstwhere1=1

andt.commentsisnotnull

andt.table_name='表名'

需注意:

1、該語句僅查詢當前登錄用戶的表或試圖,不包含其他用戶授權(quán)的表或試圖;

2、表或試圖名一定要大寫。

關(guān)于notnull注解到此分享完畢,希望能幫助到您。

返回列表
上一篇: