DAO Medge
This project is hosted at SourceForge.net Logo specifically here: DAO Icon To download the code generator and dao you just need the latest daomedgegen.zip. Download DAOMedge

Return to Medge's Home Page

DAOMedge

This is a database access object with a code generator.
It translates database to Plain Old Java Objects, or POJO, by using various techniqiues to build a SQL statement behind the scenes to retrieve the data.
It allows selections across tables, across catalogs etc. The filters are pretty powerful and if there is a gap in the library's abilities it could be filled by using a view instead of a table. Version 10 allows for columns from multiple tables in the same result set. See documentation for any limitations.

Why daomedge? I'm glad you asked. When I started this I figured that there was a lot of DAO type libraries, and I wasn't too wrong, so called it daomedge because no one else would have called theirs that!

Not to be confused with The Doomadgee Aboriginal Shire Council!

The old version, just the source is available here. Have fun!


Basic Principles

The basic principle is that the database structure is the correct one, not the java objects. I am, at heart a DBA and database designer1.


To build a Database Diagram

Download the node.js package from https://www.dbml.org/home/ using npm for linux and run:

dbml-renderer -i comMybusiness.dbml -o comMybusiness.svg
      

Example Code

These are based on my test suite, I have changed what needs to be changed. They should give you an idea of how to use this library.
Unit tests are tricky when dealing with databases, particularly the C UD parts of CRUD, So these are a little more direct.

Example how to create a connector/dao
Loading/Saving Connector to/from properties/xml files
Database Execute
Multiple Table Selection
Updating
Some select examples


Background

This is not specifically JDO nor does it conform to any DAO standards. I developed this library as a personal project I started when, over 30 years ago, fellow coders were chatting about JDO and how to implement it. We were also talking abount Mandelbrot Sets and how to generate them. I was working in Delphi from Borland, writing a Mandelbrot generator app in Object Pascal. I wrote version 1.0.0 of DAOMedge using a MySQL database at home, in Java JDK 1.1 (The first version with JDBC) on an early pentium computer, running Windows 95. I was hoping to port it to Delphi, but that would be clunky as Delphi didn't have reflection or, as it turns out, longevity. I LGPL'd it, privately2, at that point.

I was working at Company A at the time, and we were in the middle of redeveloping all of the internal applications into Visual BASIC, rather than the fudged, command line code currently in use. Soon after we were fully committed to developing in Visual BASIC Java arrived. We started playing around in Java. Eventually we started to redevelop the VB code into Java, but by that time I had moved to Company B.


History

All of my personally developed java code at Company A and Company B used DAOMedge.

From 2004 I was a DBA at Company B. In late 2004 I was tasked with the improvement of the data entry system, that was being done by a third party. I, naturally, started using DAOMedge officially. It was now that I submitted it to Source Forge making it LGPL for real which allowed me to use it for Company B and any other thing I needed it for.

Company B used MSSQL and Ingres as their databases, for reason's that are irrelevant to this page, so I could test against MSSQL, MySQL and Ingres. I tried to shoehorn the various catalog/schema combinations into a consistent naming of value objects. This was unpleasant, but not an issue unless you were moving database rows from one type of database to another.

DAOMedge grew up during the next 18 years as more and more features were added and more and more select methods were added. By the time I had reached version 9 it was obvious that it needed a rewrite. So much had been added to Java in that time, the important one was annotations. When my employment at Company B came to an end, I was made redundant in 2021, I left them with version 9.2.6 and was determined to start from scratch using annotations and JavaFX.
JavaFX was being recalcitrant, in as much as I couldn't get a table cell renderer and editor to behave well when it came to tool tip texts. So in late 2022 I decided to ignore JavaFX and stick with Swing. I still thought annotations were the way to go though.

Version 10 is a complete rewrite, it targets Java 173, which was the latest Long Term Support version of the JDK when I had the first cut of the code ready. There is not a lot of sites using Java 17 so I have a bit of a buffer for bugs etc. and I have used Java 17 syntax (mainly text block). The new version occupies a completely different namespace. Instead of mapping XML files it uses annotations. Starting from scratch allowed me to rationalise the way in which SQL is built by the library.

It is much smaller and doesn't use third party libraries at all (except, of course, JDBC drivers).

Java 21 is also a LTS release but, I'm not sure if I need the changes, so I'm sticking with 17 for the time being.


Command Line Interface


I have added a command line interface that you can use to generate directly.
Say you have two generators configured; my_database that doesn't have a stored password, and my_development_database which does.

java -Xmx2g -jar daomedgegen.jar my_database:password my_development_database

This will generate for my_database using the supplied password and then do my_development_database which has the password stored in the xml configuration file.

java -Xmx2g -jar daomedgegen.jar my_database my_development_database

This will prompt for a password and generate for my_database and then do my_development_database which has the password stored in the xml configuration file.


JDBC Drivers and Connection Strings


Light research on the web finds:

