d12g

Blog von Daniel Grewing

Spring Boot – Zugriff auf zwei Datenbanken

24. April 2016 Softwareentwicklung

Mit Spring Boot kann man Spring Anwendungen per “convention over configuration” erstellen. Eine Webanwendung mit MVC-Logik und Datenbankzugriff ist schnell erstellt. Für ein Projekt benötigte ich eine Anwendung, die auf zwei unterschiedliche Datenbanken (MySql und PostgreSQL) zugreifen konnte.
Da der Zugriff auf zwei Datenbanken nur über weitere Konfigurationen möglich ist, musste ich recht lange suchen und probieren, bis ich eine schöne Lösung gefunden hatte. Diese möchte hier vorstellen.
Bei diesem Beispiel soll eine Anwendung Benutzerdaten aus zwei Datenbanken laden und anzeigen. In der MySql-Datenbank liegt die Tabelle User, in der PostgreSQL-Datenbank die Tabelle Benutzer. Ein Controller soll jeweils einen Datensatz laden und auf einer Webseite anzeigen.

Der Screenshot zeigt die Struktur des Eclipseprojekts:
spring-boot-projekt_twoDbs

Das Spring-Projekt basiert auf dieser pom.xml.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>de.rockworm</groupId>
	<artifactId>springBootTwoDb</artifactId>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.3.3.RELEASE</version>
	</parent>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<dependency>
			<groupId>postgresql</groupId>
			<artifactId>postgresql</artifactId>
			<version>9.1-901.jdbc4</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<properties>
		<java.version>1.7</java.version>
	</properties>
	<repositories>
		<repository>
			<id>spring-milestone</id>
			<url>https://repo.spring.io/libs-release</url>
		</repository>
	</repositories>
	<pluginRepositories>
		<pluginRepository>
			<id>spring-milestone</id>
			<url>https://repo.spring.io/libs-release</url>
		</pluginRepository>
	</pluginRepositories>
</project>

Der Datenbankzugriff wird über eine Java-Bean- und eine DataAccessObject-Klasse erstellt:
Für user auf der MySql-Datenbank:

@Entity
@Table(name="user")
public class User {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Integer id;
	 
	@Column
	private String name;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

@Transactional
public interface UserDao extends CrudRepository<User, Integer> {
}

Für benutzer auf der PostgreSQL-Datenbank:

@Entity
@Table(name="benutzer")
public class Benutzer {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Integer id;
	 
	@Column
	private String nickname;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getNickname() {
		return nickname;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}
}
@Transactional
public interface BenutzerDao extends CrudRepository<Benutzer, Integer> {

}

Die Konfiguration für den Zugriff auf die beiden Datenbanken erfolgt in den Klassen MySqlConfig.java und PostgreSqlConfig.java

@Configuration
@EnableJpaRepositories(entityManagerFactoryRef = "customerEntityManagerFactory", transactionManagerRef = "customerTransactionManager")
class MySqlConfig {

    @Bean
    PlatformTransactionManager customerTransactionManager() {
	return new JpaTransactionManager(customerEntityManagerFactory().getObject());
    }

    @Bean
    LocalContainerEntityManagerFactoryBean customerEntityManagerFactory() {

	HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
	jpaVendorAdapter.setGenerateDdl(true);

	LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();

	factoryBean.setDataSource(dataSource());
	factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
	factoryBean.setPackagesToScan(MySqlConfig.class.getPackage().getName());

	return factoryBean;
    }

    @Bean(name = "datasource.mysql")
    @ConfigurationProperties(prefix = "datasource.mysql")
    public DataSource dataSource() {
	return DataSourceBuilder.create().build();
    }
}
@Configuration
@EnableJpaRepositories(entityManagerFactoryRef = "orderEntityManagerFactory", transactionManagerRef = "orderTransactionManager")
class PostgreSqlConfig {

