如何为mysqlcluster创建hibernate配置文件?

时间:2016-05-17 16:01:29

标签: mysql-cluster nhibernate-configuration

需要用于mysql集群的Hibernate配置(hibernate.cfg.xml)文件。

[Hibernate]自动生成POJO类和* .hbm.xml文件。

我可以使用以下配置访问Mysql数据库。

我还可以使用简单的JDBC连接访问 MYSQL NDB Cluster 数据库。

问题是当我使用 MYSQL NDB Cluster 数据库凭据时,我无法使用Hibernate访问数据库。

请使用Hibernate配置文件(hibernate.cfg.xml)为Connect MYSQL NDB CLuster 数据库建议任何其他配置。

我认为解决方案是 MySQL NDB集群表类型所需的新方言。 否则配置文件中的任何更改

          

   <property name="hibernate.bytecode.use_reflection_optimizer">false</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.password">HAZE@rt!f!c!aldb</property>
    <property name="hibernate.connection.pool_size">10</property>
    <property name="hibernate.connection.url">jdbc:mysql://192.168.1.187:3306/haze_videocon_v0.8</property>
    <property name="hibernate.connection.username">haze</property>
    <property name="hibernate.current_session_context_class">thread</property>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.search.autoregister_listeners">false</property>
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.validator.apply_to_ddl">false</property>
</session-factory>

1 个答案:

答案 0 :(得分:0)

必须启动并运行MySQL Cluster。为简单起见,构成群集的所有节点(进程)将与应用程序一起在同一物理主机上运行。

这些是正在使用的MySQL Cluster配置文件:

<强>的config.ini:

[ndbd default]noofreplicas=2
datadir=/home/billy/mysql/my_cluster/data

[ndbd]
hostname=localhost
id=3

[ndbd]
hostname=localhost
id=4

[ndb_mgmd]
id = 1
hostname=localhost
datadir=/home/billy/mysql/my_cluster/data

[mysqld]
hostname=localhost
id=101

[api]
hostname=localhost

<强>的my.cnf:

[mysqld]
ndbcluster
datadir=/home/billy/mysql/my_cluster/data
basedir=/usr/local/mysql

这主要关注ClusterJ而不是运行MySQL Cluster;如果您不熟悉MySQL Cluster,请在尝试之前参考运行简单的Cluster。

需要告诉ClusterJ如何连接到我们的MySQL Cluster数据库;包括连接字符串(管理节点的地址/端口),要使用的数据库,用户登录以及连接的属性,例如超时值。如果未定义这些参数,则ClusterJ将因运行时异常而失败。此信息表示图3中所示的“配置属性”。这些参数可以在应用程序代码中进行硬编码,但创建将由应用程序导入的clusterj.properties文件更易于维护。该文件应存储在与应用程序源代码相同的目录中。

<强> clusterj.properties:

com.mysql.clusterj.connectstring=localhost:1186
 com.mysql.clusterj.database=clusterdb
 com.mysql.clusterj.connect.retries=4
 com.mysql.clusterj.connect.delay=5
 com.mysql.clusterj.connect.verbose=1
 com.mysql.clusterj.connect.timeout.before=30
 com.mysql.clusterj.connect.timeout.after=20
 com.mysql.clusterj.max.transactions=1024

由于ClusterJ不会自动创建表,下一步是创建'clusterdb'数据库(在clusterj.properties中引用)和'employee'表:

[dadaso@ubuntu14-lts-server ~]$ mysql -u root -h 127.0.0.1 -P 3306 -u root
 mysql>  create database clusterdb;use clusterdb;
 mysql> CREATE TABLE employee (
 ->     id INT NOT NULL PRIMARY KEY,
 ->     first VARCHAR(64) DEFAULT NULL,
 ->     last VARCHAR(64) DEFAULT NULL,
 ->     municipality VARCHAR(64) DEFAULT NULL,
 ->     started VARCHAR(64) DEFAULT NULL,
 ->     ended  VARCHAR(64) DEFAULT NULL,
 ->     department INT NOT NULL DEFAULT 1,
 ->     UNIQUE KEY idx_u_hash (first,last) USING HASH,
 ->     KEY idx_municipality (municipality)
 -> ) ENGINE=NDBCLUSTER;

