-
-
Save trasa/1fbc60dc130231898273013492904e64 to your computer and use it in GitHub Desktop.
@Slf4j | |
@EnableSwagger2 | |
@SpringBootApplication | |
@EnableScheduling | |
@SuppressWarnings("unused") | |
public class Application extends SpringBootServletInitializer { | |
/** | |
* Create our JDBI singleton. Configure plugins. Set options, pooling, etc. | |
* | |
* @return Jdbi instance | |
*/ | |
@Bean | |
public Jdbi db() { | |
// connect to in memory db | |
// DB_CLOSE_DELAY=-1 says to keep the db around as long as | |
// the JVM is live (otherwise its gone as soon as there's no | |
// connections...leading to errors about insert failing because | |
// the table doesn't exist. | |
Jdbi jdbi = Jdbi.create("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"); | |
jdbi.installPlugin(new SqlObjectPlugin()); | |
// just for testing, create an in-memory table: | |
jdbi.useHandle(h -> h.execute("create table example (id integer primary key, name varchar)")); | |
jdbi.useHandle(h -> h.execute("insert into example (id, name) values (1, 'foo')")); | |
return jdbi; | |
} | |
/** | |
* Wire up our ExampleDao to spring. | |
* | |
* While I generally like the explicit approach, there are | |
* ways to have the wiring of @Repository beans happen | |
* automatically. | |
* | |
* @param jdbi | |
* @return | |
*/ | |
@Bean | |
public ExampleDao exampleDao(Jdbi jdbi) { | |
return jdbi.onDemand(ExampleDao.class); | |
} | |
} |
/** | |
* It's an Example DTO. So exciting. | |
*/ | |
@Getter | |
@Setter | |
@AllArgsConstructor | |
@NoArgsConstructor | |
public class Example { | |
int id; | |
String name; | |
} |
/** | |
* A very simple, boring Repository for our Example Beans. | |
* | |
* See http://jdbi.org/#_introduction_to_jdbi | |
* | |
* | |
* There's a lot of cool stuff that we can do using JDBI and the various | |
* mappers. Not showing that stuff here. | |
* | |
* Note that there are a few different ways to tie Spring and JDBI | |
* together, depending on how much spring-data and transaction management | |
* you want (i.e. how much like Hibernate/JPA do you want to be)... I | |
* prefer to keep things simple and avoid spring-data, JPA, and so on | |
* unless there's a really good cause for otherwise. | |
*/ | |
@Repository | |
@RegisterBeanMapper(Example.class) | |
public interface ExampleDao { | |
@SqlUpdate("insert into example (id, name) values (:id, :name)") | |
void add(@BindBean Example ex); | |
@SqlQuery("select * from example") | |
List<Example> getAll(); | |
} |
<project> | |
<properties> | |
<lib.jdbi.version>3.6.0</lib.jdbi.version> | |
... | |
</properties> | |
<plugin> | |
<configuration> | |
<source>${java.version}</source> | |
<target>${java.version}</target> | |
<compilerArgs> | |
<arg>-parameters</arg> | |
</compilerArgs> | |
</configuration> | |
</plugin> | |
<!-- JDBI 3 has a whole bunch of different modules. | |
http://jdbi.org/#_modules | |
I'm just doing the basics, particularly not getting | |
too far into things like jdbi3-spring4 integration. | |
--> | |
<dependency> | |
<groupId>org.jdbi</groupId> | |
<artifactId>jdbi3-core</artifactId> | |
<version>${lib.jdbi.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.jdbi</groupId> | |
<artifactId>jdbi3-sqlobject</artifactId> | |
<version>${lib.jdbi.version}</version> | |
</dependency> | |
<!-- test db: in memory database --> | |
<dependency> | |
<groupId>com.h2database</groupId> | |
<artifactId>h2</artifactId> | |
<version>1.4.197</version> | |
</dependency> | |
... | |
</project> |
It has been a long while since I've looked at this code, and I don't spend much time in Spring anymore. But, from what I recall, there were a couple of options - using the @ComponentScan
annotation to tell spring where to find your @Repository
s, and then having them take a Jdbi in their ctor. Then you're not using the interface and onDemand creation, which I don't think is a good tradeoff.
Or, better - use a package like Reflections and filters to find all classes annotated with Repository, and then for each, call jdbi.onDemand(class)
- this is what I've used to autowire message handlers when there's an arbitrary number of them and I definitely don't want to load them one at a time.
Sometimes I get pushback on using Reflections on startup like this as being "too magical", but hey, I like magic, that's why we were using Spring...
I've been looking around for a while trying to figure out how to have spring automatically use jdbi's on-demand for @ Repository-annotated interfaces but I cant seem to find anything. You mention there are ways, can you point me towards one?