我的數據庫位於ssh隧道中,我使用JSch來連接它。如何通過休眠方式通過SSH隧道連接數據庫
這裏是我的Java代碼:
static String sshHost, sshAccount, sshPassword;
static int sshPort = 22;
static int localPort = 3399, remotePort = 3306;
static String remoteHost = "localhost";
public static void main(String[] args) throws JSchException {
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
JSch jsch = new JSch();
com.jcraft.jsch.Session jschSession = jsch.getSession(sshAccount, sshHost, sshPort);
jschSession.setPassword(sshPassword);
jschSession.setConfig(config);
System.out.println("Start Connecting " + sshHost + ":" + sshPort);
jschSession.connect();
int assinged_port = jschSession.setPortForwardingL(localPort,
remoteHost, remotePort);
System.out.println("localhost:" + assinged_port + " -> " + remoteHost + ":" + remotePort);
System.out.println("Connect Hibernate");
Configuration configuration = new Configuration().configure();
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
SessionFactory factory = configuration.buildSessionFactory(builder.build());
Session session = factory.openSession();
Transaction tx = session.beginTransaction();
System.out.println("Close Hibernate Connection");
tx.commit();
session.close();
factory.close();
System.out.println("Closing SSH Connection");
session.disconnect();
}
這是我Hibernate.cfg.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration >
<session-factory name="java:hibernate/SessionFactory">
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">[Database password]</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3906/PM?characterEncoding=utf8</property>
<property name="hibernate.connection.username">[Database User]</property>
<property name="hibernate.connection.socketFactory">com.mysql.jdbc.NamedPipeSocketFactory</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
</session-factory>
<mapping class="db.User" />
</hibernate-configuration>
我已經使用的代碼在here和here測試。因此,我確定SSH服務器,數據庫帳戶,密碼,url和端口的變量是正確的。
後,我運行的代碼,它給我的錯誤信息:
Exception in thread "main" org.hibernate.MappingException: invalid configuration
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:2160)
at org.hibernate.cfg.Configuration.configure(Configuration.java:2077)
at org.hibernate.cfg.Configuration.configure(Configuration.java:2056)
at sshtest.hibernate_connect.main(hibernate_connect.java:41)
Caused by: org.xml.sax.SAXParseException; lineNumber: 15; columnNumber: 27; 元素類型 "hibernate-configuration" 的內容必須配對 "(session-factory,security?)"。
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.handleEndElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.endElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at org.dom4j.io.SAXReader.read(SAXReader.java:465)
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:2157)
... 3 more
我不知道如何連接我的數據庫。
09-23添加
現在我改變像下面的xml文件(刪除db.User &會話工廠 「name」 屬性的映射):
<hibernate-configuration >
<session-factory>
...
</session-factory>
</hibernate-configuration>
而且我用的是方式Question 12737293給,所以我相信我的端口(3399)沒有使用。
但是,它仍然給我的錯誤信息:
Cannot connect Hibernateorg.hibernate.exception.JDBCConnectionException: Error calling Driver#connect
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:132)
at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator$1$1.convert(BasicConnectionCreator.java:118)
at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.convertSqlException(BasicConnectionCreator.java:140)
at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:58)
at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.createConnection(BasicConnectionCreator.java:75)
at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.configure(DriverManagerConnectionProviderImpl.java:106)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.buildJdbcConnectionAccess(JdbcServicesImpl.java:260)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:94)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1887)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1845)
at sshtest.hibernate_connect.main(hibernate_connect.java:46)
Caused by: com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception:
** BEGIN NESTED EXCEPTION **
java.io.FileNotFoundException
MESSAGE: \\.\pipe\MySQL (系統找不到指定的檔案。)
STACKTRACE:
java.io.FileNotFoundException: \\.\pipe\MySQL (系統找不到指定的檔案。)
at java.io.RandomAccessFile.open0(Native Method)
at java.io.RandomAccessFile.open(Unknown Source)
at java.io.RandomAccessFile.<init>(Unknown Source)
at java.io.RandomAccessFile.<init>(Unknown Source)
at com.mysql.jdbc.NamedPipeSocketFactory$NamedPipeSocket.<init>(NamedPipeSocketFactory.java:57)
at com.mysql.jdbc.NamedPipeSocketFactory.connect(NamedPipeSocketFactory.java:215)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:271)
at com.mysql.jdbc.Connection.createNewIO(Connection.java:2771)
at com.mysql.jdbc.Connection.<init>(Connection.java:1555)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:55)
at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.createConnection(BasicConnectionCreator.java:75)
at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.configure(DriverManagerConnectionProviderImpl.java:106)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.buildJdbcConnectionAccess(JdbcServicesImpl.java:260)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:94)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1887)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1845)
at sshtest.hibernate_connect.main(hibernate_connect.java:46)
** END NESTED EXCEPTION **
Last packet sent to the server was 1 ms ago.
at com.mysql.jdbc.Connection.createNewIO(Connection.java:2847)
at com.mysql.jdbc.Connection.<init>(Connection.java:1555)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:55)
... 13 more
你有一個XML解析錯誤。我懷疑這與你的SSH隧道有什麼關係。 –
嗯......當我使用不在ssh隧道中的數據庫時,我使用相同的xml代碼,它不會給出任何錯誤。因此,如果是xml的問題,我不知道應該在哪裏更改 – Shiyou