標籤:mysql
JDK:j2sdk1.5.0
MySQL:mysql-5.0.41-win32_178
JDBC驅動:mysql-connector-java-3.2.0-alpha-bin.jar
一、java與資料庫的串連
java與資料庫的串連書上寫有四種方法,我的理解其實從其實質上說就兩種,一種建立JDBC-ODBC橋,通過ODBC資料來源與資料庫相連。另一種是純java式的串連,通過java類庫API驅動串連。以MySQL為例,這兩種方法分別需要MySQL-ODBC驅動和MySQL-JDBC-ODBC驅動。我用的是第二種方法,當然也建議使用純java式的串連,需要MySQL-JDBC-ODBC驅動,可以從網上下載。
首先需要把驅動放在jdk的安裝目錄的lib目錄中,並在環境變數classpath中加上該jar包,其設定和jdk的classpath中dt.jar和tools.jar一樣。
串連過程分三步:載入驅動程式;使用java.sql包中的Connection建立串連;由Connection對象產生Statement對象,然後Statement對象就可以調用其方法傳遞SQL語句了。
下面以一個具體的執行個體來測試我們的串連:
import java.sql.*;
public class ConnectToMySQLTest
{
public static void main(String[] args)
{
try
{
//載入驅動程式
Class.forName("com.mysql.jdbc.Driver");
//建立指定資料庫的URL
String url="jdbc:mysql://localhost:3306/student"; //student是建立的資料庫的名字
String userName="root"; //root是MySQL預設的使用者名稱
String password="123"; //123是你設定的MySQL密碼
//建立串連
Connection conn=DriverManager.getConnection(url,userName,password);
//建立Statement對象
Statement stmt=conn.createStatement();
//Statement對象向資料庫提交SQL語句
stmt.execute("drop table if exists stu"); //若表stu存在則刪除
stmt.execute("create table stu(id int not null primary key,name varchar(20) not null,sex varchar(4))"); //建立表stu
//插入記錄
stmt.execute("insert into stu values(1,‘aaa‘,‘boy‘)");
stmt.execute("insert into stu values(2,‘bbb‘,‘girl‘)");
stmt.execute("insert into stu values(3,‘ccc‘,‘girl‘)");
//執行查詢資料庫操作,並返回查詢的結果集
ResultSet rs=stmt.executeQuery("select * from stu");
//將結果集表指標定位到第一條記錄前
rs.beforeFirst();
//列印查詢結果
System.out.println("stu表的資料如下:");
System.out.println("---------------------");
System.out.println("學號\t姓名\t性別");
System.out.println("---------------------");
int num;
String name;
String sex;
while (rs.next())
{
num=rs.getInt("id");
name=rs.getString("name");
sex=rs.getString("sex");
System.out.println(num+"\t"+name+"\t"+sex);
}
stmt.close();
conn.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
在測試之前,你需要啟動MySQL,在mysql命令視窗中輸入:create database student; 斷行符號建立student資料庫,然後在命令提示字元中編譯運行ConnectToMySQLTest,即可出現如下結果:
二、MySQL中文亂碼問題
首先我們先來做個測試:
上面的代碼運行成功後,開啟mysql命令視窗,在其中輸入:use student; (斷行符號選擇資料庫)
select * from stu; (斷行符號出現如下查詢結果)
然後把上面代碼stmt.execute("insert into stu values(1,‘aaa‘,‘boy‘)");中的‘aaa‘改為‘張三‘,然後儲存重新編譯運行,啟動並執行結果為:
我們再開啟mysql命令視窗,因為剛才我們已經選擇了student資料庫,我們可以直接輸入:select * from stu; (斷行符號查詢) 結果如下:
可以發現改成張三以後,運行結果正常顯示,但mysql中卻顯示的是兩個問號。
MySQL預設的字元編碼是latin1,與java對應的就是ISO-8859-1。所以要正確的顯示我們的中文字元,只需要將MySQL的字元編碼方式有latin1改成中文的就行了,改成“gbk”或"gb2312",修改的方法有兩種:
一種是重新設定MySQL,在它的設定精靈中有一項是讓你選擇字元的編碼,你可以選擇自訂選項,然後將其自訂為“gbk”或“gb2312”;
另一種是直接修改MySQL安裝目錄中的“my.ini”檔案,在MySQL的安裝目錄下找到該檔案,用記事本開啟,在其中找到以下兩句:
[my sql]
default-character-set=latin1
[my sqld]
……
……
default-character-set=latin1
分別將其中的latin1改成“gbk”即可,注意要用小寫,聽說大寫不識別。
網上還有幾種其他的方法,在這裡也說一下,有一種是在串連資料的串連串中指定字元集和Unicode編碼,他把資料庫的URL寫成:
String url="jdbc:mysql://localhost:3306/student?user=root&password=123&useUnicode=true&characterEncoding=gb2312";
這樣寫的目的是告訴驅動在與資料庫進行轉碼的時候按照這種方式來轉,從而避免亂碼,這種方法只能解決從java從MySQL中取出資料輸出時的亂碼問題,但若從java中向MySQL中插入中文資料時,在MySQL中仍然顯示的是亂碼,因為你並沒有修改MySQL的字元編碼方式,它還是預設的latin1,所以中文仍然不能正常顯示,換句話也就是說,若MySQL的編碼方式是latin1,你java向其中插入中文時,在MySQL中永遠是亂碼,它只能正確顯示在MySQL中直接向其插入的中文,從外界向其插入中文它是不能正常顯示的。
還有一種方法是,再使java從MySQL中取出資料時讓其由"latin1"轉化為"gbk",從java向MySQL中插入資料時讓其由"gbk"轉化為"latin1",以取出資料為例,經過這樣的轉化:
String name=new String(rst.getString("name").getBytes("ISO-8859-1"),"GBK");
這裡注意:gbk在java中是大寫,小寫會出錯。latin1在java中對應的是ISO-8859-1.
也可以寫兩個轉化函數,在轉化時通過調用函數去轉化,這兩個函數如下:
import java.io.UnsupportedEncodingException;
//解決中文問題
public class EncodingUtil {
//從資料庫取出用
public static String latin1ToGBK(String str)
{
try {
String temp_p = str;
byte[] temp_t = temp_p.getBytes("ISO-8859-1");
String temp = new String(temp_t,"GBK");
return temp;
}catch (UnsupportedEncodingException ex) {
System.out.println(ex);
return "";
}
}
//存入中文資料時用
public static String GBKToLatin1(String str)
{
if(str==null)
{
str="";
}
else{
try{
str=new String(str.getBytes("GBK"),"ISO-8859-1");
}
catch(Exception ex){
ex.printStackTrace();
}
}
return str;
}
}
但這種用於較少的資料庫操作的話還行,若你要頻繁的從資料庫中存取資料,那麼每一句存取的語句你都去調用方法去轉化,那顯然是行不通的。
寫到這裡,我再多說一點,我自己的理解對於後兩種方法,應該是在早期驅動程式不完善的時候出現問題的解決方案,可能驅動程式中對兩種編碼的轉化沒有能很好的實現,從而導致的存取亂碼問題,我在網上就見過有人通過修改mysql-jdbc驅動去解決問題,因為mysql-jdbc驅動是開放源碼的,他通過修改程式,重新編譯產生class檔案,然後運行不出現任何問題,很牛的人。
我自己的理解認為:現在的驅動已經完善了,所以在存取資料庫時,不會出現亂碼問題,亂碼問題只是資料庫使用的編碼方式若不是中文的,那麼在向其插入中文資料時,它不能正確顯示出來,我們只需修改資料庫的編碼方式即可OK了。
還有注意:不同版本的MySQL會有不同的結果,這個很奇怪,網上有人說MySQL資料庫的東西都是二進位存放的,支援任何資料,當然包括中文,你在MySQL命令列下輸入:
insert into stu values(4,‘李四‘,‘boy‘);
select * from stu;
會正確顯示李四,而如果你在java中向其插入該條記錄,再在MySQL中查看,就成??了,他的意思是證明了亂碼出現的原因是在java與MySQL的串連部分,也即驅動不能正確轉化。我在mysql-5.0.51a-win32中這樣測試過,確實是這樣的,但你在我們現在用的mysql-5.0.41-win32_178中測試,若MySQL編碼為latin1時,在MySQL命令中插入中文記錄時,會出現錯誤:ERROR:1366(HY000)Incorrect string value: .....
也即在mysql-5.0.41-win32_178中,若編碼為latin1時,它不讓我們直接插入中文資料,但不知為何在mysql-5.0.51a-win32卻可以,這是個疑問,有知人士可以給出解答,在這先謝了。
java 連結mysql資料庫以及亂碼