    @Bean
    PlatformTransactionManager orderTransactionManager() {
	return new JpaTransactionManager(orderEntityManagerFactory().getObject());
    }

    @Bean
    LocalContainerEntityManagerFactoryBean orderEntityManagerFactory() {

	HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
	vendorAdapter.setGenerateDdl(true);

	LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();

	factoryBean.setDataSource(dataSource());
	factoryBean.setJpaVendorAdapter(vendorAdapter);
	factoryBean.setPackagesToScan(PostgreSqlConfig.class.getPackage().getName());

	return factoryBean;
    }

    @Bean(name = "datasource.postgres")
    @ConfigurationProperties(prefix = "datasource.postgres")
    public DataSource dataSource() {
	return DataSourceBuilder.create().build();
    }
}

In beiden Klassen wird in den Annotationen Bean und ConfigurationProperties ein Prefix genutzt, welches sich in der application.properties wiederfindet.

server.port = 8833

datasource.mysql.driverClassName=com.mysql.jdbc.Driver
datasource.mysql.url=jdbc:mysql://172.16.1.207/dev-springboot
datasource.mysql.username=user
datasource.mysql.password=pass
datasource.mysql.testOnBorrow=true
datasource.mysql.validationQuery=SELECT 1

datasource.postgres.driverClassName=org.postgresql.Driver
datasource.postgres.url = jdbc:postgresql://172.16.1.204/dev-springboot
datasource.postgres.username = user
datasource.postgres.password = pass
datasource.postgres.testOnBorrow=true
datasource.postgres.validationQuery=SELECT 1

spring.jpa.hibernate.ddl-auto=update

Im Controller können nun Datensätze aus beiden Datenbanken abgerufen und an das Model übergeben werden:

@Controller
public class IndexController {

    @Autowired
    private UserDao userDao;

    @Autowired
    private BenutzerDao benutzerDao;
    
