NOTE: Project has been divided into 2 subprojects (DDBC and HibernateD) and moved to GitHub!
https://github.com/buggins/ddbc
https://github.com/buggins/hibernated
HibernateD is ORM (Object/Relation Mapping) library for D language with interface and annotations similar to Hibernate ORM for Java.
Contains [DDBC] - D DataBase Connector - similar to JDBC (currently has MySQL and SQLite drivers) - which is used as DB abstraction layer.
You can annotate your classes with Hibernate-like [Annotations], to add persistance.
Hibernated [Session] allows to save, update, delete, load objects from DB, query DB using [HQL] (Hibernate Query Language).
Simple properties of supported: you can annotate fields, D properties or getter+setter pairs in your class, of types string, byte, short, int, long, ubyte, ushort, uint, ulong, byte[], ubyte[], DateTime, Date, TimeOfDay; for non-nullable types to support Null value use Nullable! template.
@Embedded entities supported - you can embed properties from @Embeddable object to @Entity's table.
@OneToOne, @OneToMany, @ManyToOne, @ManyToMany relations are supported. You can use Lazy! and LazyCollection! to support lazy loading of aggregates.
import ddbc.drivers.mysqlddbc; import hibernated.core; import hibernated.dialects.mysqldialect; // Annotations of entity classes class User { long id; string name; Customer customer; @ManyToMany // cannot be inferred, requires annotation LazyCollection!Role roles; } class Customer { int id; string name; // Embedded is inferred from type of Address Address address; Lazy!AccountType accountType; // ManyToOne inferred User[] users; // OneToMany inferred this() { address = new Address(); } } @Embeddable class Address { string zip; string city; string streetAddress; } class AccountType { int id; string name; } class Role { int id; string name; @ManyToMany // w/o this annotation will be OneToMany by convention LazyCollection!User users; } // setup DB connection MySQLDriver driver = new MySQLDriver(); string url = MySQLDriver.generateUrl(MYSQL_UNITTEST_HOST, MYSQL_UNITTEST_PORT, MYSQL_UNITTEST_DB); string[string] params = MySQLDriver.setUserAndPassword(MYSQL_UNITTEST_USER, MYSQL_UNITTEST_PASSWORD); DataSource ds = ConnectionPoolDataSourceImpl(driver, url, params); // create metadata from annotations EntityMetaData schema = new SchemaInfoImpl!(User, Customer, AccountType, T1, TypeTest, Address, Role, GeneratorTest); // create session factory Dialect dialect = new MySQLDialect(); SessionFactory factory = new SessionFactoryImpl(schema, dialect, ds); scope(exit) factory.close(); // create session Session sess = factory.openSession(); scope(exit) sess.close(); // use session to access DB Query q = sess.createQuery("FROM User ORDER BY name"); User[] list = q.list!User(); // create sample data Role r10 = new Role(); r10.name = "role10"; Role r11 = new Role(); r11.name = "role11"; Customer c10 = new Customer(); c10.name = "Customer 10"; User u10 = new User(); u10.name = "Alex"; u10.customer = c10; u10.roles = [r10, r11]; sess.save(r10); sess.save(r11); sess.save(c10); sess.save(u10); // load and check data User u11 = sess.createQuery("FROM User WHERE name=:Name").setParameter("Name", "Alex").uniqueResult!User(); assert(u11.roles.length == 2); assert(u11.roles[0].name == "role10" || u11.roles.get()[0].name == "role11"); assert(u11.roles[1].name == "role10" || u11.roles.get()[1].name == "role11"); assert(u11.customer.name == "Customer 10"); assert(u11.customer.users.length == 1); assert(u11.customer.users[0] == u10); assert(u11.roles[0].users.length == 1); assert(u11.roles[0].users[0] == u10); // remove reference u11.roles.get().remove(0); sess.update(u11); // remove entity sess.remove(u11);
Added DB tables and indexes generation.
Added DDBC SQLite driver.
Wiki: Annotations
Wiki: DDBC
Wiki: HQL
Wiki: Query
Wiki: Session