前言:一提起数据库偶就心血来潮温故了下以前的东西。记得以前就被一个数据库写入读取时候遇到的中文字节编码的问题给懵了半天,后来以我三天打鱼两天晒网的生活习惯,我就放那里没理他了,反正也没什么要我急于解决的。最近要弄那个密码和ID的验证,必须用到数据库了这次,本来也是,不准备放用户名的,但是后来玩着玩着感觉这样全输入英文的太不爽了,当然就要解决这个问题来了,不过稍微看了下,基本程序能用了,就是老要转换编码很是麻烦。
这个是临时我没事做了个测试用的JFrame,老单独设置蛮麻烦的,于是就独立一个出来,以后测试都用它就行了,呵呵。
/**/
/*
* 一个窗口的公共类
*
*/

import java.awt.
*
;
import javax.swing.
*
;
import java.awt.
event
.
*
;


public
class
SosoFrame extends JFrame
...
{
private JTextArea jta = null;
private JTextField jtf = null;
private JButton jbOK = null;
private JButton jbCancel = null;

public SosoFrame(String name) ...{
super(name);
jbOK = new JButton("确定");
jbCancel = new JButton("取消");
JPanel jpSouth = new JPanel(new FlowLayout());
jta = new JTextArea();
jta.setRows (5);
jta.setEditable(false);
jtf = new JTextField(20);
jpSouth.add(jtf);
jpSouth.add(jbOK);
jpSouth.add(jbCancel);
JScrollPane jsp = new JScrollPane(jta);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(new JLabel("Soso's Frame"), BorderLayout.NORTH);
this.add(jsp, BorderLayout.CENTER);
this.add(jpSouth, BorderLayout.SOUTH);
}

public void display(boolean show) ...{
this.pack();

if (show) ...{
this.setVisible(true);
}

else ...{
this.setVisible(false);
}
}

public JTextField getTextField () ...{
return jtf;
}

public JTextArea getTextArea () ...{
return jta;
}

public JButton getButtons (int c) ...{

switch (c) ...{
case 1:
return this.jbOK;
case 2:
return this.jbCancel;
}
return null;
}

public void jtaAppend (String content) ...{
jta.append(content + " ");
}
}
下面是个数据库的连接显示文件:
/**/
/*
* MySql数据库的中文输入问题
*
*/
import
java.sql.
*
;
import
java.io.
*
;
import
java.awt.event.
*
;
import
javax.swing.
*
;


class
MySQLDB
...
{

public static Connection getConnection() throws SQLException, java.lang.ClassNotFoundException ...{
// 数据库名称
String dbname = "test";
//取得连接的url
String url = "jdbc:mysql://localhost:3306/" + dbname;
//加载MySQL的jdbc驱动
Class.forName("org.gjt.mm.mysql.Driver");
//使用能访问MySQL数据库的用户名root
String userName = "root";
//使用口令
String password = "admin";
//打开数据库连接
Connection con = DriverManager.getConnection(url, userName, password);
return con;
}

public static void main(String[] args) ...{
final SosoFrame frame = new SosoFrame("数据库测试");
frame.jtaAppend("数据库测试,这里是显示区域");
final JButton jbCancel = frame.getButtons(2);
final JButton jbOK = frame.getButtons(1);
jbCancel.addActionListener( new ActionListener ()

...{

public void actionPerformed(ActionEvent e) ...{
System.exit(0);
}
}
);
jbOK.addActionListener( new ActionListener ()

...{

public void actionPerformed(ActionEvent e) ...{
// System.exit(0);
// 读取数据库!

if (!frame.getTextField ().getText ().trim ().equals ("")) ...{
}
}
}
);
frame.display(true);

try ...{
//BufferedReader buffReader = null;
Connection con = getConnection();
Statement stmt = con.createStatement();
String sql = new String("insert into test(name) values('丁丁')");
sql = new String(sql.getBytes ("GBK"), "8859_1");
stmt.executeUpdate (sql);
ResultSet rs = stmt.executeQuery("select * from test");

while(rs.next()) ...{
int id = rs.getInt(1);
String name = new String(rs.getString(2).getBytes ("8859_1"), "GBK");
frame.jtaAppend(id + " " + name);
}
rs.close();
stmt.close();
con.close();
// buffReader.close();
}

catch (Exception e) ...{
e.printStackTrace();
}
}
}
做了些基本的,也就插插读读的。读出来的时候一定要以8859_1的格式读入,并且转换成GBK的,当然如果是中文操作系统就默认是GBK的,写入的时候要指定写入流为8859_1的,不然是乱码,也就只能麻烦自己手一点了,哎~苦命那……
昨天太急匆匆了,忘记说了,我用的是MYSQL4.1,装好后是用utf8编码格式的。
后参考了个很爽的地方:http://imysql.cn/,里面东西蛮全蛮多的,呵呵,关心MySQL的朋友不妨去看看,会有很大帮助的。说实话,最近看了好多关于编码集的文章,脑子里面着实有点乱!!
经过不容易的修改,终于把最后的方案定下来了(只是这个测试用的方案,嘿嘿)
/**/
/*
* MySql数据库的中文输入问题
*
*/
import
java.sql.
*
;
import
java.io.
*
;
import
java.awt.event.
*
;
import
javax.swing.
*
;


