Code Monkey home page Code Monkey logo

polyjdbc's Introduction

PolyJDBC

Build Status

PolyJDBC is a polyglot, lightweight wrapper around standard JDBC drivers with schema inspection/creation capabilities.

Why?

When developing SmartParam JDBC repository i realized that i was writing polyglot JDBC wrapper instead of focusing on core JDBC repository responsibilities. PolyJDBC came to life by extracting low-level wrapping code to separate project.

Before starting work on SmartParam JDBC repo i was looking for a good JDBC wrapper that would do more than suppress SQLExceptions. Specifically i was looking for transaction-aware wrapper that would also make it easy to perform DDL operations.

Target

PolyJDBC primary target are libraries that need light and cross-platform JDBC persistence. Hibernate is great, but it leaves little place for end-user customization, which is important when offering a library. It is also quite heavy. PolyJDBC size is only 75kB, no dependencies except for slf4j logging API.

Features

  • polyglot (or better poly-dialect? multiple DB dialect support, including id generation strategies)
  • transaction-oriented
  • resources (Statements, ResultSets) are managed inside transaction scope
  • intiutive transaction commit/rollback support
  • option to leave transaction management to external framework (i.e. Spring)
  • DDL operation DSL (CREATE TABLE/INDEX/SEQUENCE with constraints, DROP *)
  • SQL query DSL (INSERT, SELECT, UPDATE, DELETE)
  • lightweight
  • schema inspection (table/sequence exists?)
  • schema alteration

Supported database engines

  • H2
  • PostgreSQL
  • MySQL
  • Oracle
  • Microsoft SQL Server
  • DB2 and DB2400 (beta)

Thanks to testng magic PolyJDBC runs integration tests on each database. This way i can be sure that all features all supported across all engines.

How to get it?

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'org.polyjdbc', name: 'polyjdbc', version: '0.5.0'
}

Enough, show me the code

Instantiation

By default, PolyJDBC takes care of transaction management on it's own:

Dialect dialect = DialectRegistry.H2.getDialect();
PolyJDBC polyjdbc = PolyJDBCBuilder.polyJDBC(dialect).connectingToDataSource(dataSource).build();

But it is possible to leave connection management to any external framework:

Dialect dialect = DialectRegistry.H2.getDialect();
PolyJDBC polyjdbc = PolyJDBCBuilder.polyJDBC(dialect).usingManagedConnections(() -> frameworkManager::getConnection).build();

Querying

To ask simple questions, use simple tool. SimpleQueryRunner performs each query in new transaction:

SelectQuery query = polyJdbc.query().selectAll().from("test").where("name = :name")
        .withArgument("name", "test");
        
Test test = polyJdbc.simpleQueryRunner().queryUnique(query, new TestMapper());

You might want to span your transaction across multiple statements, if so use TransactionRunner:

TransactionRunner transactionRunner = polyjdbc.transactionRunner();

Test test = transactionRunner.run(new TransactionWrapper<Test>() {
    @Override
    public Test perform(QueryRunner queryRunner) {
        SelectQuery query = polyJdbc.query().selectAll().from("test").where("name = :name")
            .withArgument("name", "test");
        return queryRunner.queryUnique(query, new TestMapper());
    }
});

transactionRunner.run(new VoidTransactionWrapper() {
    @Override
    public void performVoid(QueryRunner queryRunner) {
        DeleteQuery query = polyJdbc.query().delete().from("test").where("year < :year")
            .withArgument("year", 2012);
        queryRunner.delete(query);
    }
});

Or if you need to get your hands dirty, see QueryRunner, but remember to free the resources:

QueryRunner queryRunner = null;

try {
    queryRunner = polyjdbc.queryRunner();
    SelectQuery query = polyJdbc.query().selectAll().from("test").where("year = :year")
        .withArgument("year", 2013).limit(10);
    List<Test> tests = queryRunner.selectList(query, new TestMapper());
    queryRunner.commit()
}
catch(Exception exception) {
    polyjdbc.rollback(queryRunner);
    throw exception;
}
finally {
    polyjdbc.close(queryRunner);
}

Schema management

PolyJDBC comes with tools for schema creating and deletion. More options for schema inspection are planned, although there is no concrete release date.

To check if relation exists:

SchemaInspector schemaInspector = null;
try {
    schemaInspector = polyjdbc.schemaInspector();
    boolean relationExists = schemaInspector.relationExists("testRelation");
} finally {
    polyjdbc.close(schemaManager);
}

To create new schema (group of relations):

SchemaManager schemaManager = null;
try {
    schemaManager = polyjdbc.schemaManager();

    Schema schema = new Schema(configuration.getDialect());
    schema.addRelation("test_one")
        .withAttribute().longAttr("id").withAdditionalModifiers("AUTO_INCREMENT").notNull().and()
        .withAttribute().string("name").withMaxLength(200).notNull().unique().and()
        .withAttribute().integer("age").notNull().and()
        .primaryKey("pk_test_one").using("id").and()
        .build();
    schema.addSequence("seq_test_one").build();
    schema.addRelation("test_two")
        .withAttribute().longAttr("id").withAdditionalModifiers("AUTO_INCREMENT").notNull().and()
        .withAttribute().longAttr("fk_test_one").notNull().and()
        .foreignKey("fk_test_one_id").references("test_one", "id").on("fk_test_one").and()
        .build();
    schema.addSequence("seq_test_two").build();

    schemaManager.create(schema);
} finally {
    polyjdbc.close(schemaManager);
}

You don't need to define Schema object. Single Relation, Sequence or Index can be created using SchemaManager as well.

License

PolyJDBC is published under Apache License 2.0.

Changelog

  • 0.6.3 (05.10.2016)
    • added the possibility to create relations in given schema (pr by @ianagius)
  • 0.5.0
    • added possibility to plug in external framework for transaction management
    • [API change] PolyJDBC is build using PolyJDBCBuilder
  • 0.4.0 (24.08.2014)
    • fixed bug with closing transaction on exception in query runners
    • [API change] QueryRunner.close() does not commit, use QueryRunner.commit() explicitly
    • [API change] some queries from QueryFactory.* now need Dialect (better Oracle support in future), use dialect-aware PolyJDBC.query()
  • previous versions
    • support for PostgreSQL, MySQL, H2 and partial support for Oracle

polyjdbc's People

Contributors

adamdubiel avatar bartoszwalacik avatar glebexadel avatar ianagius avatar marvindaviddiaz avatar mdii avatar pszymczyk avatar raupachz avatar wcchristian avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.