-
Notifications
You must be signed in to change notification settings - Fork 24
Introduction
Mirage is an easy and powerful SQL centric database access library. It provides two main features below:
-
2WaySQL
The main feature of Mirage is 2WaySQL. This makes plain old SQL template, and it is executable using any SQL client tools because parameters and conditions are written as SQL comment.
-
SQL less Update
Generally, update processing are simpler than search processing. However, especially, large INSERT SQL brings us the considerable pain. In the Mirage, you can insert / update / delete records using entity class (without SQL).
At first, see the Configuration to setup Mirage.
The basic example of searching using the SQL file. SqlManager
is a main interface of Mirage. You can get it from Session
and you can control transaction using Session
also.
Session session = SessionFactory.getSession();
SqlManager sqlManager = session.getSqlManager();
session.begin();
try {
BookParam param = new BookParam();
List<Book> result = sqlManager.getResultList(
Book.class, "/META-INF/selectBooks.sql", param);
// ...
session.commit();
} catch(Exception ex) {
session.rollback();
} finally {
session.release();
}
Book
is a POJO to mapping ResultSet
:
public class Book {
public Long bookId;
public String bookName;
public String author;
public Integer price;
}
BookParam
is a parameter class:
public class BookParam {
public String author;
public Integer minPrice;
public Integer maxPrice;
}
/META-INF/selectProducts.sql:
SELECT * FROM BOOK
/*BEGIN*/
WHERE
/*IF author != null */
AUTHOR = /*author*/'Naoki Takezoe'
/*END*/
/*IF minPrice != null */
AND PRICE >= /*minPrice*/20
/*END*/
/*IF maxPrice != null */
AND PRICE <= /*maxPrice*/100
/*END*/
/*END*/
ORDER BY BOOK_ID ASC
Mirage supports 2WaySQL. This is based on Japanese O/R mapping framework S2JDBC. 2WaySQL is the plain old SQL template. You can specify parameters and conditions using SQL comment. So these SQLs are executable using SQL client tools.
For exmaple, the following SQL has a SQL comment(/*author*/
), however it is executable as SQL.
SELECT * FROM BOOK
WHERE AUTHOR = /*author*/'Naoki Takezoe'
ORDER BY BOOK_ID ASC
Mirage replaces /*author*/
to a place holder and removes a word ('Naoki Takezoe'
) after replaced SQL comment. Actually, Mirage would execute the following SQL.
SELECT * FROM BOOK
WHERE AUTHOR = ?
ORDER BY BOOK_ID ASC
See 2WaySQL to know details about 2WaySQL.
Mirage can insert / update / delete using entity object (without SQL file).
Entity Class must have a primary key field with @PrimaryKey
annotation:
public class Book {
@PrimaryKey(generationType=GenerationType.IDENTITY)
public Long bookId;
public String bookName;
public String author;
public Integer price;
}
You should specify the generation type of primary keys. Mirage supports following generation types:
-
GenerationType.APPLICATION
Primary keys have to be set by the application before invocation of
SqlManager#insertEntity()
.
@PrimaryKey(generationType=GenerationType.APPLICATION)
public Long id;
-
GenerationType.IDENTITY
Primary keys are set by database automatically. Database have to support
PreparedStatement.RETURN_GENERATED_KEYS
to acquire generated keys. Oracle does not support this feature.
@PrimaryKey(generationType=GenerationType.IDENTITY)
public Long id;
-
GenerationType.SEQUENCE
Primary keys are set by Mirage using sequence. In this strategy, you have to specify the sequence name at generator attribute of
@PrimaryKey
annotation.
@PrimaryKey(generationType=GenerationType.SEQUENCE, generator="USER_ID_SEQ")
public Long id;
Example to insert an entity using SqlManager#insertEntity()
:
Book book = new Book();
book.bookName = "Mirage in Action";
book.author = "Naoki Takezoe";
book.price = 20;
sqlManager.insertEntity(entity);
You can also select entity using SqlManager#findEntity()
.
Book book = sqlManager.findEntity(Book.class, bookId);
Please note that Mirage does not support relationship between entities because it may bring complexity into Mirage.
SqlManager#getResultList()
creates all entity instances and returns a list which contains them. If SQL returns a large result, it causes OutOfMemory.
In these case, you should use SqlManager#iterate()
instead of SqlManager#getResultList()
.
Integer result = sqlManager.iterate(
Book.class,
new IterationCallback<Book, Integer>() {
private int result;
@Override public Integer iterate(Book entity) {
result = result + entity.price;
return result;
}
},
SQL_PREFIX + "SqlManagerImplTest_selectBooks.sql");
SqlManager#iterate()
accepts IterationCallback
and invoke it per record. The return value of SqlManager#iterate()
is a last returned value from IterationCallback
.
If you want to break iteration search on the way, throw BreakIterationException
from IterationCallback
. By this exception, iteration search is stopped and SqlManager#iterate()
returns the previous returned value from IterationCallback
. If BreakIterationException
is thrown at first IterationCallback#iterate()
invocation, SqlManager#iterate()
returns null.
Mirage can call stored procedures / functions by database independed way.
-
SqlManager#call()
Calls the procedure or the function which returns the single result.
-
SqlManager#callForList()
Calls the function which returns the result list.
// Parameter class
public class GetCountParam {
@In
public long deptId;
}
// Creates parameter object which give to stored function
GetCountParam param = new GetCountParam();
param.deptId = 1;
// Calls a stored function and get a result value.
Long count = sqlManager.call(Long.class, "get_emp_count", param);
Fields of the parameter class has annotation such as @In
, @Out
, @InOut
and @ResultSet
. These annotations mean the parameter type.
- The field has no annotation or it has
@In
annotation, it means the IN parameter. - The field has
@Out
annotation, it means the OUT parameter. - The field has
@InOut
annotation, it means the INOUT parameter. - The field has
@ResultSet
annotation, it's mapped to the result set which is not returned as a parameter. In the database which can return a result set as a parameter only such as Oracle or PostgreSQL,@ResultSet
field means the OUT parameter.