All modules are hosted on Bintray's JCenter repository.
To add to Maven:
<repositories>
<!-- ... -->
<repository>
<id>jcenter</id>
<url>https://jcenter.bintray.com/</url>
</repository>
</repository>
To add to Gradle:
repositories {
jcenter()
}
You can also download the JARs by hand from Bintray, but you'll need Dropwizard and its dependencies, too. Really, use a dependency manager. You'll be happier.
Add a dependency on com.loginbox.mybatis:dropwizard-mybatis:+
to your
project, then proceed.
A mapper interface defines methods that map to SQL queries or procedure calls. For example, an interface for managing users might look like
package com.example.helloworld.mappers;
public interface UsersMapper {
User findByUsername(@Param("username") String username);
void addUser(@Param("user") User user);
}
MyBatis binds these interfaces to actual SQL stored in a mapper config file in
the same package. In this case, UsersMapper.xml
would look like this:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.helloworld.mappers.UsersMapper">
<select id="findByUsername" resultType="User">
<![CDATA[
select username, email
from users
where username = #{username}
]]>
</select>
<resultMap id="User" type="com.example.helloworld.mappers.User">
<id column="username" property="username" />
<result column="email" property="email" />
</resultMap>
<insert id="addUser">
<![CDATA[
insert into users (username, email)
values (#{user.username}, #{user.email})
]]>
</insert>
</mapper>
See the MyBatis documentation for more thorough examples, covering things like nested results and complex relational mapping for joins.
Before you can use MyBatis in your Dropwizard app, you'll need to configure a database connection pool in your application configuration class:
package com.example.helloworld;
/* imports */
public class HelloWorldConfiguration extends Configuration {
@Valid
@NotNull
private DataSourceFactory dataSourceFactory = new DataSourceFactory();
@JsonProperty("database")
public DataSourceFactory getDataSourceFactory() {
return this.dataSourceFactory;
}
}
You can configure the database connection in your config file:
database:
# the name of your JDBC driver
driverClass: org.postgresql.Driver
# the username
user: pg-user
# the password
password: iAMs00perSecrEET
# the JDBC URL
url: jdbc:postgresql://db.example.com/db-prod
# any properties specific to your JDBC driver:
properties:
charSet: UTF-8
# the maximum amount of time to wait on an empty pool before throwing an exception
maxWaitForConnection: 1s
# the SQL query to run when validating a connection's liveness
validationQuery: "/* MyService Health Check */ SELECT 1"
# the timeout before a connection validation queries fail
validationQueryTimeout: 3s
# the minimum number of connections to keep open
minSize: 8
# the maximum number of connections to keep open
maxSize: 32
# whether or not idle connections should be validated
checkConnectionWhileIdle: false
# the amount of time to sleep between runs of the idle connection validation, abandoned cleaner and idle pool resizing
evictionInterval: 10s
# the minimum amount of time an connection must sit idle in the pool before it is eligible for eviction
minIdleTime: 1 minute
Once your database connection is configured, you can register a MybatisBundle
during your application's bootstrap. I strongly recommend storing the bundle in
a private final
attribute on your application class, for later use:
package com.example.helloworld;
public class HelloWorld extends Application<HelloWorldConfiguration> {
public static void main(String... args) throws Exception {
new HelloWorld().run(args);
}
private final MybatisBundle<HelloWorldConfiguration> mybatisBundle
= new MybatisBundle<HelloWorldConfiguration>("com.example.helloworld") {
@Override
public DataSourceFactory getDataSourceFactory(HelloWorldConfiguration configuration) {
return configuration.getDataSourceFactory();
}
};
@Override
public void initialize(Bootstrap<HelloWorldConfiguration> bootstrap) {
bootstrap.addBundle(mybatisBundle);
}
// . . .
}
You can use MyBatis from your resource classes by calling
getSqlSessionFactory()
on the bundle to get its session factory:
public void run(HelloWorldConfiguration configuration, Environment environment) throws Exception {
SqlSessionFactory sessionFactory = mybatisBundle.getSqlSessionFactory();
environment.jersey().register(new ExampleResource(sessionFactory));
// . . .
}
The SqlSessionFactory
will only be available after initialize
completes.
Your resources can use the SqlSessionFactory
's openSession()
methods to
begin database conversations:
package com.example.helloworld.resources;
@Path("/user/{username}")
public class ExampleResource {
private final SqlSessionFactory sessionFactory;
public ExampleResource(SqlSessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@GET
public User getUser(@PathParam("username") String username) {
try (SqlSession session = sessionFactory.openSession()) {
UsersMapper users = session.getMapper(UsersMapper.class);
return users.findByUsername(username);
}
}
}
At present, MybatisBundle
doesn't provide any kind of automated transaction
management. Applications are responsible for demarcating their own transactions
using the session's commit()
and rollback()
methods.
This bundle includes an injection provider for SqlSession
, scoped to the
current HTTP request. Multiple injection targets within the same request will
receive the same SqlSession
object, allowing them to share a database context:
package com.example.helloworld.resources;
@Path("/user/{username}")
public class InjectionExampleResource {
@GET
public User getUser(
@PathParam("username") String username,
@Context SqlSession sqlSession) {
UsersMapper users = session.getMapper(UsersMapper.class);
return users.findByUsername(username);
}
}
The session will be automatically closed at the end of the request. As with manual session management, this does not provide automatic transaction management.
In addition to MyBatis' suite of built-in types, this bundle automatically registers support for the following types:
java.net.URL
java.net.URI
java.util.UUID
java.util.Optional
com.google.common.base.Optional