下一步是创建带注释的界面:

<强> Employee.java:

import com.mysql.clusterj.annotation.Column;
import com.mysql.clusterj.annotation.Index;
import com.mysql.clusterj.annotation.PersistenceCapable;
import com.mysql.clusterj.annotation.PrimaryKey;
@PersistenceCapable(table="employee")
@Index(name="idx_uhash")
public interface Employee {
@PrimaryKey
int getId();
void setId(int id);
String getFirst();
void setFirst(String first);

String getLast();
void setLast(String last);
@Column(name="municipality")
@Index(name="idx_municipality")
String getCity();
void setCity(String city);
String getStarted();
void setStarted(String date);
String getEnded();
void setEnded(String date);
Integer getDepartment();
void setDepartment(Integer department);
}

表的名称在注释@PersistenceCapable(table =“employee”)中指定,然后employee表中的每一列都具有在接口中定义的关联getter和setter方法。默认情况下,界面中的属性名称与表中的列名称相同 - 通过在关联的getter方法之前显式包含@Column(name =“municipality”)注释,已为City属性覆盖列名称。 @PrimaryKey批注用于标识其关联列是表中主键的属性。使用@Index注释使ClusterJ知道数据库中是否存在索引。

下一步是编写我们逐步执行的应用程序代码;第一个只包含import语句,然后加载上面定义的clusterj.properties的内容:

Main.java(第1部分):

import com.mysql.clusterj.ClusterJHelper;
import com.mysql.clusterj.SessionFactory;
import com.mysql.clusterj.Session;
import com.mysql.clusterj.Query;
import com.mysql.clusterj.query.QueryBuilder;
import com.mysql.clusterj.query.QueryDomainType;
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.*;
import java.util.Properties;
import java.util.List;
public class Main {
public static void main (String[] args) throws java.io.FileNotFoundException,java.io.IOException {
// Load the properties from the clusterj.properties file
File propsFile = new File("clusterj.properties");
InputStream inStream = new FileInputStream(propsFile);
Properties props = new Properties();
props.load(inStream);
//Used later to get userinput
BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));

