All Projects → dieselpoint → Norm

dieselpoint / Norm

Licence: other
Access a database in one line of code.

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Norm

Sqlhelper
SQL Tools ( Dialect, Pagination, DDL dump, UrlParser, SqlStatementParser, WallFilter, BatchExecutor for Test) based Java. it is easy to integration into any ORM frameworks
Stars: ✭ 242 (+59.21%)
Mutual labels:  sql, orm, jdbc, database
Jooq
jOOQ is the best way to write SQL in Java
Stars: ✭ 4,695 (+2988.82%)
Mutual labels:  sql, orm, jdbc, database
Ebean
Ebean ORM
Stars: ✭ 1,172 (+671.05%)
Mutual labels:  sql, orm, jdbc, database
Nano Sql
Universal database layer for the client, server & mobile devices. It's like Lego for databases.
Stars: ✭ 717 (+371.71%)
Mutual labels:  sql, orm, database
Go Sqlbuilder
A flexible and powerful SQL string builder library plus a zero-config ORM.
Stars: ✭ 539 (+254.61%)
Mutual labels:  sql, orm, database
Jailer
Database Subsetting and Relational Data Browsing Tool.
Stars: ✭ 576 (+278.95%)
Mutual labels:  sql, jdbc, database
Pg
Golang ORM with focus on PostgreSQL features and performance
Stars: ✭ 4,918 (+3135.53%)
Mutual labels:  sql, orm, database
Fluent
Vapor ORM (queries, models, and relations) for NoSQL and SQL databases
Stars: ✭ 1,071 (+604.61%)
Mutual labels:  sql, orm, database
Express Knex Objection
A simple API system on a pg database, using knex and objection to simplify connection and management
Stars: ✭ 20 (-86.84%)
Mutual labels:  sql, orm, database
Dbx
A neat codegen-based database wrapper written in Go
Stars: ✭ 68 (-55.26%)
Mutual labels:  sql, orm, database
Evolutility Server Node
Model-driven REST or GraphQL backend for CRUD and more, written in Javascript, using Node.js, Express, and PostgreSQL.
Stars: ✭ 84 (-44.74%)
Mutual labels:  sql, orm, database
Qb
The database toolkit for go
Stars: ✭ 524 (+244.74%)
Mutual labels:  sql, orm, database
Ragtime
Database-independent migration library
Stars: ✭ 519 (+241.45%)
Mutual labels:  sql, jdbc, database
Godb
A Go SQL query builder and struct mapper.
Stars: ✭ 651 (+328.29%)
Mutual labels:  sql, orm, database
Hibernate Orm
Hibernate's core Object/Relational Mapping functionality
Stars: ✭ 4,806 (+3061.84%)
Mutual labels:  orm, jdbc, database
Gorose
GoRose(go orm), a mini database ORM for golang, which inspired by the famous php framwork laravle's eloquent. It will be friendly for php developer and python or ruby developer. Currently provides six major database drivers: mysql,sqlite3,postgres,oracle,mssql, Clickhouse.
Stars: ✭ 947 (+523.03%)
Mutual labels:  sql, orm, database
Snowflake Jdbc
Snowflake JDBC Driver
Stars: ✭ 83 (-45.39%)
Mutual labels:  sql, jdbc, database
Sequelize Ui
Browser-based GUI for previewing and generating Sequelize project files.
Stars: ✭ 142 (-6.58%)
Mutual labels:  sql, orm, database
Android Orma
An ORM for Android with type-safety and painless smart migrations
Stars: ✭ 442 (+190.79%)
Mutual labels:  sql, orm, database
Nymph
Data objects for JavaScript and PHP.
Stars: ✭ 97 (-36.18%)
Mutual labels:  sql, orm, database

Norm

Read a blog post on this project.

Norm is a simple way to access a JDBC database, usually in one line of code. It purges your code of the complex mess that is Hibernate, JPA, and ORM.

Lots of people think that complex ORMs are a bad idea.

Here it is:

List<Person> people = db.where("name=?", "Bob").results(Person.class);

Get Started

Configure your system.

Start with this sample code.

Overview

Norm is an extremely lightweight layer over JDBC. It gets rid of large amounts of boilerplate JDBC code. It steals some ideas from ActiveJDBC, which is a very nice system, but requires some very ugly instrumentation / byte code rewriting.

Why?

Sometimes the most important thing about writing software is knowing when to stop. A solution that gets you 90% of the way is often good enough, because the other 90% isn't worth the hassle. In this case, Norm gives you a fast and convenient way to do select, insert, update and delete, and when you need more, you just drop into straight SQL.

Norm returns results as a list of POJOs or as a List of Map objects, whichever you prefer.

POJOs are fabulous, truly fabulous:

  • Populating them is really fast with the newer JVMs.
  • You can use them for declaratory data validation.
  • Using Jackson, you can serialize them to JSON.

which means that, yes, you can use the same class to fetch a record from a database and then create JSON from it.

Sample Code

There's a full example here.

Database db = new Database();

Person joe = new Person();
joe.firstName = "Joe";
joe.lastName = "Sixpack";

db.insert(joe);

List<Person> people = db.where("lastname=?", "Sixpack").orderBy("lastName").results(Person.class);

The Person class:

@Table(name="people")
class Person {
	public String firstName;
	public String lastName;
    // you can also use getters and setters
}

You can modify your database using .insert(), .upsert(), .update(), .delete(), and .sql().execute():

int rowsAffected = db.table("people").where("firstName=?", "Joe").delete();

// or just:
int rowsAffected = db.delete(joe);

// rowsAffected will equal the number of rows inserted, updated, or deleted

When you need more than this, just use straight SQL. This is the best way to do joins:

