Java Hibernate检查MySQL Replication是同步的

时间:2013-05-28 09:25:32

标签: mysql hibernate

通常我们通过控制台命令

检查从站上的复制是否正常
SHOW SLAVE STATUS \G;

我想将此功能合并到servlet报告应用程序中。 但是,hibernate似乎不允许这样做:

createSQLQuery("SHOW SLAVE STATUS");
...executing query...
java.lang.UnsupportedOperationException: not yet implemented for SQL queries

我确信使用本机JDBC可以实现这一点,但是可能有更好的方法吗? 环境:Linux 2.6.18,Tomcat 6/7,Hibernate 3.4,Java 1.6,MySQL 5 注意:我对在master上插入时间戳的解决方案不感兴趣。

4 个答案:

答案 0 :(得分:4)

使用createSQLQuery运行本机SQL查询时,必须告诉Hibernate how to convert the results into Java objects。在您的情况下最简单的方法是添加

query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);

在执行之前查询。 (如果查询返回已经映射的实体,则可以使用addEntity()。)

答案 1 :(得分:3)

我没有努力使用Hibernate,但如果失败了,你仍然可以使用一个很好的老式JDBC连接:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Test {

    static final String DB_ADDRESS = "localhost";
    static final String DB_NAME = "mysql";
    static final String DB_USER = "root";

    public static void main (String[] args) {
        // get password
        String password = "";
        if (args!=null && args.length>0) {
            password = args[0];
        }

        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
        } catch (Exception ex) {
            // handle the error
            System.out.println("Driver issue: " + ex.getMessage());
            System.out.println("Driver issue: " + ex.getClass().toString());
        }
        // connect to database
        try {
            Connection conn = 
               DriverManager.getConnection("jdbc:mysql://"+DB_ADDRESS+"/"+DB_NAME+"?autoReconnect=true",DB_USER,password);

            // Do something with the Connection
            System.out.println("Connection: " + conn);
            Statement stmt = conn.createStatement();


            ResultSet RS = stmt.executeQuery("SHOW TABLES");
            while (RS.next()) {
                System.out.println("table: '" + RS.getString(1) + "'");
            }

            // disconnect from database
            conn.close();
            stmt.close();

        } catch (SQLException ex) {
            // handle any errors
            System.out.println("SQLException: " + ex.getMessage());
            System.out.println("SQLState: " + ex.getSQLState());
            System.out.println("VendorError: " + ex.getErrorCode());
        }
    }
}

这将返回:

Connection: com.mysql.jdbc.JDBC4Connection@528acf6e
table: 'columns_priv'
table: 'db'
table: 'event'
table: 'func'
table: 'general_log'
table: 'help_category'
table: 'help_keyword'
table: 'help_relation'
table: 'help_topic'
table: 'host'
table: 'ndb_binlog_index'
table: 'plugin'
table: 'proc'
table: 'procs_priv'
table: 'proxies_priv'
table: 'servers'
table: 'slow_log'
table: 'tables_priv'
table: 'time_zone'
table: 'time_zone_leap_second'
table: 'time_zone_name'
table: 'time_zone_transition'
table: 'time_zone_transition_type'
table: 'user'

毋庸置疑,关键是要确保您的用户拥有足够的权限。

答案 2 :(得分:2)

正如UnsupportedOperationException例外消息所示,getReturnTypes()SQLQuery返回的createSQLQuery()对象未实现。{/ p>

顺便说一句,你的问题的措辞是误导性的,你在调用createSQLQuery()时没有收到例外,但是后来几行。

当您发出本机SQL时,您将检索行作为通用Object[]的列表(除非您明确地为Hibernate提供映射)。通常,类型将在编译时知道。

有关详细信息,请参阅here

答案 3 :(得分:2)

这对我有用..

SQLQuery query =session.createSQLQuery("show slave status");
ArrayList<Object[]> results = (ArrayList<Object[]>)query.list();
//there is only one row returned
Object [] result =  results.get(0);
//Seconds Behind Master should always be the last value in the row.
String secondsBehindMaster = ""+result[result.length-1];

确保数据库用户具有REPLICATION CLIENT权限才能进行此查询。

GRANT REPLICATION CLIENT ON *.* TO 'db_user'@'db_server' IDENTIFIED BY 'db_password';