{"id":3700,"date":"2024-09-07T09:48:29","date_gmt":"2024-09-07T07:48:29","guid":{"rendered":"https:\/\/bob-team.de\/wordpress\/?p=3700"},"modified":"2026-01-08T12:31:59","modified_gmt":"2026-01-08T11:31:59","slug":"webapp-mit-datenbank","status":"publish","type":"post","link":"https:\/\/bob-team.de\/wordpress\/2024\/09\/07\/webapp-mit-datenbank\/","title":{"rendered":"Webapp mit Datenbank"},"content":{"rendered":"<p><code>XyzdbStartStop implements LifecycleListener<\/code> reagiert auf <code>Lifecycle.START_EVENT<\/code> und <code>Lifecycle.STOP_EVENT<\/code>; beim Start wird <code>Server.createTcpServer<\/code> mit passenden TCP-Optionen ausgef\u00fchrt und eine globale Ressource &#8222;xyz\/db&#8220; bereitgestellt; beim Stopp wird per SQL-Befehl ein &#8222;SHUTDOWN&#8220; ausgel\u00f6st und die globale Ressource abgebaut<\/p>\n<p><code>XyzdbLink implements LifecycleListener<\/code> reagiert auch auf <code>Lifecycle.START_EVENT<\/code> und <code>Lifecycle.STOP_EVENT<\/code>; beim Start wird die globale Ressource &#8222;xyz\/db&#8220; als lokale &#8222;xyzdb&#8220;gebunden; beim Stopp wird entbunden<\/p>\n<p>die Webapp nutzt die lokale Ressource &#8222;xyzdb&#8220;<\/p>\n<pre lang=\"java\">Context initCtx = new InitialContext();\r\nContext envCtx = (Context) initCtx.lookup(\"java:comp\/env\");\r\nXyzdb db = (Xyzdb) envCtx.lookup(\"xyzdb\");<\/pre>\n<p>beim <a href=\"https:\/\/tomcat.apache.org\/tomcat-10.1-doc\/config\/loader.html\">Loader<\/a> muss &#8222;delegate&#8220; gleich &#8222;true&#8220; sein, damit die Ressource korrekt bereitgestellt werden kann<\/p>\n<p>siehe auch <a href=\"https:\/\/stackoverflow.com\/questions\/58407349\/tomcat-how-to-programmatically-define-a-datasource-resource-in-globalnamingreso\">https:\/\/stackoverflow.com<\/a><\/p>\n<hr\/>\n<pre lang=\"xml\">\r\n<!-- context.xml -->\r\n<Resource name=\"jdbc\/xyz\" auth=\"Container\" type=\"javax.sql.DataSource\"\r\n            driverClassName=\"com.ibm.db2.jcc.DB2Driver\"\r\n            username=\"admin\" password=\"geheim\"\r\n            maxActive=\"20\" maxIdle=\"10\"\r\n            maxWait=\"-1\"\r\n            url=\"jdbc:db2:\/\/{servername}:50000\/{dbname}\"\r\n\/>\r\n<\/pre>\n<pre lang=\"java\">\r\nInitialContext ic = new InitialContext();\r\nvar dsName = \"java:comp\/env\/jdbc\/xyz\";\r\nvar ds = (javax.sql.DataSource) ic.lookup(dsName);\r\ntry (var conn = ds.getConnection()) {\r\n   \/\/ ...\r\n}\r\n<\/pre>\n<hr\/>\n<p>Datenbank per JSTL nutzen<\/p>\n<pre lang=\"java\"><%\r\n    \/\/ lokale Einstellungen f\u00fcr Datenbankverbindung holen\r\n    Properties props = AppUtil.lookForProperties();\r\n    ResourceText query = ResourceText.fromJar(props.getProperty(\"sql\"));\r\n%>\r\n<%-- Konfiguration --%>\r\n<c:set var=\"dbDriver\"><%= props.get(\"driver\") %><\/c:set>\r\n<c:set var=\"dbUrl\"><%= props.get(\"url\") %><\/c:set>\r\n<c:set var=\"dbUser\"><%= props.get(\"user\") %><\/c:set>\r\n<c:set var=\"dbPass\"><%= props.get(\"pass\") %><\/c:set>\r\n<c:set var=\"abfrage\"><%= props.get(\"sql\") %><\/c:set>\r\n<sql:setDataSource var = \"db\"\r\n    driver = \"${dbDriver}\" url = \"${dbUrl}\"\r\n    user = \"${dbUser}\" password = \"${dbPass}\"\/>\r\n<%-- SQL-Abfrage --%>\r\n<sql:query dataSource=\"${db}\" var=\"result\">\r\n    <%= query.text() %>\r\n<\/sql:query>\r\n\r\n<c:if test=\"${fn:length(result.rows) eq 0}\">\r\n    <p>Keine Daten!<\/p>\r\n<\/c:if>\r\n\r\n<c:forEach var=\"x\" items=\"${result.rows}\" varStatus=\"loop\">\r\n    ${x.abcd}\r\n<\/c:forEach><\/pre>\n<hr \/>\n<p><a href=\"https:\/\/stackoverflow.com\/questions\/13129070\/webapp-tomcat-jdbc-pooled-db-connection-throwing-abandon-exception\">connection throwing abandon exception<\/a><\/p>\n<hr \/>\n<p><a href=\"https:\/\/github.com\/h2database\/h2database\/blob\/master\/h2\/src\/main\/org\/h2\/server\/web\/JakartaDbStarter.java\">github: JakartaDbStarter<\/a><br \/>\n<a href=\"https:\/\/stackoverflow.com\/questions\/58407349\/tomcat-how-to-programmatically-define-a-datasource-resource-in-globalnamingreso\">programmatically datasource<\/a><\/p>\n<p><strong>CIF2: programmatisch (alt)<\/strong><\/p>\n<p>in XyzMain wird H2-Server gestartet (keine Bereitstellung als Ressource, Zugriff \u00fcber JDBC, Einstellungen aus lokaler Konfiguration und Systemumgebung)<\/p>\n<p><strong>CIF2: programmatisch + XML-Konfiguration<\/strong><\/p>\n<p>a) <span style=\"font-family: monospace;\">server.addLifecycleListener(new XyzdbStartStop())<\/span> in XyzMain startet H2-Server und stellt globale Ressource bereit<br \/>\nb) &lt;Listener className=&#8220;net.btmx.mboee.XyzdbLink&#8220; \/&gt; in <span style=\"font-family: monospace;\">webapp\/META-INF\/context.xml<\/span> erstellt Ressourcen-Link f\u00fcr Webapp<\/p>\n<p><strong>CIF3: XML-Konfiguration<\/strong><\/p>\n<p>a) server.xml mit &lt;Listener className=&#8220;net.btmx.mboee.GlobalDatasourceCreator&#8220; \/&gt; startet H2-Server und stellt globale Ressource bereit<br \/>\nb) context.xml mit &lt;Listener className=&#8220;net.btmx.mboee.AppDatasourceLinkCreator&#8220; \/&gt; erstellt einen Ressoucen-Link in der Webapp<\/p>\n<p><strong>XYZDEV: programmatisch<\/strong> &rarr; LifecycleListener in \u00dcbersichtstabelle<\/p>\n<p><span style=\"font-family: monospace;\">ctx.addLifecycleListener(new net.btmx.bree.AppDbServer())<\/span> in XyzMain startet H2-Server und stellt Ressource mit Factory in Webapp bereit (Factory liefert Datenbank-Ressource als SingleTon)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>XyzdbStartStop implements LifecycleListener reagiert auf Lifecycle.START_EVENT und Lifecycle.STOP_EVENT; beim Start wird Server.createTcpServer mit passenden TCP-Optionen ausgef\u00fchrt und eine globale Ressource &#8222;xyz\/db&#8220; bereitgestellt; beim Stopp wird per SQL-Befehl ein &#8222;SHUTDOWN&#8220; ausgel\u00f6st und die globale Ressource abgebaut XyzdbLink implements LifecycleListener reagiert auch auf Lifecycle.START_EVENT und Lifecycle.STOP_EVENT; beim Start wird die globale Ressource &#8222;xyz\/db&#8220; als lokale &#8222;xyzdb&#8220;gebunden; beim [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[217],"class_list":["post-3700","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-mboee","entry"],"_links":{"self":[{"href":"https:\/\/bob-team.de\/wordpress\/wp-json\/wp\/v2\/posts\/3700","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bob-team.de\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bob-team.de\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bob-team.de\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bob-team.de\/wordpress\/wp-json\/wp\/v2\/comments?post=3700"}],"version-history":[{"count":15,"href":"https:\/\/bob-team.de\/wordpress\/wp-json\/wp\/v2\/posts\/3700\/revisions"}],"predecessor-version":[{"id":4267,"href":"https:\/\/bob-team.de\/wordpress\/wp-json\/wp\/v2\/posts\/3700\/revisions\/4267"}],"wp:attachment":[{"href":"https:\/\/bob-team.de\/wordpress\/wp-json\/wp\/v2\/media?parent=3700"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bob-team.de\/wordpress\/wp-json\/wp\/v2\/categories?post=3700"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bob-team.de\/wordpress\/wp-json\/wp\/v2\/tags?post=3700"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}