2010年8月22日星期日

JAVA开发二三事(续一)

dom4j 写入 xml 文件汉字乱码的问题

1、代码:
XMLWriter xmlWriter = new XMLWriter(new java.io.FileWriter(path));

2、问题:
在集成开发环境下启动的程序,写入文件,汉字确实是utf-8,不乱码;但是在console控制台下启动的独立运行,汉字就是乱码了。

3、解决的方法:
代码改成:
XMLWriter xmlWriter = new XMLWriter(new java.io.FileOutputStream());
问题解决。

4、原因:
java.io.FileWriter 没有实现 ENCODING 相关的接口(该说法来源于网络),所以在集成开发环境都是utf-8的情况下,可以输出utf-8,但是在console控制台下,是GBK环境,写入的就不是utf-8了。即使设置了也不起作用。
java.io.FileOutputStream 是二进制的流,实现了相关接口,所以没有问题。

2010年8月15日星期日

JAVA开发二三事

最近做了一个简单的JAVA图形界面程序,给一个同事的项目用。网上搜索解决了不少问题,现在总结一下,做个存档。

一、JAVA Sybase数据库连接:
1、JDBC连接字符串:
String url = "jdbc:sybase:Tds:" + machine + ":" + port + "/" + dbname + "?charset=cp936";
properties = new Properties();
properties.put("user", userID);
properties.put("password", password);
其中:machine是数据库服务器的IP地址。不能是机器名、不能是Localhost、不能是127.0.0.1。我的操作系统是Win7,除了静态IP地址,其他的都连接不上,这个折腾的时间最多。还有端口port是5000,不是文档上说的那个43XX。dbname是数据库的名字。加上 "?charset=cp936"参数是指明了字符集,为了返回结果中的中文正常显示,否是是乱码。默认的userID是sa,password是空字符串。

2、打开连接:
Class.forName("com.sybase.jdbc3.jdbc.SybDriver").newInstance();
connection1 = DriverManager.getConnection(url, properties);

3、数据库读取操作以及结果集循环:
Statement selectStatement;
ResultSet resultSet;
String kmdm;
String mc;
try {
if (connection1 != null) {
selectStatement = connection1.createStatement();
resultSet = selectStatement.executeQuery("SELECT KMDM, "
+ " MC "
+ " FROM KM" + cyear
+ " WHERE 1=1 ");
while (resultSet.next()) {
kmdm = resultSet.getString("kmdm");
mc = resultSet.getString("mc");
jTextArea1.append(kmdm + " - '" + mc + "'\n");
} catch (Exception exception) {
jTextArea1.append("Error: " + exception.getMessage());
}

二、JAVA Sybase Spring JdbcTemplate数据库连接:
1、连接字符串
String url = "jdbc:sybase:Tds:" + machine + ":" + port + "/" + dbname + "?charset=cp936";
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.sybase.jdbc3.jdbc.SybDriver");
dataSource.setUrl(url);
dataSource.setUsername(userID);
dataSource.setPassword(password);
其中:dataSource.setUsername和dataSource.setPassword不能省略。其实连接字符串中的url里面也能写上用户名和密码,但是会报错,一定要写。
2、查询一:
JdbcTemplate jt = new JdbcTemplate();
jt.setDataSource(dataSource);
String qry;
qry = "select count(MAX(SXH)) from BAK_PZ" + cyear + " GROUP BY YUE,PZLB,PZBH";
pzcount = jt.queryForInt(qry);
其中:queryForInt能直接得到整数型的返回值;
3、查询二:
qry = "SELECT A.* FROM BAK_PZ" + cyear + " A JOIN "
+ " (SELECT MAX(SXH) AS SXH,YUE,PZLB,PZBH FROM BAK_PZ" + cyear
+ " GROUP BY YUE,PZLB,PZBH) B "
+ " ON A.SXH =B.SXH AND A.YUE=B.YUE AND A.PZLB=B.PZLB AND A.PZBH=B.PZBH "
+ " ORDER BY A.YUE,A.PZLB,A.PZBH ";

List rows = jt.queryForList(qry);

Iterator it = rows.iterator();
String shrNull;
int tmpi = 0;
while (it.hasNext()) {
Map userMap = (Map) it.next();
shrNull = userMap.get("SHR") == null ? "" : userMap.get("SHR").toString().trim();
其中:queryForList 能直接把返回结果集组装成一个list,每个list里面是一个个的map,存放的是字段和对应的值,遍历、使用都非常方便。唯一的缺点是字段的值被装箱成Object了,一是要自己类型转换;二是内存消耗很大。方便飞副作用就是内存占用上升。

三、dom4j的使用(XML的生成、写入文件)
1、创建xml跟节点:
Document doc = null;
Element root = null;
doc = DocumentHelper.createDocument();
root = DocumentHelper.createElement("ufinterface");
doc.setRootElement(root);

2、给某个节点添加属性:
root.addAttribute("roottag", "voucher");

3、增加子节点
Element voucherElem = root.addElement("voucher");
voucherElem.addAttribute("id");
或者直接连续增加:
voucher_head.addElement("fiscal_year").addText(cyear);

4、DOM XML写入文件:
OutputFormat outFmt = OutputFormat.createPrettyPrint();
outFmt.setEncoding("UTF-8");
outFmt.setIndent(" ");//设置缩进
outFmt.setNewlines(true);//让xml换行,方便查看
XMLWriter xmlWriter = new XMLWriter(new java.io.FileWriter("c:\\凭证_" + dbname +pk_corp + "公司" + cyear + "年.xml"), outFmt);
xmlWriter.write(doc);
xmlWriter.close();
其中:Encoding设置为UTF-8能保证不乱码。缩进和换行是为了后续调试xml方便。为了减少体积可以不加。

四、用Netbeans来写GUI 图形界面程序太爽了,简直就是VB、C#图形程序的开发方式,拖拉控件、设置布局、写事件响应代码、挂接。很高效。当然,这个是调用的Netbeans自带的Swing开发框架。您老要是觉得不地道,自己整Swing或者AWT都行。Eclipse里面也可以自己去弄响应的框架。

五、JAVA 程序的打包发行。偷懒的也是最简单的做法,把编译生成的jar和自己加工过的jdk一起压缩发给客户。就40MB。然后写个简单的批处理文件,如下调用:
.\jdk1.6.0_20L\jre\bin\java -jar .\DesktopApplication1\dist\DesktopApplication1.jar
看到了吗,我直接把整个Netbeans项目文件夹都给客户了。顶多删除源码。jdk就是安装之后的1.6.0.20版,自己删除了里面带的源码、例子等等不需要的做了精简。

六、想到再说。吃饭了。