MyBatis - microfox-framework/MicroFox GitHub Wiki
MicroFox integrates with MyBatis β a lightweight persistence framework that simplifies database interaction by mapping SQL queries to Java interfaces using annotations or XML.
Mappers in MyBatis are interfaces annotated with SQL commands. For example:
public interface ClientMapper {
@Insert("INSERT INTO client (id, name, family) VALUES (#{id}, #{name}, #{family})")
@SelectKey(statement = "SELECT client_seq.NEXTVAL FROM dual", keyProperty = "id", before = true, resultType = Long.class)
void save(Client client);
@Select("SELECT * FROM client")
@Results({
@Result(column = "id", property = "id"),
@Result(column = "name", property = "name"),
@Result(column = "family", property = "family"),
@Result(property = "addresses", column = "id",
many = @Many(select = "ir.moke.example.persistence.mapper.AddressMapper.findAddressByClientId"))
})
List<Client> findAll();
@Select("SELECT * FROM client WHERE id=#{id}")
@Results({
@Result(column = "id", property = "id"),
@Result(column = "name", property = "name"),
@Result(column = "family", property = "family"),
@Result(property = "addresses", column = "id",
many = @Many(select = "ir.moke.example.persistence.mapper.AddressMapper.findAddressByClientId"))
})
Client findById(long id);
}
The following setup initializes an H2 in-memory database using HikariCP as the connection pool, and registers mappers dynamically:
public class DB {
public static void initializeMyBatis() {
HikariConfig config = new HikariConfig();
config.setDriverClassName(Driver.class.getCanonicalName());
config.setJdbcUrl("jdbc:h2:mem:testdb;MODE=Oracle;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false");
config.setUsername("sa");
config.setPassword("sa");
HikariDataSource dataSource = new HikariDataSource(config);
Environment environment = new Environment("h2", new JdbcTransactionFactory(), dataSource);
Configuration configuration = new Configuration(environment);
configuration.setMapUnderscoreToCamelCase(true); // snake_case β camelCase
configuration.addMappers("ir.moke.example.persistence.mapper");
MicroFoxMyBatis.configure(dataSource, configuration);
}
}
Hereβs how a job inserts and queries data using mybatis() utility:
public class MyBatisRunner {
static {
DB.initializeMyBatis();
DB.initializeDatabase();
}
public static void main(String[] args) {
Address a1 = new Address("Iran", "Tehran", "Tehran", "Enghelab", "0123456789");
Address a2 = new Address("Iran", "Golestan", "Gorgan", "Azadi", "951753464");
Client client = new Client("Mahdi", "Sheikh Hosseini", List.of(a1, a2));
mybatis("h2", ClientMapper.class, mapper -> mapper.save(client));
mybatis("h2", AddressMapper.class, mapper -> mapper.save(a1, client));
mybatis("h2", AddressMapper.class, mapper -> mapper.save(a2, client));
mybatis("h2", AddressMapper.class, mapper -> {
mapper.findAll().forEach(addr -> System.out.println(JsonUtils.toJson(addr)));
});
}
}
For more flexibility, Provider classes can return dynamic SQL using MyBatis's fluent SQL builder:
public class AddressProvider {
public String insert(Map<String, Object> params) {
Address address = (Address) params.get("address");
Client client = (Client) params.get("client");
return new SQL()
.INSERT_INTO("address")
.VALUES(MyBatisUtils.getColumns(Address.class) + ", client_id",
MyBatisUtils.getValues(address) + "," + client.getId())
.toString();
}
}
- Insert, @Select, @Results annotations
- @SelectKey for database-generated IDs
-
Lazy-loading relations using
@Many
-
Dynamic SQL generation using
SQL
builder - In-memory database setup using HikariCP + H2
- Package-wide mapper registration
- Support for XML-based mappers alongside annotations
- Integration with JPA-like annotations for mapping entity relations
- Transactional unit-of-work abstraction
- Multi-database support per tenant/schema