1

通常我们通过控制台命令检查从服务器上的复制是否正在工作

SHOW SLAVE STATUS \G;

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

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

4 回答 4

4

当您使用createSQLQuery运行原生 SQL 查询时,您必须告诉 Hibernate如何将结果转换为 Java 对象。在您的情况下,最简单的方法是添加

query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);

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

于 2013-06-05T16:15:46.143 回答
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'

不用说,关键是确保您的用户拥有足够的权限。

于 2013-06-10T21:33:57.350 回答
2

正如UnsupportedOperationException异常消息所暗示的,getReturnTypes()不是由SQLQuery返回的对象实现的createSQLQuery()

顺便说一句,您问题的措辞具有误导性,您在调用时没有收到异常createSQLQuery(),但在几行之后。

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

请参阅此处了解更多信息。

于 2013-06-01T16:54:37.530 回答
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];

确保 DB 用户具有 REPLICATION CLIENT 进行此查询的权限。

GRANT REPLICATION CLIENT ON *.* TO 'db_user'@'db_server' IDENTIFIED BY 'db_password';
于 2013-06-26T15:59:52.737 回答