    @RequestMapping("/index")
    public String index(Model model) {

    	User user1 = userDao.findOne(1);
    	Benutzer benutzer1 = benutzerDao.findOne(1);
    	
    	model.addAttribute("user", user1);
    	model.addAttribute("benutzer", benutzer1);
	
	return "index";
    }
}

Auf den Weg zur Superintelligenz

10. April 2016 Allgemein

11252626214_7f0e0613c3_z

Vor wenigen Wochen gingen Berichte über ein Duell im Spiel Go zwischen einem der besten Spieler der Welt, Lee Sedol,  und der Software von Google AlphaGo durch die Medien. Das Spiel Go ist noch komplexer als Schach und es wurde lange daran gezweifelt, dass eine Software so bald in der Lage sein würde einen Profispieler schlagen zu können. Nach drei Partien stand es am Ende 3:1 für AlphaGo.

Einige waren überrascht, dass der Sieg so deutlich für Google ausging. Mich überraschte vielmehr, dass es bereits jetzt, 2016, soweit war. In Superintelligenz beschreibt Nick Bostrom die Gefahren bei der Entwicklung der künstlichen Intelligenz. Sein Buch erschien 2014 und Bostrom ist eine bekannte Kompetenz auf dem Gebiet der Zukunftsforschung und Superintelligenz.

Superintelligenz (wörtl. Über-Intelligenz) bezeichnet Wesen oder Maschinen mit dem Menschen überlegener Intelligenz. Der Begriff findet insbesondere im Transhumanismus und im Bereich der Künstlichen Intelligenz Verwendung. Ein tatsächlich geistig überlegenes Wesen, das die Kriterien einer Superintelligenz erfüllt, ist nach heutigem Kenntnisstand nicht bekannt.

https://de.wikipedia.org/wiki/Superintelligenz

In einem Vergleich macht er deutlich, bei welchen Spielen und ab welchem Jahr der Mensch kein Gegner mehr für einen Computerspieler war. Interessant ist, dass Bostrom für das Spiel Go 2014 eine Computerintelligenz noch als amateurhaften Spieler einstufte. Zwei Jahre später kann ich mir gar nicht mehr vorstellen, dass ein menschlicher Spieler jemals eine Chance gegen AlphaGo oder eine andere Software haben wird. Zum Vergleich wann eine Software bei bekannten Spielen ein übermenschlicher Gegner war: Backgammon 1979, Dame im Jahr 1994 und im Schach besiegte 1997 Deep Blue von IBM den Schachweltweister Kasparow.

Es ist also viel eher eingetreten. Es kann natürlich sein, dass Bostrom eine falsche Einschätzung über den aktuellen Stand der KI-Forschung gehabt hat. Es kann aber auch bedeuten, dass die großen Internetunternehmen wie Google, Facebook oder Apple an Systemen arbeiten von denen wir nichts ahnen und sie dann plötzlich der Öffentlichkeit vorstellen. Ich denke wir werden in den nächsten Jahren noch einige Überraschungen im Bereich der künstlichen Intellegenz erleben.

Bostrom beschreibt ein sehr düsteres Bild in Superintelligenz und für ihn scheint es nur eine Frage der Zeit bis eine Superintelligenz die Macht über die Menschheit übernimmt. Seine Schlussfolgerungen scheinen mir durchaus logisch und seine Motivation ist auch eine Diskussion in der Gesellschaft anzuregen (der erste Gipfel in Deutschland findet im April statt). Ich bin aber skeptisch, dass eine KI-Software so schnell zu einer Superintelligenz reifen kann und in der Lage wäre, die Geschicke der Menschheit zu lenken. Aber vielleicht ist es doch bald soweit und wir werden von einer Superintelligenz überrascht, die es als ihre Lebensaufgabe sieht möglichst viele Büroklammern herzustellen.

Notizbuchsuche.de

14. Februar 2016 Softwareentwicklung

nbhs1

 

Heute möchte ich eine neues Projekt von mir vorstellen.

Unter Notizbuchsuche.de habe ich einen Katalog für Notizbücher entwickelt. Man kann sich über viele verschiedene Parameter Notizbücher suchen und sich im Detail anschauen. Das Projekt ist noch am Anfang und der Katalog wird wöchentlich größer. Bis heute habe ich knapp 150 Notizbücher von verschiedenen Herstellern in der Größe DIN A5 eingepflegt. Es sollen noch viel mehr werden. Aber jetzt ist der Zeitpunkt gekommen mal zu schauen, was „die Welt“ da draußen davon hält. Für Feedback bin ich also äußert dankbar.

 

Silvesterlauf 2015 oder “Der Mann mit dem Hammer”

3. Januar 2016 Sport

Zum ersten Mal habe ich beim Silvesterlauf von Werl nach Soest teilgenommen. Der Lauf gilt als der größte Lauf an Silvester deutschlandweit. Bei der 34. Ausgabe liefen die etwa 6500 Teilnehmer wieder 15 km von Werl über die B1 nach Soest.

Das Wetter war ausgezeichnet, kein Niederschlag und für Silvester fast zu warme 10°C. Ich bin in Soest aufgewachsen, aber es kam mir nie in den Sinn mich vor dem Jahreswechsel noch über 15 km zu quälen. Dieses Jahr hatte ich mir den Wettkampf dann mal vorgenommen, mich einigermaßen darauf vorbereitet und über die Weihnachtstage immer nur zwei statt drei Portionen gegessen.

Der Lauf begann um halb zwei, für mich eher eine ungewohnte Zeit, laufe ich doch eher morgens oder abends. Dennoch begann der Lauf recht gut und ich konnte die ersten zehn Kilometer in meinem geplanten Tempo laufen. Zu Beginn hatte ich aber bereits ein kleines Hungergefühl. Ich hatte gegen neun Uhr ein kleines Frühstück und bis zum Lauf dann nur noch einige Bananen gefuttert. In Ampen, also fast genau bei dem Schild „10 km“, kam dann der Einbruch. Ich merkte bereits wie meine Beine ungewohnt müde wurden, ich bekam einen Hungerast und war völlig unterzuckert. Zum Glück, dachte ich, hatte ich noch eine kleine Tüte Gummibärchen (diese Minipackungen mit 10 Stück) und ein Traubenzucker dabei. Es ging dann bis etwa 12 km wieder, dann kam es aber ganz dicke. Meine Beine wurden schwach und mir wurde schwindelig, ich musste gehen. Zwischendurch konnte ich noch einige Kekse bei einer Zuschauergruppe ergattern, so dass ich die letzten 500 m in der Innenstadt von Soest wenigstens noch laufen und die Ziellinie laufend (und nicht gehend) überqueren konnte. Meine Zielzeit hatte ich natürlich lange nicht erreicht.

Das war schon ärgerlich, ich fühlte mich nämlich konditionell recht fit und war optimistisch mein Tempo die ganzen 15 km halten zu können, ohne mich so zu quälen, dass ich den Silvesterabend nur müde in der Ecke liegen würde. Ich hatte diese Erfahrung (“Hungerast” oder “Der Mann mit dem Hammer”) schonmal gemacht, aber leider bei meiner Vorbereitung nicht mehr genügend bedacht. Alles war perfekt organisiert, meine Lauftasche war gut gepackt und die Anreise nach Werl mit dem Zug stressfrei. Naja, nur meiner Ernährung kam dann etwas zu wenig Bedeutung bei und das rächt sich leider.

Aber immerhin konnte ich zum Jahreswechsel noch etwas lernen:

  1. Ich habe meinen Trainingsplan mehr oder weniger genau durchgezogen, trotz der vielen Weihnachtstermine im Dezember, der ganzen Weihnachtsorganisation und der dunklen Jahreszeit. Das ist also durchaus möglich.
  2. Beim nächsten Wettkampf werde ich penibel auf meine Ernährung achten und mich besser vorbereiten.
  3. Es macht sehr viel Spaß ab und an an solchen Events teilzunehmen.

13. Dezember 2015
von
Keine Kommentare

Ein Blog ist nicht genug

IMG_20151108_111541-e1447094426395-1024x727Ich führe diesen Blog seit etwa einem Jahr. Ohne bestimmtes Ziel habe ich diesen Blog gestartet. Ich wollte einfach nur einen Blog haben und schauen wohin es führt. Wie das Archiv offenbart habe ich keinen wirklichen Themenschwerpunkt. Ich wollte mich auch nie auf ein bestimmtes Thema festlegen, sondern einfach mal schauen was mir besonders Spaß macht.
Nach und nach habe ich gemerkt, über welche Themen ich gerne geschrieben habe und was mir leicht von der Hand ging. Über eines habe ich jetzt einen eigenen Blog gestartet. Auf Notizbuchhelden.de will ich über alles bloggen was mit Notizbüchern zu tun hat. Über Hersteller und die vielen verschiedenen Notizbücher die auf dem Markt zur Verfügung stehen. Ich möchte über Einsatzzwecke schreiben, also was man alles mit Notizbüchern anstellen kann und über Organisationssysteme, die einem das tägliche Leben vereinfachen sollen.
Die Welt der Notizbücher ist sehr vielfältig und es ist für jeden etwas dabei: Für den ordnungsliebenden Planer, für die Kreativen oder für den reinen Schreiberling.
Neben dem Besuch auf meinem Blog freue ich mich auch über Follower auf meiner Twitter- und Pinterest-Seite.

Zoolander 2

22. November 2015 Sonst so

Im April hatte ich ein Video gepostet wie Derek Zoolander und Hansel, die Protagonisten aus dem Film Zoolander, wieder über den Laufsteg geschwebt sind. Auf der Pariser Modewoche haben sie den Laufsteg von Valentino gecrashed, um den zweiten Teil von Zoolander zu promoten.
Jetzt wurde der offizielle Trailer von Zoolander 2 veröffentlicht:

Die beiden Modelstars sind sehr gealtert, haben sich aber der Zeit angepasst, wie z.B. beim Gebrauch des Selfie-Sticks. Neben Ben Stiller und Owen Wilson sind auch weitere Star von der Partie wie Penélope Cruz oder Will Ferrell. Eine wirklich interessante Nebenrolle als männliches weibliches Modell hat Benedict Cumberbatch.

Beginn der Weihnachtszeit

8. November 2015 Allgemein

Dieses Wochenende habe ich mit dem Bau eines Knusperhäuschens die Weihnachtszeit eingeläutet. Nach diesem Rezept
http://www.chefkoch.de/rezepte/156961069052870/Lebkuchenhaus.html
habe ich die Bauteile erstellt. Wer die genaue Backzeit wissen möchte, die leider nicht im Rezept angegeben wird, schaut sich den Kommentar von Nora vom 08.11.2008 14:47 Uhr an.
IMG_20151107_174812

Für den Zusammenbau macht man sich dann Zement aus Eiweiß und Puderzucker. Dazu habe ich zehn Eiweiß zu Eischnee aufgeschlagen und anschließend etwa acht oder neun Packungen Puderzucker gesiebt und untergerührt.

IMG_20151107_174823

Der Dachbau war etwas kniffelig. Aber als guter Baumeister weiß man sich zu helfen und nimmt ein paar Holzspieße zur Hilfe

IMG_20151107_190115

Steht das Haus dann (nachdem das Dach nach dem zu frühen Entfernen der Holzspieße abgerutscht ist, man sich total einsaut, versucht das Dach zu retten und dann weitere Holzspieße einfach mit Gewalt reinbohrt), dekoriert man nach Belieben

IMG_20151107_194344

IMG_20151107_194420

Und dann der Vergleich mit der Konkurrenz
IMG_20151107_195045

Die Holzspieße konnte ich dann am nächsten Morgen natürlich ohne Probleme wieder entfernen. Abschließend haut man den restlichen Zuckerguss als Schnee auf das Haus; so kann man dann auch die letzten Baumängel wunderbar verdecken.

IMG_20151108_203314

Kuboshow 2015

25. Oktober 2015 Allgemein

IMG_20151024_105355
Die Kuboshow ist eine Kunstmesse, die jährlich in den Flottmannhallen in Herne stattfindet. Junge Künstler haben die Möglichkeit ihre Werke einem Publikum vorzustellen und zu verkaufen. Die Auswahl der etwa 100 Künstler findet nach verschiedenen Kriterien statt. Wichtig ist, dass die Künstler Profis sind, also von ihrer Arbeit leben. Das können Autodidakten sein, aber meistens sind die Künstler Studenten oder Absolventen einer Kunstakademie. Weitere Kriterien sind eine gewisse Auswahl vorhandener Werke, einen Stil, der zur Kuboshow passt und eine realistische Einschätzung der Preise. Die Macher der Kuboshow betonen auch, dass die Auswahl sehr subjektiv ist und bei Kunst auch zwangsläufig ist.
Diesmal jährte sich die Kuboshow zum 20. Mal mit dem Subtitel “Das ist der Anfang”. Ich war jetzt das vierte Mal Jahr dort und bin immer wieder von vielen Werken begeistert. Noch habe ich mir kein Werk gekauft. Ich denke aber, die Preise sind sehr einsteigerfreundlich (wohl auch etwas zu niedrig. Die Kuboshow stößt bei der Preisgestaltung auch mal auf Kritik anderer Galerien). Ein Besuch lohnt sich, wenn man sich mal ein Kunstwerk anschaffen oder seine Sammlung erweitert möchte.
Hier eine Auswahl von Werken, die mir sehr gefallen haben.
Kuboshow 2015