Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/buggins/hibernated
HibernateD is ORM for D language (similar to Hibernate)
https://github.com/buggins/hibernated
Last synced: 3 months ago
JSON representation
HibernateD is ORM for D language (similar to Hibernate)
- Host: GitHub
- URL: https://github.com/buggins/hibernated
- Owner: buggins
- Created: 2013-04-12T09:59:10.000Z (over 11 years ago)
- Default Branch: master
- Last Pushed: 2024-05-14T16:00:50.000Z (6 months ago)
- Last Synced: 2024-05-15T07:27:23.299Z (6 months ago)
- Language: D
- Size: 1000 KB
- Stars: 82
- Watchers: 14
- Forks: 31
- Open Issues: 17
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-d - hibernated - HibernateD is an ORM for D (similar to [Hibernate](https://hibernate.org/)). (Database clients / XML)
README
HibernateD
==========[![DUB Package](https://img.shields.io/dub/v/hibernated.svg)](https://code.dlang.org/packages/hibernated) [![GitHub CI](https://github.com/buggins/hibernated/actions/workflows/dub.yml/badge.svg)](https://github.com/buggins/hibernated/actions/workflows/dub.yml) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/buggins/hibernated?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
HibernateD is ORM for D language (similar to Hibernate)
The project is hosted on [github](https://github.com/buggins/hibernated) with documentation available on the [wiki](https://github.com/buggins/hibernated/wiki).
Uses [DDBC](https://github.com/buggins/ddbc) as an abstraction layer for the underlying database. DDBC currently supports SQLite, MySQL, Postgres, SQL Server, and potentially Oracle.
## SQL dialects supported by Hibernated
Currently hiberanted supports:
- SQLite (requires SQLite v3.7.11 or later)
- MySQL (tests are run against mysql v5.7)
- PostgresBut since the underlying DDBC library now has ODBC support some work is underway to also add
- SQL Server (2017 & 2019)
- Oracle (due to the size of the docker image for Oracle this may not be tested during CI)## Sample code:
```D
import hibernated.core;
import std.algorithm;// 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;
}int main() {
// create metadata from annotations
EntityMetaData schema = new SchemaInfoImpl!(User, Customer, AccountType,
Address, Role);// setup DB connection factory
version (USE_MYSQL) {
import ddbc.drivers.mysqlddbc;
MySQLDriver driver = new MySQLDriver();
string url = MySQLDriver.generateUrl("localhost", 3306, "test_db");
string[string] params = MySQLDriver.setUserAndPassword("testuser", "testpasswd");
Dialect dialect = new MySQLDialect();
} else {
import ddbc.drivers.sqliteddbc;
SQLITEDriver driver = new SQLITEDriver();
string url = "zzz.db"; // file with DB
static import std.file;
if (std.file.exists(url))
std.file.remove(url); // remove old DB file
string[string] params;
Dialect dialect = new SQLiteDialect();
}
DataSource ds = new ConnectionPoolDataSourceImpl(driver, url, params);// create session factory
SessionFactory factory = new SessionFactoryImpl(schema, dialect, ds);
scope(exit) factory.close();// Create schema if necessary
{
// get connection
Connection conn = ds.getConnection();
scope(exit) conn.close();
// create tables if not exist
factory.getDBMetaData().updateDBSchema(conn, false, true);
}// Now you can use HibernateD
// create session
Session sess = factory.openSession();
scope(exit) sess.close();// use session to access DB
// read all users using query
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";
c10.address = new Address();
c10.address.zip = "12345";
c10.address.city = "New York";
c10.address.streetAddress = "Baker st., 12";
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 = u11.roles().remove(0);
sess.update(u11);// remove entity
sess.remove(u11);
return 0;
}
```## Additional Features
### Composite Keys
If a database contains tables with a composite primary key, the `@EmbeddedId` can be used to
represent this. The columns that represent the primary key should be in an `@Embeddable` class
which is then referenced in a property annotated with `@EmbeddedId`.For example, consider a database table created via the following SQL command:
```sql
CREATE TABLE invoices (
vendor_no VARCHAR(8) NOT NULL,
invoice_no VARCHAR(20) NOT NULL,
amount_e4 INTEGER);
ALTER TABLE invoices
ADD CONSTRAINT invoices_pkey PRIMARY KEY (vendor_no, invoice_no);
```To represent this using HibernateD, the following code would be used:
```
@Embeddable
class InvoiceId {
string vendorNo;
string invoiceNo;// Be sure to implement this to benefit from session caching.
bool opEquals(const InvoiceId o) const @safe {
return vendorNo == o.vendorNo && invoiceNo == o.invoiceNo;
}
}@Table("invoices")
class Invoice {
@EmbeddedId InvoiceId invoiceId;
int amountE4;
}
```**Note**: At the time of writing, there are important limitations.
1. The function `DBInfo.updateDbSchema(Connection conn, bool dropTables, bool createTables)`
does not generate schemas with compound keys.
2. The Hibernate annotation `@JoinColumns` (plural) has not yet been implemented, thus,
the `@ManyToOne` and `@ManyToMany` relations are not usable for classes using an
`@EmbeddedId`.
3. The `@Embedded` class referenced via an `@EmbeddedId` property should implement `opEquals`
in order to gain performance benefits from session caching.
These features will be added in future updates.