2008年2月1日
CJDBC官网http://c-jdbc.ow2.org/
cjdbc与hibernate的整合
Configuring C-JDBC with Hibernate
C-JDBC just has to be defined as any JDBC driver in Hibernate, leaving the syntax set to the proper database. Here is a configuration example to use Hibernate with a C-JDBC cluster made of Sybase backends:
## C-JDBC
hibernate.dialect net.sf.hibernate.dialect.SybaseDialect
hibernate.connection.driver_class org.objectweb.cjdbc.driver.Driver
hibernate.connection.username user
hibernate.connection.password pass
hibernate.connection.url jdbc:cjdbc://localhost:25322/test
转自:http://lzj0470.javaeye.com/blog/445348
一、前言 |
cjdbc ( http://c-jdbc.objectweb.org/ ) 是一个open source的数据库集群中间件,任何基于jdbc的应用都可以通过它透明地访问数据库集群,它可以进行各个节点之间的数据复制,并且可以实现各个节点的查询负载均衡。通过这样的软件,偶们可以方便的实现RAIDb - Redundant Array of Inexpensive Database 廉价数据库冗余阵列。
大型应用随着用户量访问越来越大,增加数据库存储和做好数据库冗余可以增加系统的可靠性和性能。
下面利用cjdbc,把两台对等的 Mysql 做 RAIDb,本文假定你已经搭建好两台对等的 Mysql环境并建好一个需要做集群冗余的数据库 clusterdb。 |
|
二、配置环境 |
Mysql: 5.0.19, 并使用 InnoDB 作为 Mysql 引擎
C-jdbc: 2.0.2
Jdk: 1.5 |
|
三、选择合适的 C-JDBC RAIDb 机制 |
cjdbc有几种RAIDb的机制可以选择,如RAIDb-0,RAIDb-1等等,可以根据不同的情况选择不同的RAIDb的机制。各种 RAIDb的机制详情请查看 cjdbc 的文档和 Demo。
RAIDb-1有如下功能:
完全镜像处理机制,每个节点上都有完整的数据库结构,这种方式提供了最好的容错处理,并且通过设置合理的Loading Balance策略,可以带来查询性能相当好的提高。但是由于对于任何的写操作(create/update/delete),需要在各个节点上进行传播复制,写操作就会比原来慢一些了,如下图:
这里选择 RAIDb-1 做为 cjdbc RAIDb 机制。
|
|
四、给两台对等的 Mysql 建表,假设两台 Mysql 的IP分别是 192.168.0.2和192.168.0.3 |
bash> mysql -h192.168.0.2 -uroot
bash> use clusterdb
bash> create table user (id int(3) not null auto_increment primary key, name char(50) not null) engine innodb;
bash> exit;
bash> mysql -h192.168.0.3 -uroot
bash> use clusterdb
bash> create table user (id int(3) not null auto_increment primary key, name char(50) not null) engine innodb;
bash> exit; |
|
五、在 Linux 下安装 C-JDBC Controller |
bash> mkdir -p /usr/local/c-jdbc
bash> cd /usr/local/c-jdbc
bash> tar xvfz c-jdbc-2.0.2-bin.tar.gz
bash> export CJDBC_HOME=/usr/local/c-jdbc
|
|
六、把 Mysql JDBC Driver 放到 C-JDBC Controller 中来 |
这里我们使用 mysql-connector-java-3.1.12-bin.jar 驱动程序,把它放到
/usr/local/c-jdbc/drivers 中
|
|
七、配置 C-JDBC Controller |
1、在 /usr/local/c-jdbc/config/virtualdatabase 目录中创建 虚拟数据库配置文件,并把它命名为 mysql-raidb1-distribution.xml,内容如下:
<?xml version="1.0" encoding="UTF8"?>
<!DOCTYPE C-JDBC PUBLIC "-//ObjectWeb//DTD C-JDBC 2.0.2//EN" "http://c-jdbc.objectweb.org/dtds/c-jdbc-2.0.2.dtd">
<C-JDBC>
<VirtualDatabase name="myDB">
<Distribution>
</Distribution>
<AuthenticationManager>
<Admin>
<User username="admin" password="c-jdbc"/>
</Admin>
<VirtualUsers>
<VirtualLogin vLogin="boss" vPassword="boss"/>
</VirtualUsers>
</AuthenticationManager>
<DatabaseBackend name="mysqlNode211" driver="org.gjt.mm.mysql.Driver" url="jdbc:mysql://192.168.0.2/clusterdb" connectionTestStatement="select 1">
<ConnectionManager vLogin="boss" rLogin="boss_user" rPassword="123456">
<VariablePoolConnectionManager initPoolSize="10" minPoolSize="10" maxPoolSize="50" idleTimeout="30" waitTimeout="10"/>
</ConnectionManager>
</DatabaseBackend>
<DatabaseBackend name="mysqlNode213" driver="org.gjt.mm.mysql.Driver" url="jdbc:mysql://192.168.0.3/clusterdb" connectionTestStatement="select 1">
<ConnectionManager vLogin="boss" rLogin="boss_user" rPassword="123456">
<VariablePoolConnectionManager initPoolSize="10" minPoolSize="10" maxPoolSize="50" idleTimeout="30" waitTimeout="10"/>
</ConnectionManager>
</DatabaseBackend>
<RequestManager>
<RequestScheduler>
<RAIDb-1Scheduler level="passThrough"/>
</RequestScheduler>
<LoadBalancer>
<RAIDb-1>
<WaitForCompletion policy="first"/>
<RAIDb-1-LeastPendingRequestsFirst/>
</RAIDb-1>
</LoadBalancer>
</RequestManager>
</VirtualDatabase>
</C-JDBC>
|
2、在 /usr/local/c-jdbc/config/controller 目录中创建 C-JDBC controller 配置文件,并把它命名为 uud-controller-distributed.xml,内容如下:
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE C-JDBC-CONTROLLER PUBLIC "-//ObjectWeb//DTD C-JDBC-CONTROLLER 2.0.2//EN" "http://c-jdbc.objectweb.org/dtds/c-jdbc-controller-2.0.2.dtd">
<C-JDBC-CONTROLLER>
<Controller port="25323">
<JmxSettings>
<RmiJmxAdaptor port="1091"/>
</JmxSettings>
<VirtualDatabase configFile="mysql-raidb1-distribution.xml" virtualDatabaseName="myDB" autoEnableBackends="true"/>
</Controller>
</C-JDBC-CONTROLLER>
|
3、在 /usr/local/c-jdbc/config/demo 目录中创建启动 C-JDBC controller sh,并把它命名为 uud-distributed-raidb1-controller.sh,内容如下:
#!/bin/sh
export CJDBC_HOME=/usr/local/c-jdbc
export JAVA_HOME=/opt/jdk1.5
cd $CJDBC_HOME/bin
echo "Waiting for mysql servers to finish start up"
echo "Starting Controller"
./controller.sh -f ../config/controller/uud-controller-distributed.xml &
|
|
|
八、启动 C-JDBC Controller |
bash> cd /usr/local/c-jdbc/demo
bash> chmod u+rwx uud-distributed-raidb1-controller.sh
bash> ./uud-distributed-raidb1-controller.sh &
如果启动正常,显示的信息如下:
Waiting for mysql servers to finish start up
Starting Controller
2006-04-20 10:32:21,126 INFO controller.core.Controller C-JDBC controller (2.0.2)
2006-04-20 10:32:21,189 INFO controller.core.Controller Loading configuration file: ../config/controller/uud-controller-distributed.xml
2006-04-20 10:32:21,278 INFO controller.core.Controller JMX is enabled
2006-04-20 10:32:21,308 INFO controller.core.Controller Starting JMX server on host: 127.0.0.1
2006-04-20 10:32:21,674 INFO backend.DatabaseBackend.mysqlNode211 Adding connection manager for virtual user "boss"
2006-04-20 10:32:21,749 INFO backend.DatabaseBackend.mysqlNode213 Adding connection manager for virtual user "boss"
2006-04-20 10:32:21,809 INFO controller.RequestManager.myDB Request manager will parse requests with the following granularity: NO_PARSING
2006-04-20 10:32:21,814 INFO controller.virtualdatabase.myDB Configuring jgroups using: file:/usr/local/c-jdbc/config/jgroups.xml
-------------------------------------------------------
GMS: address is 127.0.0.1:32773
-------------------------------------------------------
2006-04-20 10:32:26,476 INFO controller.virtualdatabase.myDB Group myDB connected to /127.0.0.1:32773[/127.0.0.1:32773]
2006-04-20 10:32:26,476 INFO controller.virtualdatabase.myDB First controller in group myDB
2006-04-20 10:32:26,477 WARN controller.virtualdatabase.myDB No recovery log has been configured, enabling backend without checkpoint.
[1]+ Done ./uud-distributed-raidb1-controller.sh
|
|
|
八、编写 C-JDBC 客户端程序 |
1、把 C-JDBC Drivers(/usr/local/c-jdbc/drivers/c-jdbc-driver.jar) 放置到 CLASSPATH 中
2、编写插入 10 条数据到 Mysql 中,程序如下:
/**
* @author 胡荣华
* @Company 世纪龙 21cn
*/
package com.cjdbc.test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.DriverManager;
/**
*
*/
public class GenerateSampleData {
public void generate() {
Connection conn = null;
PreparedStatement pstmt = null;
try {
// 这是 c-jdbc drivers 的 Drivers class,注意不是 mysql 的 Drivers class
Class.forName("org.objectweb.cjdbc.driver.Driver").newInstance();
// 192.168.0.1 是 cjdbc controller 所在的 ip
// myDB 是在 文件 mysql-raidb1-distribution.xml 里定义的 <VirtualDatabase name="myDB">
// user=boss&password=boss 是在 文件 mysql-raidb1-distribution.xml 里定义的
// <VirtualUsers>
// <VirtualLogin vLogin="boss" vPassword="boss"/>
// </VirtualUsers>
String url = "jdbc:cjdbc://192.168.0.1:25323/myDB?user=boss&password=boss";
conn = DriverManager.getConnection(url);
try{
conn.setAutoCommit(false);
pstmt = conn.prepareStatement("insert into user values ('', ?)");
int numOfTestRecords = 10;
System.out.println("Update Record Start.");
for (int i=0;i<numOfTestRecords;i++) {
String newkey = i + "-" + i;
pstmt.setString(1, "hua_" + newkey);
pstmt.executeUpdate();
}
conn.commit();
System.out.println("Update Record Success.");
}
catch(Exception ex){
conn.rollback();
ex.printStackTrace();
}
finally{
try {
if( pstmt != null )
pstmt.close();
if( conn != null)
conn.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
GenerateSampleData g = new GenerateSampleData();
g.generate();
}
}
|
3、程序执行完毕后,分别到 Mysql Node 192.168.0.2 和 192.168.0.3 查询,看看是否已同步了数据,如果两个 Mysql Node 都有相同的数据,说明 C-JDBC 环境搭建成功。
|
|
posted @
2010-03-25 20:23 Dong 阅读(394) |
评论 (0) |
编辑 收藏
最近做了一个日志管理系统
个人觉得采用了一套非常非常创新或者变态的开发方式,就像题目说的那样,使用web的方法开发桌面应用程序,当然所有的技术都是基于java的。
总结一下在整个项目中使用到的技术
1、底层服务器的开发socket通信、http报文解析、反射机制(这些技术其实就是开发了一款小型的服务器,让我们的web代码能够在本地运行起来,之所以选择自己开发服务器的原因是,tomcat对于我们这个小桌面程序来说还是太大了点,如果作为桌面启动,用户不可能等待程序启动这么长的时间,我给这个服务器起了个名字叫做jnet)
2、SWT,包括的浏览器控件和窗口等。
3、使用installanywhere来打包程序,方便发布
4、前台展现数据使用了ext2.2
5、扩展自己开发的服务器jnet,开发出自己的“action”,应该来说还是符合MVC的
数据库使用的是access,采用jdbc的方式访问,你知道,如果在桌面软件上使用hibernate...
好了,不说废话
先贴出成品的效果图
1、桌面图标
2、登录界面
3、登录效果图
4、主界面
是不是觉得还不错呢?JAVA也可以扬眉吐气开发出这样的桌面系统,可惜的是因为使用到了SWT,所以整个项目并不能跨平台,放到linux系统下去运行。
好了先理一理,发一张项目的原理图
看图说话,我们整个项目的构架,就是这个样子的,采用SWT封装了IE作为前台展现,后台使用自己开发的服务器作为后台来处理数据,中间数据通信方式当然就只能是http了
所以中心思想就是,我开发了个服务器,这个服务器能够让用户扩展自己的类,自己的方法,然后用户就可以根据自己的需要来书写自己的系统,最最最重要的就是,让我们这些写惯了J2EE的人能够使用已经形成的思维来编写桌面系统,我们可以不需要再去学swing和swt,可以使用html的方式来做前台的布局,因为老实说我每次写桌面程序的时候,总会把代码弄得一团糟,在web系统上容易规规矩矩的写出分层的代码,桌面系统...布局就让我头大(我的意思是当你跑出去接私活干的时候,不用再学一套东西,呵呵)。
好了,这个帖子只是一个简单的介绍,整个系统具体的实现方式,会在后续的帖子中一步步解析,大家有什么意见或者建议可以给我留言,谢谢!
posted @
2009-03-19 15:16 Dong 阅读(4351) |
评论 (23) |
编辑 收藏
开发的时候有时候会碰到这样的情况,我们在写程序的时候并不知道需要调用某个对象的哪个方法,只有程序运行后,我们才能够知道。或许我们需要根据客户端传过来的某个String参数的值来判断我们应该执行哪个方法。在这种情况下JAVA的反射执行就可以帮上忙了。下面是我做的一个简单的测试代码,提供给大家做个参考。
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/** *//**
* @author Dong
* 测试JAVA reflect机制
*/
public class TestRef{
/** *//**
* @param args
*/
public static void main(String[] args){
TestBean test = new TestBean();
Method[] methods = test.getClass().getMethods();
test.setAbc("---");
for(int i=0;i<methods.length;i++){
if(methods[i].getName().equalsIgnoreCase("getabc")){
try {
System.out.println(methods[i].invoke(test));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
posted @
2008-06-05 16:36 Dong 阅读(10165) |
评论 (7) |
编辑 收藏
(String[])ArrayList.toArray(new String[0]);
posted @
2008-06-02 11:25 Dong 阅读(791) |
评论 (0) |
编辑 收藏
XML里是无法直接正常输出&等特殊字符的,可用&转义表示!
posted @
2008-05-21 09:03 Dong 阅读(473) |
评论 (0) |
编辑 收藏
1、数字格式化
<fmt:formatNumber value="33.33333" pattern="#.0"></fmt:formatNumber>-->输出33.3
pattern中符号的约束规定
0 一个数位
# 一个数位,前导零和追尾零不显示
. 小数点分割位置
, 组分隔符的位置
- 负数前缀
% 用100乘,并显示百分号
其他任何符号 在输出字符串中包括指定符号
2、日期格式化
<fmt:formatDate value="${vo.lateCompleteDate}" type="both" pattern="yy-MM-dd"/>
posted @
2008-05-20 09:29 Dong 阅读(1754) |
评论 (0) |
编辑 收藏
HashMap<String,String> testMap = new HashMap<String,String>();
for (Map.Entry<String, String> entry : testMap .entrySet()) {
entry.getKey();
entry.getValue();
}
posted @
2008-05-19 17:09 Dong 阅读(312) |
评论 (0) |
编辑 收藏
ApplicationContext ctx = new ClassPathXmlApplicationContext("application-config.xml");
Map<String,String> bureauMap = ((DictionaryService)ctx.getBean("dictionaryService")).getBureauMap();
posted @
2008-05-19 16:45 Dong 阅读(259) |
评论 (0) |
编辑 收藏
今天在调试一个Servlet程序的时候,报了以下错误!
java.lang.IllegalStateException: Cannot forward after response has been committed
根据字面理解的话,意识是在response已经提交后程序不能再一次的跳转!
研究代码以后发现,是因为前面已经执行过一次request.request.getRequestDispatcher().forward()
但是后面的request.request.getRequestDispatcher().forward()依然被执行到了!
那么很有理由相信request.request.getRequestDispatcher().forward()跳转本身是不会返回什么,也不会终止程序体的执行!
程序体后面该执行的还是会执行!
posted @
2008-04-17 10:28 Dong 阅读(7736) |
评论 (1) |
编辑 收藏
<Resource name="jdbc/dong" auth="Container" type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/dong">
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>100</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>30</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>5000</value>
</parameter>
<parameter>
<name>username</name>
<value>root</value>
</parameter>
<parameter>
<name>password</name>
<value>colorful</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>org.gjt.mm.mysql.Driver</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:mysql://localhost:3306/dong</value>
</parameter>
</ResourceParams>
使用如上配置的时候一直报这个
org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'错误
在网络上寻觅后发现是因为Tomcat版本引起的,改成如下问题就消失了
<Resource
name="jdbc/dong"
type="javax.sql.DataSource"
password="colorful"
driverClassName="org.gjt.mm.mysql.Driver"
maxIdle="2"
maxWait="5000"
username="root"
url="jdbc:mysql://localhost:3306/dong"
maxActive="4"/>
posted @
2008-02-24 13:47 Dong 阅读(2682) |
评论 (1) |
编辑 收藏
1、 解决Action过多问题
通过DispatchAction的方式
建立一个继承自DispatchAction的Action
此类Action允许我们在表单中带有参数,根据参数执行Action中的不同方法,以此实现Action的多用
步骤
① 建立一个继承自DispatchAction的Action规定方法名称
② 在表单页面中添加一个隐藏域值,假设为codi value=”insert”
③ 在Struts-config.xml的相应Form中action项目中设置parameter参数值为codi
那么当表单提交的时候,Action中的insert()方法就会被执行,可以通过改隐藏域中的值的方式来改变Action要执行的方法
2、 解决ActionForm过多的问题
通过动态ActionForm的方式,即DynaActionForm
步骤
① 在Struts-config.xml
<form-beans>
<form-bean name=”abcForm” type=”org.apache.struts.action.DynaActionForm”>
<form-property name=”userid” type=”java.long.String”></form-property>
</form-bean>
</form-beans>
② 在Struts-config.xml
更改相应的action中的attribute和name为abcForm
这样就配置好了一个动态的ActionForm
3、 解决动态ActionForm的验证问题
通过动态验证ActonForm的方式,即DynaValidatorForm
步骤
① 在Struts-config.xml
同2的第一步,但是type需要改成org.apache.struts.action.DynaValidatorForm
② 配置一个validation.xml文件
<form-validation>
<formset>
<form name="abcForm">
<field property="userid" depends="required">
<arg key="err.userid" resource="true"/>
</field>
</form>
</formset>
</form-validation>
③ 在Struts资源文件中配置err.userid、以及errors.required
④ 在Struts-config.xml配置相应的action,添加validate=”true”添加验证支持
⑤ 添加struts Plugin插件
设置plugin class为org.apache.struts.validator.ValidatorPlugIn
添加propertys
Propertyà pathnames
Valueà /WEB-INF/validator-rules.xml,/WEB-INF/validation.xml
这样一个验证框架就配置好了!
posted @
2008-02-12 13:47 Dong 阅读(3473) |
评论 (6) |
编辑 收藏
读Excel:
Workbook workbook = null;
try
{
workbook = Workbook.getWorkbook(new File(path));
}
catch(Exception e)
{
System.out.println(e);
}
Sheet sheet = workbook.getSheet(0);
Cell cell=sheet.getCell(i,j);//读第i列,第j行表格的值
System.out.println(cell.getContents());
对于循环读出可以使用
sheet.getRows();方法得到行数
sheet.getColumns();方法得到列数
写Excel:
Workbook wb = Workbook.getWorkbook(new File(path));
WritableCellFormat wcf = new WritableCellFormat();
book = Workbook.createWorkbook(new File(path, wb);
sheet = book.getSheet(0);
jxl.write.Label name = new jxl.write.Label(i,j,"abc",wcf);//在第i列,第j行写入"abc"值,风格为wcf,如果写入的是数字则使用jxl.write.Number
sheet.addCell(name);
try
{
book.write();
book.close();
}
catch(WriteException e){}
catch(IOException e){}
单元格风格:
设置边框—
WritableCellFormat wcf = new WritableCellFormat();
wcf.setVerticalAlignment(VerticalAlignment.CENTRE);
wcf.setBorder(Border.RIGHT,BorderLineStyle.THIN);
wcf.setBorder(Border.LEFT,BorderLineStyle.THIN);
wcf.setBorder(Border.BOTTOM,BorderLineStyle.THIN);
合并单元格-
sheet.mergeCells(0,1,0,2)
合并(0,1)、(0,2)两个单元格
设置字体-
WritableFont wf = new WritableFont(WritableFont.ARIAL,12, WritableFont.BOLD, false);
WritableCellFormat wcf = new WritableCellFormat(wf);
以及其它各种单元格样式,如设置背景颜色
都可以通过设置WritableCellFormat来设置
还有一点需要说明一下,JXL组件对于公式的支持似乎比Apache的poi好
posted @
2008-02-01 16:16 Dong 阅读(4975) |
评论 (2) |
编辑 收藏