Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

What is New in RavenDB 3.0: JVM Client API

DZone's Guide to

What is New in RavenDB 3.0: JVM Client API

· Java Zone ·
Free Resource

RavenDB vs MongoDB: Which is Better? This White Paper compares the two leading NoSQL Document Databases on 9 features to find out which is the best solution for your next project.  

RavenDB has always been accessible from other platforms. We have users using RavenDB from Python and Node.JS, we also have users using Ruby & PHP, although there isn’t a publicly available resource for that.

With RavenDB 3.0, we release an official Java Client API for RavenDB. Using it is pretty simple if you are familiar with the RavenDB API or the Hibernate API.

We start by creating the document store:

IDocumentStore store = new DocumentStore(ravenDbUrl, "todo-db");
store.initialize();
store.executeIndex(new TodoByTitleIndex());

Note that we have an compiled index as well here, which looks like this:

public class TodoByTitleIndex extends AbstractIndexCreationTask {

    public TodoByTitleIndex() {
        map = "from t in docs.todos select new { t.Title, t.CreationDate } ";
        QTodo t = QTodo.todo;
        index(t.title, FieldIndexing.ANALYZED);
    }
}

Since Java doesn’t have Linq, we use the Querydsl to handle that. The index syntax is still Linq on the server side, though.

That is enough about setup, let us see how we can actually work with this. Here is us doing a search:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    ServletContext context = request.getSession().getServletContext();
    IDocumentStore store = (IDocumentStore) context.getAttribute(ContextManager.DOCUMENT_STORE);

    String searchText = request.getParameter("search");

    try (IDocumentSession session = store.openSession()) {
        QTodo t = QTodo.todo;

        IRavenQueryable<Todo> query = session.query(Todo.class, TodoByTitleIndex.class)
            .orderBy(t.creationDate.asc());

        if (StringUtils.isNotBlank(searchText)) {
            query = query.where(t.title.eq(searchText));
        }

        List<Todo> todosList = query.toList();

        response.getWriter().write(RavenJArray.fromObject(todosList).toString());
        response.getWriter().close();

    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

Basically, we get the store from the context, and then open a session. You can see the fluent query API, and how we work with sessions.

A more interesting example, albeit simpler, is how we write:

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
    IOException {
    ServletContext context = request.getSession().getServletContext();
    IDocumentStore store = (IDocumentStore) context.getAttribute(ContextManager.DOCUMENT_STORE);

    try (IDocumentSession session = store.openSession()) {
        Todo todo = new Todo(request.getParameter("title"));
        session.store(todo);
        session.saveChanges();

    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

This API should be instantly familiar for any RavenDB or Hibernate users. As for the actual entity definition, here it goes:

@QueryEntity
public class Todo {

    private Boolean completed;
    private Date creationDate;
    private Integer id;
    private String title;

    public Todo() {
        super();
    }

    public Todo(final String title) {
        super();
        this.title = title;
        this.creationDate = new Date(System.currentTimeMillis());
    }

    public Boolean getCompleted() {
        return completed;
    }

    public Date getCreationDate() {
        return creationDate;
    }

    public Integer getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }

    public void setCompleted(Boolean completed) {
        this.completed = completed;
    }

    public void setCreationDate(Date creationDate) {
        this.creationDate = creationDate;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    @Override
    public String toString() {
        return "Todo [title=" + title + ", completed =" + completed + ", creationDate=" + creationDate + ", id=" + id
            + "]";
    }
}
Except for the @QueryEntity annotation, it is a plain old Java class.
And of course, I’m using the term Java Client API, but this is actually available for any JVM language. Including Groovy, Scala and Clojure*.
* There is actually a  dedicated RavenDB client for Clojure, written by Mark Woodhall.

Do you pay to use your database? What if your database paid you? Learn more with RavenDB.

Topics:

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}