下一步是从ClusterJHelper类获取SessionFactory的句柄,然后使用该工厂创建会话(基于从clusterj.properties文件导入的属性。

Main.java(第2部分):

//创建会话(与数据库的连接) SessionFactory factory = ClusterJHelper.getSessionFactory(props); Session session = factory.getSession(); 现在我们有了一个会话,可以实例化新的Employee对象,然后将它们保存到数据库中。如果没有事务begin()或commit()语句,则涉及数据库的每个操作都被视为一个单独的事务。

Main.java(第3部分):

/

/ Create and initialise an Employee
Employee newEmployee = session.newInstance(Employee.class);
newEmployee.setId(988);
newEmployee.setFirst("John");
newEmployee.setLast("Jones");
newEmployee.setStarted("1 February 2009");
newEmployee.setDepartment(666);
// Write the Employee to the database
session.persist(newEmployee);

此时,“employee”表中会添加一行。为了验证这一点,创建了一个新的Employee对象,用于使用主键(Id)值998从'employee'表读回数据:

Main.java(第4部分):

// Fetch the Employee from the database
 Employee theEmployee = session.find(Employee.class, 988);
if (theEmployee == null)
 {System.out.println("Could not find employee");}
else
 {System.out.println ("ID: " + theEmployee.getId() + "; Name: " +
 theEmployee.getFirst() + " " + theEmployee.getLast());
 System.out.println ("Location: " + theEmployee.getCity());
 System.out.println ("Department: " + theEmployee.getDepartment());
 System.out.println ("Started: " + theEmployee.getStarted());
 System.out.println ("Left: " + theEmployee.getEnded());
}

这是此时看到的输出:

ID: 988; Name: John Jones
Location: null
Department: 666
Started: 1 February 2009
Left: null

在我更改员工之前检查数据库 - 完成后点击返回 下一步是修改这些数据,但它还没有将其写回数据库:

Main.java(第5部分):

// Make some changes to the Employee & write back to the database
theEmployee.setDepartment(777);
theEmployee.setCity("London");
System.out.println("Check the database before I change the Employee -
hit return when you are done");
String ignore = br.readLine();

此时应用程序将暂停并让您有机会检查数据库以确认原始数据已添加为新行,但尚未写回更改:

mysql> select * from clusterdb.employee;
+-----+-------+-------+--------------+-----------------+-------+------------+
| id  | first | last  | municipality | started         | ended | department |
+-----+-------+-------+--------------+-----------------+-------+------------+
| 988 | John  | Jones | NULL         | 1 February 2009 | NULL  |        666 |
+-----+-------+-------+--------------+-----------------+-------+------------+

点击返回后,应用程序将继续并将更改写入表中,使用自动事务执行更新。

Main.java(第6部分):

session.updatePersistent(theEmployee);
System.out.println("Check the change in the table before I bulk add
Employees - hit return when you are done");
ignore = br.readLine();

应用程序将再次暂停,以便我们现在可以检查更改是否已写回(持久)到数据库:

mysql> select * from clusterdb.employee;
+-----+-------+-------+--------------+-----------------+-------+------------+
| id  | first | last  | municipality | started         | ended | department |
+-----+-------+-------+--------------+-----------------+-------+------------+
| 988 | John  | Jones | London       | 1 February 2009 | NULL  |        777 |
+-----+-------+-------+--------------+-----------------+-------+------------+

然后,应用程序将创建并保留100名新员工。为了提高性能,使用单个事务,以便在运行commit()语句时可以立即将所有更改写入数据库:

Main.java(第7部分):

// Add 100 new Employees - all as part of a single transaction
 newEmployee.setFirst("Billy");
 newEmployee.setStarted("28 February 2009");
session.currentTransaction().begin();
for (int i=700;i<800;i++) {
 newEmployee.setLast("No-Mates"+i);
 newEmployee.setId(i+1000);
 newEmployee.setDepartment(i);
 session.persist(newEmployee);
 }
session.currentTransaction().commit();

现在,100名新员工将被持久保存到数据库中。下一步是创建并执行一个查询,该查询将使用QueryBuilder在数据库中搜索部门777中的所有员工,并使用该查询构建一个QueryDomain,将“department”列与参数进行比较。创建之后,department参数设置为777(随后可以使用不同的部门编号重用查询)。然后,应用程序运行查询并迭代并显示结果集中的每个员工:

Main.java(第8部分):

// Retrieve the set all of Employees in department 777
QueryBuilder builder = session.getQueryBuilder();
QueryDomainType<Employee> domain =
builder.createQueryDefinition(Employee.class);
domain.where(domain.get("department").equal(domain.param(
"department")));
Query<Employee> query = session.createQuery(domain);
query.setParameter("department",777);
List<Employee> results = query.getResultList();
for (Employee deptEmployee: results) {
System.out.println ("ID: " + deptEmployee.getId() + "; Name: " +
deptEmployee.getFirst() + " " + deptEmployee.getLast());
System.out.println ("Location: " + deptEmployee.getCity());
System.out.println ("Department: " + deptEmployee.getDepartment());
System.out.println ("Started: " + deptEmployee.getStarted());
System.out.println ("Left: " + deptEmployee.getEnded());
}
System.out.println("Last chance to check database before emptying table
- hit return when you are done");
ignore = br.readLine();

此时,应用程序将显示以下内容并提示用户继续:

ID: 988; Name: John Jones
Location: London
Department: 777
Started: 1 February 2009
Left: null
ID: 1777; Name: Billy No-Mates777
Location: null
Department: 777
Started: 28 February 2009
Left: null

我们可以将该输出与在数据库上执行的SQL查询进行比较:

mysql> select * from employee where department=777;
 +------+-------+-------------+--------------+------------------+-------+------------+
 | id   | first | last        | municipality | started          | ended | department |
 +------+-------+-------------+--------------+------------------+-------+------------+
 |  988 | John  | Jones       | London       | 1 February 2009  | NULL  |        777 |
 | 1777 | Billy | No-Mates777 | NULL         | 28 February 2009 | NULL  |        777 |
 +------+-------+-------------+--------------+------------------+-------+------------+

最后,再次按下返回后,该应用程序将删除所有员工:

Main.java(第9部分):

session.deletePersistentAll(Employee.class);

作为最终检查,SQL查询确认已从“员工”表中删除了所有行。

mysql> select * from employee;
Empty set (0.00 sec)