I work with Mongo and Java. Actually I use Criteria to make select .
for example
Criteria.where("customerType").is(customerType) (1)
for me customerType is key in MongoDB. If I change it in future, my (1) query will be
useless and more bad if I used it many times my code will be broken. I have googled ,but
there is no result. My question is , are there any project or workaround for such problem?
I'm not sure I've got your question completely, but take a look at spring-data-mongo http://projects.spring.io/spring-data-mongodb/
You would just need to declare interface
public interface CustomerRepository extends MongoRepository<Customer, String> {
public Customer findByCustomerType(String customerType);
}
and spring will do it's magic, providing implementation under the hood.
Related
When a method is created under a specific rule of Spring Data JPA, a method that calls the corresponding query is created.
For example,
public interface CustomerJpaRepository implements JpaRepository<Customer, Long>{
public List<Customer> findByName(String name);
}
findByName() generate the query similar to one below.
select * from Customer where name = name;
I am curious about this principle. To be precise, I'm curious about the code that parses this method and turns it into a query.
I looked at the code of the SimpleJpaRepository class that implements JpaRepository, but could not find a clue. (Of course, there is a possibility that I did not find it).
In summary, when a method consisting of specific words is declared in JpaRepository, I am curious about the code that actually executes this method internally. More specifically, I'd like to see the code that makes this method works.
If there is no code to do this internally (I personally doubt it's possible...), I want to know how it is implemented in detail, if there is a link or material that explains the principle or internal process, please share related references.
The parsing logic for creating queries from spring-data repository method names is currently mainly declared in the package org.springframework.data.repository.query.parser.
Basically, a repository method name string is parsed into a PartTree, which contains Parts representing defined abstract query criteria.
The PartTree can then be used to create a more specific query object, e.g. with a JpaQueryCreator, or a RedisQueryCreator, depending on the type of repository.
I recommend you to check this Query Creation spring doc
It explains the rules of how the method convert into a query.
I was writing Java code to get all the rows from the database table.
I was using CrudRepository and used this method below.
public interface StudentRepository extends CrudRepository<Student, Long>
{
public List<Student> findById(long id);
}
or
#Query(value = "SELECT s FROM Student s")
List<Student> customMethod(long id);
Which method is faster? Does Java internal method provide faster than our custom query?
Thanks in advance.
The default findById provided by Spring Data Repository and a query-annotated method have significantly different semantics. But, to keep it short, I will try to focus on differences in performance exclusively.
Unless you have query cache enabled, a query-annotated method will always hit the database with a query.
findById, on the other hand, ultimately calls EntityManager.find(). EntityManager.find() looks up the entity in the persistence context first. That means if the entity has already been loaded into the context, the call will not hit the underlying database.
As a side note, if you're curious as to how Spring implements the default repository methods, have a look at the source of SimpleJpaRepository.
You have to understand that findAll() method eventually generates the query for the selection. The only way to prove that is to test it. I don't think you will gain a significant performance boost. JPA's, on another hand, query generation is extremely easy to understand and use. So, if you hesitate between using one or the other, I would stick to findAll() JPA or spring data repository methods.
I'm coming from a C# background and trying to implement an Android App. In .Net C#, retrieving specific data from a database is relatively easy using Entity Framework and Linq, my usual approach is something like this (simplified for clarity):
public IQueryable<T> GetElements<T>()
where T : class, IDBKeyProvider
{
return this.db.Set<T>().Where(e => e.Dbstate == (int)DBState.Active);
}
This method call results in a generic IQueryable and later on, I can use the power of deferred execution and expression trees to specify exactly which elements I want using a predicate, loading only desired elements in memory.
This is something I would very much like to go for in my Android App, however, I'm not exactly sure how I could arrive at a similar result, if I can at all.
I looked into some Java Predicate examples, which seemed promising and I also found Room to be delightfully familiar. My problem, however, is that I cannot make my queries fully customizable due to the fact that, Room still needs some hard-coded info about my db (original here):
#Dao
public interface MyDao {
#Query("SELECT first_name, last_name FROM user WHERE region IN (:regions)")
public LiveData<List<User>> loadUsersFromRegionsSync(List<String> regions);
}
I could perhaps extract the relevant pieces of information with Java Reflection from the predicate parameter, but I feel this to be a hack rather than a proper solution.
I have a PagingAndSortingRepository:
public interface BrowserLinkPagination extends PagingAndSortingRepository<BrowserLink, Long> {
List<BrowserLink> findByUserAndUriLike(User user, String uri, Pageable pageable);
}
Now what I want to do is to search for multiple words in the uri column. Like comes pretty close, but it is order dependent on how the words occur in the string.
EDIT for clarification: Order dependences is exactly what I not want. I want the search strings to be independent of order, so LIKE is not what I am looking for.
I guess this is pretty common to find, having several search terms to look for in a string, I know I could implement it by providing the SQL to execute, but I am curiuous if there is a way to express that in terms of spring data? am
I am using postgresql for production and h2 for development / tests.
After reading more about the topic it is kind of obvious I need some kind of fulltext search.
I will start using the one provided by postgresql. I found a short working example: http://rachbelaid.com/postgres-full-text-search-is-good-enough/
Thanks for the comments.
Use In in method name. In Your case it could look like that:
public interface BrowserLinkPagination extends PagingAndSortingRepository<BrowserLink, Long> {
List<BrowserLink> findByUserAndUriIn(User user, List<String> uri, Pageable pageable);
}
When You are using the standard API created by Spring, the usage from the browser URI is pretty simple - just type in the address:
/your_api/browserlink/search/findByUserAndUriIn?user=xxx&uri=uri1,uri2,uri3
I'm using named queries to fetch entities from a database using JPA and Hibernate and I came across something that was puzzling me: how come there a no default implementations of the javax.persistence.Parameter interface?
I was rather impressed by how #StaticMetamodel is used by CriteriaBuilder in JPA2 meaning that I get Type safety and don't have to mess around with setting string for names. I wanted to apply something similar to some of the JPA1 EJB's that I'm currently working on:
Dealergroup_.class:
public Dealergroup_
{
public Parameter<Integer> id = new ParameterImpl<Integer>("id");
/// etc...
}
DealergroupFacade.class:
// ...
public Dealergroup fetch(Integer id)
{
TypedQuery<Dealergroup> query = em.createNamedQuery("Dealergroup.fetchById", Dealergroup.class);
query.setParameter(Dealergroup_.id, query);
return query.getSingleResult();
}
// ...
I was surprised to find that there were no implementations of the Parameter interface - of course, I could easily implement it myself by their absence makes me suspicious that it may be a mistake to be using it in this way?
Should I be implementing Parameter? Any ideas why there isn't a readily available implementation and why I can't find many (any, really) examples of its use?
That is an interface that a JPA implementation will implement with their implementation of Criteria "ParameterExpression" (which extends Parameter), using their own implementation class. A user goes via CriteriaBuilder.parameter() to get hold of one, or via Query.getParameter() when one is defined by traditional means in the query