class
MySQLDB
...
{

public static Connection getConnection() throws SQLException, java.lang.ClassNotFoundException ...{
// 数据库名称
String dbname = "latin";
//取得连接的url
String url = "jdbc:mysql://localhost:3306/" + dbname;
//加载MySQL的jdbc驱动
Class.forName("org.gjt.mm.mysql.Driver");
//使用能访问MySQL数据库的用户名root
String userName = "root";
//使用口令
String password = "admin";
//打开数据库连接
Connection con = DriverManager.getConnection(url, userName, password);
return con;
}

public static void execute(String sql) ...{

try ...{
Connection con = getConnection();
Statement stmt = con.createStatement();
String sqls = new String(sql.getBytes ("GBK"), "ISO-8859-1");
stmt.executeUpdate (sqls);
stmt.close ();
con.close ();
}

catch (Exception e) ...{
e.printStackTrace();
}
}

public static void query(String sql, SosoFrame frame) ...{

try ...{
Connection con = getConnection();
Statement stmt = con.createStatement();
sql = new String (sql.getBytes ("GBK"), "ISO-8859-1");
ResultSet rs = stmt.executeQuery(sql);

while(rs.next()) ...{
int id = rs.getInt(1);
String name = new String(rs.getString(2).getBytes ("ISO-8859-1"), "GBK");
frame.jtaAppend(id + " " + name);
}
rs.close ();
stmt.close ();
con.close ();
}

catch (Exception e) ...{
e.printStackTrace ();
}
}

public static void main(String[] args) ...{
final SosoFrame frame = new SosoFrame("数据库测试");
frame.jtaAppend("数据库测试,这里是显示区域");
final JButton jbCancel = frame.getButtons(2);
final JButton jbOK = frame.getButtons(1);
jbCancel.addActionListener( new ActionListener ()

...{

public void actionPerformed(ActionEvent e) ...{
frame.getTextArea ().setText ("");
query (frame.getTextField ().getText ().trim (), frame);
}
}
);
jbOK.addActionListener( new ActionListener ()

...{

public void actionPerformed(ActionEvent e) ...{
// System.exit(0);
// 执行数据库!

if (!frame.getTextField ().getText ().trim ().equals ("")) ...{
execute (frame.getTextField ().getText ().trim ());
frame.getTextField ().setText ("");
}
}
}
);
frame.display(true);
}
}
还是需要配合前面的那个SosoFrame的类来实现的。查询要按后面的查询按钮,而其他的对于数据库的增减或更新操作都是按执行按钮的。而SQL语句是通过下面的JTextField来输入的,只做了个空的检查而已,自己用么是吧,不会神经到乱输东西进去的,呵呵。把前面的那个SosoFrame的两个按钮文字改成“执行”和“查询”就可以了,放到一个目录下编译后直接执行MySQLDB就行了。
表名为:imuser。两条数据都是数据库里面的,中文读写正确,插入也正确,圆满……(这个是基于latin1字符集的中文,是后来为了测试改了源代码执行的,前面的基于UTF8的完全和这个一样,没问题!)
下面来说下MySql的问题。字符集如果为了存放多种语言或者说是为了可移植性,那么设置成utf8的就圆满了,当然,就现在来说是圆满了,但是使用的时候还是会碰到许多的问题的。当然,那是后来用起来再碰到了,我这里就不多说了,因为都有相应的解决办法的。后来看imysql.cn上面说的,如果你是存放gb2312的话,直接把字符集改成latin1就可以了,而且可以在命令行中输入带中文的字符存储,也就是说你输入的东西不用转字符集了,本来你字符集没设置好,在mysql命令行下输入insert命令,如果全是E文的还好,如果有中文数据,那插入表后你读出来就是问号了。设置latin1就可以了,而且我测试过,可以读取的。对于数据库设置字符集最好和表的字符集一致化,不然弄了这边忘那边的,很容易搞错的。至于其他具体的就请看imysql.cn上的吧。