这一篇说说动态创建数据库方案二,利用jboss提供的api进行程序代码的开发,实现动态添加数据源。在jboss不重启的情况下,在jboss的standalone.xml配置文件中动态添加一套数据源节点,同时在persistence.xml配置文件中动态添加一套与standalone.xml配置文件相匹配的的一套节点。
1.在jboss的standalone.xml配置文件中动态添加一套数据源节点
这里用一个实体类来和JBOSS里的数据源相对应保存,这样数据源就是灵活的,想创建什么样的数据源都可。
1.1数据源的实体
//与jboss中数据源相对应的一个实体对象 public class DataSourceEntity { /* * DATASOURCES.Attribute 属性设置 */ //数据源名称 private String dsName; //jndi名称 private String jdniName; //是否启用 private boolean isEnabled; //驱动名称,如:mysql\oracle private String driver; /* * DATASOURCES.Conection 连接设置 */ //连接字符串 private String connURL; //是否使用JTA private boolean useJTA; /* * DATASOURCES.Security 安全设置 */ //连接ds用户名及密码 private String username; private String password; /* * DATASOURCES.Pool 连接池设置 */ //最小最大连接池 private int minPoolSize; private int maxPoolSize; //空闲时间 private int timeout; public int getTimeout() { return timeout; } public void setTimeout(int timeout) { this.timeout = timeout; } public DataSourceEntity(){ } public DataSourceEntity(String dsName,String jdniName,boolean isEnabled,String connURL,boolean useJTA,String username,String password,int minPoolSize,int maxPoolSize){ } public String getDsName() { return dsName; } public void setDsName(String dsName) { this.dsName = dsName; } public String getJdniName() { return jdniName; } public void setJdniName(String jdniName) { this.jdniName = jdniName; } public boolean isEnabled() { return isEnabled; } public void setEnabled(boolean isEnabled) { this.isEnabled = isEnabled; } public String getDriver() { return driver; } public void setDriver(String driver) { this.driver = driver; } public String getConnURL() { return connURL; } public void setConnURL(String connURL) { this.connURL = connURL; } public boolean isUseJTA() { return useJTA; } public void setUseJTA(boolean useJTA) { this.useJTA = useJTA; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getMinPoolSize() { return minPoolSize; } public void setMinPoolSize(int minPoolSize) { this.minPoolSize = minPoolSize; } public int getMaxPoolSize() { return maxPoolSize; } public void setMaxPoolSize(int maxPoolSize) { this.maxPoolSize = maxPoolSize; } }
1.2操作standalone.xml
/** * * @Title: createDateSource * @Description: TODO(动态添加数据源) * @param @param dsEntity 设定文件 数据源实体 * @return void 返回类型 void * @throws IOException * @throws * @author cfl * @date 2015年3月13日 */ public static void createDateSource(DataSourceEntity dsEntity) throws IOException { //连接jboss进程的客户端 ModelControllerClient client = ModelControllerClient.Factory .create(InetAddress.getByName("127.0.0.1"), 9999); //操作数据源节点 ModelNode op = new ModelNode(); try { op.get("operation").set("add"); // 数据源名称 String dsname = dsEntity.getDsName(); // 在datasources下面添加数据源名称为dsname的子节点data-source op.get("address").add("subsystem", "datasources").add("data-source", dsEntity.getDsName()); // 设置jndi查找名称 op.get("jndi-name").set(dsEntity.getJdniName()); // 设置数据源类 //op.get("datasource-class").set("com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"); // 设置驱动名称 op.get("driver-name").set(dsEntity.getDriver()); op.get("use-java-context").set("true"); // 数据源连接池名称 op.get("pool-name").set(dsEntity.getDsName()); // 连接池timeout op.get("Idle Timeout").set(dsEntity.getTimeout()); op.get("jta").set(true); op.get("connection-url").set(dsEntity.getConnURL()); // 连接数据源名称 op.get("user-name").set(dsEntity.getUsername()); // 连接数据源密码 op.get("password").set(dsEntity.getPassword()); // 连接池大小 op.get("max-pool-size").set(dsEntity.getMaxPoolSize()); op.get("min-pool-size").set(dsEntity.getMinPoolSize()); //启用该数据源,默认关闭 op.get("enabled").set(true); // 执行设置 ModelNode result = client.execute(op); System.out.println("----------" + result.toString() + "---------"); } finally { client.close(); } }
2.在persistence.xml配置文件中动态添加一套与standalone.xml配置文件相匹配的的一套节点,然后格式化添加的节点。(见上一篇博客)
3.用SQL语句创建数据库。(见上一篇博客)
4.具体调用
@RequestMapping("/addJbossDatasource") public void AddJbossDatasource(HttpServletRequest request) throws Exception { DataSourceEntity dsEntity = new DataSourceEntity(); // String name="xiaozuo_dynamick0"; String name= request.getParameter("name"); Dom4jUtil dom4jUtil= new Dom4jUtil(); Dom4jUtilFormat dom4jUtilFormat = new Dom4jUtilFormat(); // 连接字符串 dsEntity.setConnURL("jdbc:mysql://192.168.24.46:3306/"+name+"?useUnicode=true&characterEncoding=UTF-8"); // 数据源名称 dsEntity.setDsName(name); dsEntity.setDriver("mysql"); dsEntity.setEnabled(true); dsEntity.setJdniName("java:jboss/datasources/" + dsEntity.getDsName()); dsEntity.setMaxPoolSize(20); dsEntity.setMinPoolSize(5); dsEntity.setUseJTA(true); dsEntity.setUsername("root"); dsEntity.setPassword("root"); dsEntity.setTimeout(3600); try { //创建jboss中的数据源 createDateSource(dsEntity); //创建persistence.xml中的数据源 dom4jUtil.AddDataSourceXml(name); dom4jUtilFormat.FormatXml(); } catch (Exception e) { System.out.println(e.toString()); } }
5.需要的maven依赖
<!-- 2015年3月11日,左华蓉,动态添加数据源 --> <dependency> <groupId>org.jboss.as</groupId> <artifactId>jboss-as-controller-client</artifactId> <version>7.1.1.Final</version> </dependency> <dependency> <groupId>org.jboss.as</groupId> <artifactId>jboss-as-protocol</artifactId> <version>7.1.1.Final</version> </dependency> <dependency> <groupId>org.jboss.as</groupId> <artifactId>jboss-as-controller</artifactId> <version>7.1.1.Final</version> </dependency> <dependency> <groupId>org.jboss</groupId> <artifactId>jboss-dmr</artifactId> <version>1.1.1.Final</version> </dependency> <dependency> <groupId>org.jboss.xnio</groupId> <artifactId>xnio-api</artifactId> <version>3.0.3.GA</version> </dependency> <dependency> <groupId>org.jboss.xnio</groupId> <artifactId>xnio-nio</artifactId> <version>3.0.3.GA</version> </dependency> <dependency> <groupId>org.jboss.threads</groupId> <artifactId>jboss-threads</artifactId> <version>2.0.0.GA</version> </dependency> <dependency> <groupId>org.jboss.sasl</groupId> <artifactId>jboss-sasl</artifactId> <version>1.0.0.Final</version> </dependency> <dependency> <groupId>org.jboss.remoting</groupId> <artifactId>jboss-remoting</artifactId> <version>3.2.3.GA</version> </dependency> <dependency> <groupId>org.jboss.marshalling</groupId> <artifactId>jboss-marshalling</artifactId> <version>1.3.11.GA</version> </dependency> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6</version> </dependency>
总结,这样貌似也达到那个效果,但是通过测试,虽然他可以用JPA事务,但是不是容器管理的JPA事务,得用bean管理的JPA事务,并且远程bean调用调用不了。后来,我们觉得试试第三种方案,利用多租户来解决。多租户正在尝试中。。。。。。