前段时间让研究如何动态创建数据源,关于这个我们讨论出有两种方案,一种是将数据源放到persistence.xml文件中,然后在persistence.xml中动态添加节点,代码中根据不同的unitname创建不同的entitymanager。一种是数据源放到JBOSS里,通过JBOSS的api动态添加数据源节点,然后在persistence.xml中动态添加节点,代码中根据不同的unitname创建不同的entitymanager。
方案一:1.将在JBOSS里的数据源连接放到persistence.xml文件中
<persistence-unit name="itoo_xiaozuo3" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/> <property name="hibernate.connection.username" value="root"/> <property name="hibernate.connection.password" value="123456"/> <property name="hibernate.connection.url" value="jdbc:mysql://192.168.**.**:3306/itoo_xiaozuo3?useUnicode=true&characterEncoding=UTF-8"/> <property name="hibernate.max_fetch_depth" value="3"/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.hbm2ddl.auto" value="update"/> </properties> </persistence-unit>
2.通过dom4j在persistence.xml文件中在添加一套节点
/** * 操作dom4j创建xml数据源 * * @param name 持久化名称 数据库名称 * @throws DocumentException 异常 * @throws IOException 异常 */ public boolean AddDataSourceXml(String name) throws DocumentException, IOException{ boolean flag=false; try { String filepath = "D:/9gxpt/app/database.test/src/main/resources/META-INF/persistence.xml"; Document doc=new SAXReader().read(new File(filepath)); Element root=doc.getRootElement(); System.out.println(root); Element clazz=root.addElement("persistence-unit"); //实体单元名称 clazz.addAttribute("name", name); clazz.addAttribute("transaction-type", "RESOURCE_LOCAL"); Element provider=clazz.addElement("provider"); provider.setText("org.hibernate.ejb.HibernatePersistence"); Element properties = clazz.addElement("properties"); Element property1=properties.addElement("property"); property1.addAttribute("name", "hibernate.dialect"); property1.addAttribute("value", "org.hibernate.dialect.MySQL5Dialect"); Element property2=properties.addElement("property"); property2.addAttribute("name", "hibernate.connection.driver_class"); property2.addAttribute("value", "com.mysql.jdbc.Driver"); Element property3=properties.addElement("property"); property3.addAttribute("name", "hibernate.connection.username"); property3.addAttribute("value", "root"); Element property4=properties.addElement("property"); property4.addAttribute("name", "hibernate.connection.password"); property4.addAttribute("value", "123456"); //数据库名称 Element property5=properties.addElement("property"); property5.addAttribute("name", "hibernate.connection.url"); property5.addAttribute("value", "jdbc:mysql://192.168.24.46:3306/"+name+"?useUnicode=true&characterEncoding=UTF-8"); Element property6=properties.addElement("property"); property6.addAttribute("name", "hibernate.max_fetch_depth"); property6.addAttribute("value", "3"); Element property7=properties.addElement("property"); property7.addAttribute("name", "hibernate.show_sql"); property7.addAttribute("value", "true"); Element property8=properties.addElement("property"); property8.addAttribute("name", "hibernate.hbm2ddl.auto"); property8.addAttribute("value", "update"); XMLWriter writer = new XMLWriter(new FileWriter(filepath)); writer.write(doc); writer.close(); flag=true; } catch (Exception e) { System.out.println(e); } return flag; }
3.将添加的节点格式化,为什么有这一步呢,是因为上面添加的xml节点,jboss不重启情况下不识别,但是不管对该xml文件做任何操作之后就可以读取出来了。
public boolean FormatXml() throws DocumentException, IOException { boolean flag = false; String filename = "D:/9gxpt/app/database.test/src/main/resources/META-INF/persistence.xml"; try { SAXReader saxReader = new SAXReader(); Document document = saxReader.read(new File(filename)); XMLWriter writer = null; /** 格式化输出,类型IE浏览一样 */ OutputFormat format = OutputFormat.createPrettyPrint(); /** 指定XML编码 */ format.setEncoding("UTF-8"); writer = new XMLWriter(new FileWriter(new File(filename)), format); writer.write(document); writer.close(); /** 执行成功,需返回true */ flag = true; } catch (Exception ex) { ex.printStackTrace(); } return flag; }
4.创建数据库,切换数据库。切换数据库就是从persistence.xml文件里读取刚添加的unit单元,create一个entitymanager就行。
/** * 创建数据库 * * @param name * @return */ public boolean CreateDataBase(String name){ boolean flag=false; try { EntityManagerFactory factory=Persistence.createEntityManagerFactory(a); EntityManager em = factory.createEntityManager(); String sql="create database if not exists `"+name+"` "; em.getTransaction().begin(); Query query=em.createNativeQuery(sql); query.executeUpdate(); em.getTransaction().commit(); em.close(); System.out.println("数据库创建成功!"); flag=true; } catch (Exception e) { e.printStackTrace(); } return flag; } /** * 切换数据库 * * @param name * @return */ public boolean SwitchDataSource(String name){ boolean flag=false; try { EntityManagerFactory factory1=Persistence.createEntityManagerFactory(name); EntityManager em1 = factory1.createEntityManager(); em1.getTransaction().begin(); String sql1="create table blog_user( user_name char(15) not null check(user_name !=''),user_password char(15) not null, user_emial varchar(20) not null unique, primary key(user_name) )"; Query query1=em1.createNativeQuery(sql1); query1.executeUpdate(); em1.getTransaction().commit(); em1.close(); flag = true; } catch (Exception e) { e.printStackTrace(); } return flag; }
总结,方案一就是往persistence.xml文件里创建了一套数据库连接节点,然后用SQL语句创建数据库,接着创建一个entitymanager。虽然效果达到了,但是容器事务就不能保证了。