Database Driver jar Driver Name Minimum JDBC Connection String
MariaDB mariadb-java-client.jar org.mariadb.jdbc.Driver jdbc:mariadb://server:port/
MySQL mysql-connector-java.jar com.mysql.jdbc.Driver jdbc:mysql://server:port/
SQLServer
Microsoft
mssql-jdbc.jre11.jar com.microsoft.sqlserver.jdbc.SQLServerDriver jdbc:sqlserver://server:port
SQLServer
JTDS*
jtds.jar net.sourceforge.jtds.jdbc.Driver jdbc:jtds:sqlserver://server/database
Oracle Thin ojdbc11.jar oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:user/password@server:port:database
Oracle OCI ojdbc11.jar oracle.jdbc.OracleDriver jdbc:oracle:oci:@server:port:database
DB2 db2jcc4.jar com.ibm.db2.jcc.DB2Driver jdbc:db2://server:port/database
SQLite sqlite-jdbc-3.46.0.0.jar org.sqlite.JDBC jdbc:sqlite://filename.db
Ingres iijdbc.jar com.ingres.jdbc.IngresDriver jdbc:ingres://host:ii7/database
Postgres postgresql-42.7.7.jar org.postgresql.Driver jdbc:postgresql://host:port/database
HSQL hsqldb-2.7.4.jar org.hsqldb.jdbcDriver jdbc:hsqldb:hsql://host/database

*JTDS has been at version 1.3.1 since the 8th of June 2013. It does work very, very well so I suppose there is no reason to change it at all.


I've added a basic scripting language to the DAO, called NotSQL.

The commands are:

NotSQL command Equivalent(ish)
set classbase use
get select
filter where
sort order by
agg having

Examples
Simple select NotSQL (two queries) example 1.

set classbase com.mybusiness.data;

get Customer.*
filter (Customer.surname = 'Smith' | Customer.surname = 'Jones') & Customer.givens = 'John'
sort Customer.dateOfBirth>;

get Customer.givens, Customer.surname
filter Customer.surname = Smith | data.Customer.surname = 'Jones'
sort Customer.dateOfBirth<;
      
Multi table select NotSQL example 2.
set classbase com.mybusiness.data;

get Customer.surname, Customer.givens, PhoneNumber.phoneNumber
filter (Customer.surname = 'Smith' | Customer.surname = 'Jones') & PhoneNumber.phoneNumberType = M
sort Customer.dateOfBirth>;
      
Aggregate select with a having clause (second query uses a default) example 3.
set classbase com.mybusiness.data;

get Customer.surname
filter (Customer.surname = 'Smith' | Customer.surname = 'Jones') & PhoneNumber. phoneNumberType = M
sort Customer.surname
agg count(Customer.givens) > 1;

get Customer.surname
filter (Customer.surname = 'Smith' | Customer.surname = 'Jones') & PhoneNumber. phoneNumberType = M
sort Customer.surname
agg > 1;
      
Command order is irrelevant Simple select NotSQL (two queries) example 4, exactly the same effect as example 1.
sort Customer.dateOfBirth>;
filter (Customer.surname = 'Smith' | Customer.surname = 'Jones') & Customer.givens = 'John'
get Customer.*

sort Customer.dateOfBirth<
get Customer.givens, Customer.surname
filter Customer.surname = Smith | data.Customer.surname = 'Jones'

set classbase com.mybusiness.data;
      

In java this would be:

SimpleNotSQL simpleNotSQL = new SimpleNotSQL(dao, example_1); // There are two here
for (int i = 0; i < simpleNotSQL.getQueryCount(); i++) {
    List<T> res = simpleNotSQL.selectNotSQL(i);
}
MultiNotSQL multiNotSQL = new MultiNotSQL(dao, example_2); // There is only the one here
for (int i = 0; i < simpleNotSQL.getQueryCount(); i++) {
    List<Map<Class<?>, BaseDatabaseObject<?>>> res = multiNotSQL.selectNotSQL(i);
}
AggregateNotSQL aggregateNotSQL = new AggregateNotSQL(dao, example_3); // There are two here as well.
for (int i = 0; i < simpleNotSQL.getQueryCount(); i++) {
    List<AggregatedObject<Object>> res = aggregateNotSQL.selectNotSQL(i);
}
      

Future

I'll keep adding stuff to the library as it occurs to me or anyone using this library.

Observations

I added a table to my database the other day. It was the first one that uses nvarchar() on a MariaDB database. The generator detected it was a varchar, not nvarchar which would mean that values would be encoded as normal strings. I.E. 'test string' and not N'test string'.
I wondered if that would be an issue and I needed to detect the collation type of the column.
As it turns out, I do not. MariaDB reports it as a varchar, treats it as such and, with the collation, allows for unicode strings.

Is it that nvarchar and nchar are being deprecated? I can't find anything that suggests that it is.

As of Wed 29 Oct 2025 12:21:43 ACDT
daomedge has 80 classes; containing 21170 lines of which 19986 are not blank
daomedgegen has 173 classes; containing 26882 lines of which 24006 are not blank


Footnotes

1 Have you noticed that using UUID or GUID as the only column in a primary key really assists in normalising your database?
2Privately is emphasised here as I have worked with someone who just couldn't grasp the concept of open source, GPL etc.
3Java 21 is the new LTS, but I haven't checked to see if any of the new functionality would be useful for DAOMedge.
Return to Medge's Home Page


Viewed times.