List<MyPojo> list1 = db.sql(
    "select lastname, sum(amount) from account, transaction " + 
    "where account.accountId = transaction.accountId " +
	"and date > ?", "2000-01-01")
	.results(MyPojo.class);

You can also use straight SQL to modify the database:

db.sql("drop table people").execute();

Maps and Lists

Don't want to create a new POJO class for every query? No problem, just use a Map:

List<Map> list = db.sql("select * from people").results(HashMap.class);

HashMap, LinkedHashMap or any class that implements the Map interface will work.

Note that you must specify full sql, or at a minimum a table name, because the system won't be able to guess the table name from the Map class. Unless you've annotated it to that effect.

Primitives

A single column result set can come back in the form of a list of primitives, or even as a single primitive.

Long count = db.sql("select count(*) from people").first(Long.class);

It's sometimes really useful to get a result in the form of a List<String>.

Note that you have to specify the full sql when doing primitives because the system won't be able to guess the column or tables names from the primitive class.

Annotations

Tell the system what to do with your POJOs by using a few annotations. Norm implements a subset of the javax.persistence annotations, including @Table, @Id, @GeneratedValue, @Transient, @Column and @Enumerated.

@Table(name="people")
public class Person {
	@Id
	@GeneratedValue
	public long personId;

	public String name;

	@Column(name = "theColumnName")
	public String renameThis;

	@Transient
	public String thisFieldGetsIgnored;
}

@Table specifies the table name. If it's not there, the table defaults to the class name.

@Id specifies the primary key. The system uses this to identify the record to delete or update.

@GeneratedValue indicates that the field is marked AUTO_INCREMENT and will be generated on the server. This prevents the field from being inserted, and it fills in the value in the POJO after an insert.

@Transient tells the system to ignore the field. It doesn't get persisted to the database. (Note that this is javax.persistence.Transient, not java.beans.Transient. Different annotations.)

@Column implements a subset of javax.persistence.Column. Column.name will attach a property to a database column of a different name. Column.unique, .nullable, .length, .precision, and .scale apply when you call Database.createTable();

@Enumerated specifies the type of the enumeration to be stored in the database. By default EnumType.STRING is used for string representation. One can select EnumType.ORDINAL for integer representation.

Column-level annotations can go on either a public property or on a public getter for the property. Annotations on setters will be ignored.

Transactions

If you need multiple database operations to succeed or fail as a unit, use a transaction. The basic scheme is to create a Transaction object, pass it to every query that needs it, and then .commit() or .rollback().

Transaction trans = db.startTransaction();
try {
	db.transaction(trans).insert(row1);
	db.transaction(trans).update(row2);
	trans.commit();
} catch (Throwable t) {
	trans.rollback();
} 

Transaction is a pretty simple class, so if it doesn't do what you need, just subclass it and make it behave differently.

Custom Serialization

The older @DbSerializable and @DbSerializer annotations are now deprecated. Use @Convert and an AttributeConverter class instead.

Norm now supports JPA serialization. We'll add a bit more documentation here later, but for now you can learn all about it here:

https://thoughts-on-java.org/jpa-21-how-to-implement-type-converter/

and here:

https://www.baeldung.com/jpa-attribute-converters

In short, @Convert give you a way of converting a particular column datatype in your database to a particular datatype in your POJO. So, you can store a list of integers in your database as String, and in your POJO as List<Integer>.

Note that you can sometimes achieve the same purpose by using appropriate getters and setters on your POJO. Mark the ones that Norm should ignore with @Transient.

Pluggable SQL Flavors

You can specify the particular flavor of SQL for your database with Database.setSqlMaker(). By default, the StandardSqLMaker will handle most needs. As of version 0.8.1, there is also a MySqlMaker class that will handle MySql-style upserts. To implement your own flavor, subclass StandardSqlMaker and possibly StandardPojoInfo and do what you need.

Database db = new Database();
db.setSqlMaker(new MySqlMaker());

Some database-specific notes:

MySQL: Should work out of the box.

Postgres: Inexplicably, Postgres converts all column names to lowercase when you create a table, and forces you to use double quotes around column names if you want mixed or upper case. The workaround is to add an @Column(name="somelowercasename") annotation to the fields in your pojo.

H2: Does the opposite of Postgres. It forces all column names to upper case. Avoid the problem by adding the database_to_upper option to the jdbcUrl: jdbc:h2:./h2test;database_to_upper=false

Configuration

Here's the Maven dependency:

<dependency>
    <groupId>com.dieselpoint</groupId>
    <artifactId>norm</artifactId>
    <version>0.8.5</version>
</dependency>

To specify the database connection parameters:

Database db = new Database();
db.setJdbcUrl("jdbc:mysql://localhost:3306/mydb?useSSL=false");
db.setUser("root");
db.setPassword("rootpassword");

or

System.setProperty("norm.jdbcUrl", "jdbc:mysql://localhost:3306/mydb?useSSL=false");
System.setProperty("norm.user", "root");
System.setProperty("norm.password", "rootpassword");

Internally, Norm uses the Hikari connection pool. Hikari allows you to use the jdbcUrl method or DataSource class names. Your database is bound to be on the list.

If you don't want to use system properties, or your DataSource needs some custom startup parameters, just subclass the Database class and override the .getDataSource() method. You can supply any DataSource you like.

Dependencies

Norm needs javax.persistence, but that's just for annotations.

It also has a dependency on HikariCP for connection pooling, but that's entirely optional. If you don't want it, add an <exclude> to the Norm dependency in your project's pom. Then subclass Database and override the getDataSource() method.

Finally, you'll need to include your JDBC driver as a dependency. Here's a sample for MySQL:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.15</version>
</dependency>

That's about it. Post any bugs or feature requests to the issue tracker.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].