SQLData

Wepa

Mitglied
Guten Tag,

ich möchte in einen eigen erstellten Datenbanktypen in einen Javatypen umwandeln um bequem mit den getObject und setObject Metoden von eine ResultSet arbeiten zu können. Dabei wollte ich wie folgt vorgehen:

SQL:
CREATE TYPE person
(
   name VARCHAR(50),
   age INT
)

Java:
public class Person implements SQLData 
{
   public String name;
   public int age;
   
   public String getSQLTypeName() 
   {
      return "person";
   }

   public void readSQL(SQLInput stream, String type) throws SQLException 
   {
      name = stream.readString();
      age = stream.readInt();
   }

   public void writeSQL(SQLOutput stream) throws SQLException 
   {
      stream.writeString(name);
      stream.writeInt(age);
   }
}

Leider scheitert es schon beim erstellen des Typen person. Momentan benutze ich h2 als DBMS, wobei diese anscheinend keine benutzerdefinierte Typen unterstützt.Meine Frage lautet: Welche in Java geschriebenes DBMS kann dieses oder welche anderen wege gibt es um Javatypen in Datenbanktypen abzubilden?

mfg Wepa
 

turtle

Top Contributor
Eigentlich sollte jeder O/R-Mapper von SQL-Datentypen auf Java-Datentypen mappen können.

Beliebte Mapper sind derzeit Hibernate, JPA oder mein häufig eingesetztes myBATIS.

Dein Beispiel macht sich des objekt-relationalen Mappings in der Datenbank zu Nutze. Dieses ist aber sehr von der DB abhängig und wird (daher) meines Wissens selten eingesetzt.

Ich rate Dir daher auf eine "normale" SQL-DB aufzusetzen und mit einem O/R-Mapper Deiner Wahl in Java weiterzumachen. Wenn Du gut SQL kennst und vielleicht schon die DB vorliegen hast, rate ich zu myBATIS, sonst JPA.
 

Wepa

Mitglied
Danke für den Tipp turtle. MyBatis ist genau das, was ich gesucht habe, aber ich bekomme es nicht zum laufen.

db.properties
Code:
dbDriver=org.apache.derby.jdbc.EmbeddedDriver
dbUrl=jdbc:derby:testdb
dbUser=root
dbPassword=root

Person.xml
Code:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Person">
    <select id="selectAllPersons" resultType="Person">
        select id,vorname,nachname from person
    </select>
</mapper>

SqlMapConfig.xml

[XML]<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="database/db.properties"></properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${dbDriver}" />
<property name="url" value="${dbUrl}" />
<property name="username" value="${dbUser}" />
<property name="password" value="${dbPassword}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="database/Person.xml" />
</mappers>
</configuration>[/XML]

Java:
public static void main(String[] args)
	{
		MAIN.erstelleDB();
		try
		{

			System.out.println(new File("database/SqlMapConfig.xml").exists());
			System.out.println(new File("database/Person.xml").exists());
			System.out.println(new File("database/db.properties").exists());
			
			Reader reader = Resources.getResourceAsReader("database/SqlMapConfig.xml");
			SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
			SqlSession sqlSession = sqlSessionFactory.openSession();
			try
			{
				@SuppressWarnings("unchecked")
				List<Person> listPersons = sqlSession.selectList("Person.selectAllPersons");
				for (Person person : listPersons)
				{
					System.out.println(person);
				}
			}
			finally
			{
				sqlSession.close();
			}
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

Java:
private static void erstelleDB()
	{
		try
		{
			Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
			Connection connection = DriverManager.getConnection("jdbc:derby:testdb;create=true", "root", "root");

			Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
			statement.execute("CREATE TABLE person (id INT NOT NULL, vorname VARCHAR(200), nachname VARCHAR(200), PRIMARY KEY (id))");
			statement.execute(" INSERT INTO person(id,vorname,nachname) VALUES(1,'Turtle', 'Tau')");
			statement.execute(" INSERT INTO person(id,vorname,nachname) VALUES(2,'Angela', 'Merkel')");
			
			ResultSet resultSet = statement.executeQuery("SELECT * FROM person");
			while (resultSet.next())
			{
				System.out.println(resultSet.getString(1) + "|" + resultSet.getString(2) + "|" + resultSet.getString(3));
			}
			
			statement.close();
			connection.close();
		}
		catch (ClassNotFoundException e)
		{
		}
		catch (SQLException e)
		{
		}
	}

Fehlermeldung
Code:
1|Turtle|Tau
2|Angela|Merkel
true
true
true
java.io.IOException: Could not find resource database/SqlMapConfig.xml
	at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:104)
	at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:91)
	at org.apache.ibatis.io.Resources.getResourceAsReader(Resources.java:149)
	at entity.MAIN.main(MAIN.java:32)

leider bekomme ich immerzu die oben genannte Fehlermeldung (Unter Ubuntu und Windows 7)! Ich hoffe jemand kennt den Fehler?

mfg Wepa
 

turtle

Top Contributor
Schön, das es läuft.

Wenn man mehrmals myBATIS genutzt hat, geht die Einrichtung eines Projektes innerhalb von 5 Minuten.

Mir fiel noch auf, dass Du in Deinem Code machst:
Java:
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
Das ist bei den meisten JDBC 4.0 -Treibern nicht mehr notwendig. Diese Treiber registrieren sich automatisch durch die Angabe in META-INF/services/java.sql.Driver. Probier es mal aus und lasse die Class.forName()-Zeile einfach weg.
 

Wepa

Mitglied
Hi,

ich habe noch eine Frage:

MyBatis benutzt eine ObjectFactory um die Objekte zu erstellen, die es braucht.
Wenn man nun factory - Methoden benutzen will, kann man einfach von der DefaultObjectFactory
ableiten und diese in der mybatis-config.xml myBatis bekannt machen.

Java:
// ExampleObjectFactory.java

public class ExampleObjectFactory extends DefaultObjectFactory
{
        public Object create(Class type) 
        {
               return super.create(type);
        }

        public Object create(Class type, List<Class> constructorArgTypes, List<Object> constructorArgs)
        {
               return super.create(type, constructorArgTypes, constructorArgs);
        }

        public void setProperties(Properties properties)
        {
              super.setProperties(properties);
        }
}

[XML]
<!-- mybatis-config.xml -->
<objectFactory type="org.mybatis.example.ExampleObjectFactory">
<property name="someProperty" value="100"/>
</objectFactory>
[/XML]

Nun nutze ich myBatis - Spring und ich möchte AOP benutzen. Wie bekomme ich nun myBatis - Spring dazu eine BeanFactory zu benutzen um die Objekte zu erstellen.

mfg Wepa
 

Neue Themen


Oben