spring data neo4j crud - many optional param? - spring

I use Spring-data-neo4j with one CrudRepository
#Repository
public interface PersonRepository extends GraphRepository<Person> {}
I have a Html form with 3 inputs FirstName, Name, Age, so I have possible a multiple criteria choose : All, FirstName, FirstName + Name, FirstName + Age etc....
I would like to make a "multiple criteria find" with Map or other stuff. Is it possible?
I try this in my CRUD:
List<Person> findByFirstnameAndNameAndAge(String firstname, String name, int age);
but it's not work if one or all parameters is null.

Try to use a map and a #Query annotation
#Query("MATCH (u:Person) WHERE u.name = {param}.name OR u.age = {param}.age RETURN u")
List<Person> findDynamic(#Param("param") Map params);

Hi #Michael Hunger Thank you for your response. It's not exactly what I expected but you delivered me some fine search stuff
finally I do this :
import org.apache.commons.collections.map.HashedMap;
import com.google.common.collect.Lists;
(...)
#Autowired
private EventRepository eventRepository; //#Repository extends GraphRepository<Event>
(...)
public List<Event> findByDynamicParam(HashedMap params) {
String query = "match (event)-[:user]-(user), (event)-[:action]-(action)";
if (!params.isEmpty()) {
query += " where";
}
if (params.containsKey("actionId")) {
query += " id(action) = {actionId} and";
}
if (params.containsKey("userId")) {
query += " id(user) = {userId} and";
}
if (!params.isEmpty()) {
query = query.substring(0, query.length() - 4);
}
query += " return (event)";
return Lists.newArrayList(eventRepository.query(query, params));
}
client's caller :
HashedMap params = new HashedMap();
if (actionId != null) {
params.put("actionId", actionId);
}
if (userId != null) {
params.put("actionId", userId);
}
List<Event> events = eventService.findByDynamicParam(params);
What do you think? Is it possible to optimize this function?
Regards
Olivier from Paris

Related

How to Implement Spring Boot Paging and multiple filtering using Criteria Api

Today was my first time with criteria Api. i have create an application in Spring boot in order to make server side pagination with multiple key of an entity filtering.
So in my case i have created an entity called User and i started to implement code to paginate the data but with Criteria API.
After implementing the pagination without filtering and Criteria Api everything worked perfectly! every page return 8 results and it is well organized by current page, totalPages, etc ..
But later i have decided to start to implement Criteria API by searching my entity username and userRole. my goal is to make that paging i did in the last step mixed with filtering of keys.
In case that my keys are empty then paginate else paginate and filter.
So after implementing i have discouvered that filtering works perfectly but pagination do not work correctly anymore because i am receiving all the results in every page.
that problem happened only after implementing Criteria API which i just discovered today.
I am trying to reach my goal by keeping all i spoke about in one query and paginate correctly
Here what i have done with my UserCriteriaRepository
#Repository
public class UserCriteriaRepository {
private final EntityManager entityManager;
private final CriteriaBuilder criteriaBuilder;
public UserCriteriaRepository(EntityManager entityManager) {
this.entityManager = entityManager;
this.criteriaBuilder = entityManager.getCriteriaBuilder();
}
public ResponsePagingAndSorting<UserDTO> findAllWithFilters(int page, int size, String username, String userRole) {
CriteriaQuery<User> criteriaQuery = criteriaBuilder.createQuery(User.class);
Root<User> userRoot = criteriaQuery.from(User.class);
Predicate predicate = getPredicate(username,userRole, userRoot);
criteriaQuery.where(predicate);
TypedQuery<User> typedQuery = entityManager.createQuery(criteriaQuery);
typedQuery.setMaxResults(size * 10);
long usersCount = getUsersCount(predicate);
int totalPages = (int) ((usersCount / size) + 1);
List<User> userList = new ArrayList<>();
userList = typedQuery.getResultList();
List<UserDTO> userDTOList = UserMapper.toListDTO(userList);
return new ResponsePagingAndSorting<UserDTO>("Users List ",200,userDTOList,page,
usersCount, totalPages);
}
private Predicate getPredicate(String username, String userRole,
Root<User> userRoot) {
List<Predicate> predicates = new ArrayList<>();
if(Objects.nonNull(username)){
predicates.add(
criteriaBuilder.like(userRoot.get("username"),
"%" + username + "%")
);
}
if(Objects.nonNull(userRole)){
UserRoleType userRoleType = null;
switch (userRole){
case "MEMBER": userRoleType = UserRoleType.MEMBER;
break;
case "ADMIN": userRoleType = UserRoleType.ADMIN;
break;
case "SUPER_ADMIN": userRoleType = UserRoleType.SUPER_ADMIN;
break;
}
if (userRoleType != null) {
predicates.add(
criteriaBuilder.equal(userRoot.get("userRole"),
userRoleType)
);
}
}
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
}
private Pageable getPageable(int page, int size) {
return PageRequest.of(page,size);
}
private long getUsersCount(Predicate predicate) {
CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class);
Root<User> countRoot = countQuery.from(User.class);
countQuery.select(criteriaBuilder.count(countRoot)).where(predicate);
return entityManager.createQuery(countQuery).getSingleResult();
}
}
My Service:
//paging with Criteria Api
#Override
public ResponsePagingAndSorting<UserDTO> getAllUsers(int page, int size ,String username, String userRole) {
ResponsePagingAndSorting<UserDTO> response = userCriteriaRepository.findAllWithFilters(page,size, username, userRole);
return response;
}
My Controller
#GetMapping("/get/all")
#ResponseBody
public ResponsePagingAndSorting<UserDTO> getAllUsers(#RequestParam(defaultValue = "0") int page,
#RequestParam(defaultValue = "8") int size,#RequestParam(defaultValue = "") String username,
#RequestParam(defaultValue = "") String userRole) {
ResponsePagingAndSorting<UserDTO> response = userService.getAllUsers(page,size,username,userRole);
log.warn("Response controller is " + response);
return response;
}
My ResponsePagingAndSorting dto object:
#AllArgsConstructor
#NoArgsConstructor
#Data
public class ResponsePagingAndSorting<T> {
String message;
int status_code;
List<T> body = new ArrayList<>();
int currentPage;
long totalItems;
int totalPages;
}
In Database i have in total of 17 users, so in postman i see all the 17 everytime but if i search by username or userRole or both it works? why pagination works only when i user the filters?
Can not i paginate data without seraching by username or userRole?
what is wrong with my code ???
how to make pagination works correctly with the filtering enabled or disabled?
Why if
Postman screen capture:
unfortunately all results are displayed in page 0
Screen Capture pagination + username filter: works correctly
i hope that i will find a solution
Problem Solved by using JpaSpecification
here the Specification class:
#Component
public class UserSpecification {
public Specification<User> getUsers(String username, String userRole) {
return (root, query, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
if (username != null && !username.isEmpty()) {
predicates.add(criteriaBuilder.like(criteriaBuilder.lower(root.get("username")),
"%" + username.toLowerCase() + "%"));
}
if (userRole != null && !userRole.isEmpty()) {
UserRoleType userRoleType = null;
switch (userRole) {
case "MEMBER": userRoleType = UserRoleType.MEMBER;
break;
case "ADMIN": userRoleType = UserRoleType.ADMIN;
break;
case "SUPER_ADMIN": userRoleType = UserRoleType.SUPER_ADMIN;
break;
}
predicates.add(criteriaBuilder.equal(root.get("userRole"), userRoleType));
}
query.orderBy(criteriaBuilder.asc(root.get("username")));
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
};
}
}

Spring Specification Criteria Multiple Joins ? How?

I got stuck using a Spring Project with Spring Data + specification + criteria api.
I will try to simulate the situation with general entities we used write to get easy example.
The Entities:
Consider all attributes of the each entity is passed on the constructor showed below
Country(Long id, String name, String iso)
State(Long id, String name, String iso)
City(Long id, String name, String iso)
This is my repository:
public interface CityRepository extends PagingAndSortingRepository<City, Integer>, JpaSpecificationExecutor<City> {
}
As you can see, I don't need to implement anything on the repository
This is my service
#Service
#Transactional
public class CityService {
#Autowired
private CityRepository cityRepository;
#Transactional(readOnly = true)
public CityListVO findByNameLike(String name, PageRequest pageRequest) {
name = "%" + name + "%";
if (pageRequest == null) {
List<City> result = cityRepository.findAll(fillGridCriteria(name));
return new CityListVO(1, result.size(), result);
} else {
Page<City> result = cityRepository. findAll(fillGridCriteria(name), pageRequest);
return new CityListVO(result.getTotalPages(), result.getTotalElements(), result.getContent());
}
}
private static Specification<City> fillGridCriteria(String name) {
return new Specification<City>() {
#Override
public Predicate toPredicate(
Root<City> root,
CriteriaQuery<?> query,
CriteriaBuilder builder) {
/*
The current return I can do a like by name, and it works fine.
My problem is if for any reason I need to do multiple joins like the folow jpql:
select ci FROM City ci, State st, Country co where ci.st = st AND st.co = co AND co.name = 'Canada';
How to do this from here ? Inside this method.
How is gonna be the return for this method ?
*/
return builder.like(root.get("name"), name.trim());
}
};
}
}
Let's assume you want all the cities that their country's name like name and you have a relational Model in which :
Country(Long id, String name, String iso)
State(Long id,Long country, String name, String iso)
City(Long id, Long state, String name, String iso)
Predicate:
private static Specification<City> fillGridCriteria(String name) {
return new Specification<City>() {
#Override
public Predicate toPredicate(
Root<City> root,
CriteriaQuery<?> query,
CriteriaBuilder builder) {
return
builder.like(root.get("state").get("country").get("name"), name.trim());
}
};
}

Spring data elasticSearch returns null with findOne

I'm testing Spring data with elasticSearch. The ES server is running on a remote server in tha same room.
I have one index created a day, under an alias. I'm trying to find a simple tweet. But when I try a findOne(), it doesn't seem to work because it returns always null.
Also, findAll(ids) doesn't work because I'm using the alias, but I can't find in the documentation how to handle this.
What do I want to achieve ?
For the moment, simply retrieve a tweet with a given id_str.
The count method works, the findOne doesn't
Here are my questions
What should I do to make findOne() to work ?
Which way should I use to search on multiple indexes in this alias ?
Here is how the datas looks like in ES
{
"id_str" : "135131315100051",
"..." : "...",
"user" : {
"id_str" : "15843643228"
"..." : "..."
}
}
My model
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
#Document(indexName = "alias", type = "tweets")
public class Tweet
{
#Id
#Field(type = FieldType.String)
private String idStr;
public String getIdStr()
{
return idStr;
}
public void setIdStr(final String idStr)
{
this.idStr = idStr;
}
#Override
public String toString()
{
return "{ id_str : " + idStr + " }";
}
}
Alias is alias, and indexes are alias_dd-mm-yyyy
My repository
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import com.thales.communications.osintlab.bigdata.webservices.models.Tweet;
public interface EsTweetRepository extends ElasticsearchRepository<Tweet, String>
{
Tweet findByIdStr(String idStr);
}
My test
#Test
public void shouldReturnATweet()
{
//lets try to search same record in elasticsearch
final Tweet tweet1 = tweetRepository.findOne("593768150975512576");
//final Tweet tweet = tweetRepository.findByIdStr("593897683661824000");
System.out.println("Count is " + tweet1);
//System.out.println("Count is " + tweetRepository.count());
// System.out.println(tweet.toString());
}
Of course, the tweet with the tested Id exists :). And the count() is working fine.
Thanks for your help
EDIT
Here is a sample application of what I have : https://github.com/ogdabou/es-stackoverflow-sample
It seems that spring-data-elasticsearch is look for the field "_id" and not the field "id_str". Maybe because of method parsing (look there). I'm looking for a way to bind my json "id_str" attribute to my idStr java model.
What was the real issue
We set the _id field of our tweet in Elasticsearch with the id field given by twitter. But it saves it in another format ( eg 132 becomes 1.32E2)
When I'm going a findOne() it is searching for a match with the Elasticsearch _id field and not the id_str I needed.
Solution
There, you have 2 commits, the first is the issue, the second the solution.
New repository
public interface EsTweetRepository extends ElasticsearchRepository<Tweet, String>
{
#Query("{\"bool\" : {\"must\" : {\"term\" : {\"id_str\" : \"?0\"}}}}")
Tweet findByIdStr(String idStr);
}
The model
#Document(indexName = "my_index_01", type = "tweets")
public class Tweet
{
// Elasticsearch object internal id. Look at field "_id"
#Id
private String id;
// Twitter internal id, saved under the "id_str" field
#Field(type = FieldType.String)
private String id_str;
#Field(type = FieldType.String)
private String text;
public String getId_str()
{
return id_str;
}
public void setId_str(final String id_str)
{
this.id_str = id_str;
}
public String getText()
{
return text;
}
public void setText(final String text)
{
this.text = text;
}
public String getId()
{
return id;
}
public void setId(final String id)
{
this.id = id;
}
#Override
public String toString()
{
return "{ _id : " + id + ", id_str : " + id_str + ", text : " + text + " }";
}
}

Spring Data JPA map the native query result to Non-Entity POJO

I have a Spring Data repository method with a native query
#Query(value = "SELECT g.*, gm.* FROM group g LEFT JOIN group_members gm ON g.group_id = gm.group_id and gm.user_id = :userId WHERE g.group_id = :groupId", nativeQuery = true)
GroupDetails getGroupDetails(#Param("userId") Integer userId, #Param("groupId") Integer groupId);
and I'd like to map the result to Non-Entity POJO GroupDetails.
Is it possible and if so, could you please provide an example ?
I think the easiest way to do that is to use so called projection. It can map query results to interfaces. Using SqlResultSetMapping is inconvienient and makes your code ugly :).
An example right from spring data JPA source code:
public interface UserRepository extends JpaRepository<User, Integer> {
#Query(value = "SELECT firstname, lastname FROM SD_User WHERE id = ?1", nativeQuery = true)
NameOnly findByNativeQuery(Integer id);
public static interface NameOnly {
String getFirstname();
String getLastname();
}
}
You can also use this method to get a list of projections.
Check out this spring data JPA docs entry for more info about projections.
Note 1:
Remember to have your User entity defined as normal - the fields from projected interface must match fields in this entity. Otherwise field mapping might be broken (getFirstname() might return value of last name et cetera).
Note 2:
If you use SELECT table.column ... notation always define aliases matching names from entity. For example this code won't work properly (projection will return nulls for each getter):
#Query(value = "SELECT user.firstname, user.lastname FROM SD_User user WHERE id = ?1", nativeQuery = true)
NameOnly findByNativeQuery(Integer id);
But this works fine:
#Query(value = "SELECT user.firstname AS firstname, user.lastname AS lastname FROM SD_User user WHERE id = ?1", nativeQuery = true)
NameOnly findByNativeQuery(Integer id);
In case of more complex queries I'd rather use JdbcTemplate with custom repository instead.
Assuming GroupDetails as in orid's answer have you tried JPA 2.1 #ConstructorResult?
#SqlResultSetMapping(
name="groupDetailsMapping",
classes={
#ConstructorResult(
targetClass=GroupDetails.class,
columns={
#ColumnResult(name="GROUP_ID"),
#ColumnResult(name="USER_ID")
}
)
}
)
#NamedNativeQuery(name="getGroupDetails", query="SELECT g.*, gm.* FROM group g LEFT JOIN group_members gm ON g.group_id = gm.group_id and gm.user_id = :userId WHERE g.group_id = :groupId", resultSetMapping="groupDetailsMapping")
and use following in repository interface:
GroupDetails getGroupDetails(#Param("userId") Integer userId, #Param("groupId") Integer groupId);
According to Spring Data JPA documentation, spring will first try to find named query matching your method name - so by using #NamedNativeQuery, #SqlResultSetMapping and #ConstructorResult you should be able to achieve that behaviour
I think Michal's approach is better. But, there is one more way to get the result out of the native query.
#Query(value = "SELECT g.*, gm.* FROM group g LEFT JOIN group_members gm ON g.group_id = gm.group_id and gm.user_id = :userId WHERE g.group_id = :groupId", nativeQuery = true)
String[][] getGroupDetails(#Param("userId") Integer userId, #Param("groupId") Integer groupId);
Now, you can convert this 2D string array into your desired entity.
You can write your native or non-native query the way you want, and you can wrap JPQL query results with instances of custom result classes.
Create a DTO with the same names of columns returned in query and create an all argument constructor with same sequence and names as returned by the query.
Then use following way to query the database.
#Query("SELECT NEW example.CountryAndCapital(c.name, c.capital.name) FROM Country AS c")
Create DTO:
package example;
public class CountryAndCapital {
public String countryName;
public String capitalName;
public CountryAndCapital(String countryName, String capitalName) {
this.countryName = countryName;
this.capitalName = capitalName;
}
}
This is my solution for converting to Map and then to custom Object
private ObjectMapper objectMapper;
public static List<Map<String, Object>> convertTuplesToMap(List<?> tuples) {
List<Map<String, Object>> result = new ArrayList<>();
tuples.forEach(object->{
if(object instanceof Tuple single) {
Map<String, Object> tempMap = new HashMap<>();
for (TupleElement<?> key : single.getElements()) {
tempMap.put(key.getAlias(), single.get(key));
}
result.add(tempMap);
}else{
throw new RuntimeException("Query should return instance of Tuple");
}
});
return result;
}
public <T> List<T> parseResult(List<?> list, Class<T> clz){
List<T> result = new ArrayList<>();
convertTuplesToMap(list).forEach(map->{
result.add(objectMapper.convertValue(map, clz));
});
return result;
}
public static class CustomDTO{
private String param1;
private Integer param2;
private OffsetDateTime param3;
}
public List<CustomDTO> doSomeQuery(){
Query query = entityManager.createNativeQuery("SELECT param1, param2 param3 ... ", Tuple.class);
return parseResult(query.getResultList(), CustomDTO.class);
}
Use the default method in the interface and get the EntityManager to get the opportunity to set the ResultTransformer, then you can return the pure POJO, like this:
final String sql = "SELECT g.*, gm.* FROM group g LEFT JOIN group_members gm ON g.group_id = gm.group_id and gm.user_id = ? WHERE g.group_id = ?";
default GroupDetails getGroupDetails(Integer userId, Integer groupId) {
return BaseRepository.getInstance().uniqueResult(sql, GroupDetails.class, userId, groupId);
}
And the BaseRepository.java is like this:
#PersistenceContext
public EntityManager em;
public <T> T uniqueResult(String sql, Class<T> dto, Object... params) {
Session session = em.unwrap(Session.class);
NativeQuery q = session.createSQLQuery(sql);
if(params!=null){
for(int i=0,len=params.length;i<len;i++){
Object param=params[i];
q.setParameter(i+1, param);
}
}
q.setResultTransformer(Transformers.aliasToBean(dto));
return (T) q.uniqueResult();
}
This solution does not impact any other methods in repository interface file.
USE JPA PROJECTIONS
In your case it may be desirable to retrieve data as objects of customized types. These types reflect partial views of the root class, containing only properties we care about. This is where projections come in handy.
first declare Entity as #immutable
#Entity
#Immutable
public class Address {
#Id
private Long id;
set your Repository
public interface AddressView {
String getZipCode();
}
Then use it in a repository interface:
public interface AddressRepository extends Repository<Address, Long> {
#Query("EXEC SP_GETCODE ?1")
List<AddressView> getAddressByState(String state);
}
If you are looking for running a custom SQL query in spring boot with #repository and #service structures. Please have a look.
https://stackoverflow.com/a/71501509/4735043
You can do something like
#NamedQuery(name="IssueDescriptor.findByIssueDescriptorId" ,
query=" select new com.test.live.dto.IssuesDto (idc.id, dep.department, iss.issueName,
cat.issueCategory, idc.issueDescriptor, idc.description)
from Department dep
inner join dep.issues iss
inner join iss.category cat
inner join cat.issueDescriptor idc
where idc.id in(?1)")
And there must be Constructor like
public IssuesDto(long id, String department, String issueName, String issueCategory, String issueDescriptor,
String description) {
super();
this.id = id;
this.department = department;
this.issueName = issueName;
this.issueCategory = issueCategory;
this.issueDescriptor = issueDescriptor;
this.description = description;
}

SimpleJdbcInsert equivalent for update

I am using Spring's SimpleJdbcInsert class to create entities - eg:
final SimpleJdbcInsert insert = new SimpleJdbcInsert(dataSource).withTableName("abc");
insert.execute(new BeanPropertySqlParameterSource(abc));
Is there some equivalent of this class for doing updates? As an example, something like the below would be a convenient interface, assuming we are dealing with a single column primary key:
final SimpleJdbcUpdate update = new SimpleJdbcUpdate(dataSource).withTableName("abc").withIdColumn("abcId");
update.execute(new BeanPropertySqlParameterSource(abc));
Does Spring provide this functionality out-of-the-box somewhere?
Thanks
Jay
For any future readers - I came up with a convenience function using reflection;
Works for simple pojos:
public void dao_update(NamedParameterJdbcTemplate database, String table, Object pojo, String[] keys) {
StringBuilder sqlBuilder = new StringBuilder("UPDATE ");
sqlBuilder.append(table);
sqlBuilder.append(" SET ");
boolean first = true;
for (Field field : pojo.getClass().getDeclaredFields()) {
if (!first) {
sqlBuilder.append(",");
}
first = false;
sqlBuilder.append(field.getName());
sqlBuilder.append(" = :");
sqlBuilder.append(field.getName());
}
first = true;
for (String key : keys) {
if (first) {
sqlBuilder.append(" WHERE ");
} else {
sqlBuilder.append(" AND ");
}
first = false;
sqlBuilder.append(key);
sqlBuilder.append("= :");
sqlBuilder.append(key);
}
database.getJdbcOperations().update(sqlBuilder.toString(), new BeanPropertySqlParameterSource(pojo));
}
Example usage:
dao_update(database, "employee", my_employee, "id");
Generates:
UPDATE employee SET id = :id, name = :name, salary = :salary WHERE id = :id
There is an issue in the Spring JIRA about the lack of a SimpleJdbcUpdate class: https://jira.springsource.org/browse/SPR-4691. You might want to upvote it there.
You have to use JdbcTemplate
See: 13.2.1.1 Examples of JdbcTemplate class usage
E.X:
this.jdbcTemplate.update(
"update t_actor set = ? where id = ?",
"Banjo", 5276L);
You can get more similar effect by using SimpleJdbcTemplate instead of JdbcTemplate and by extending SimpleJdbcDaoSupport all DB operations can be put in one DAO class:
import java.util.List;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;
import org.springframework.stereotype.Repository;
#Repository
public class BankDaoImpl extends SimpleJdbcDaoSupport implements BankDao {
#Autowired
public BankDaoImpl(#Qualifier("dataSource") DataSource dataSource) {
setDataSource(dataSource);
}
#Override
public void insert(Bank bank) {
String sql = "INSERT INTO BANK (id, oib, short_name, name, street, town, postal_code, homepage_url, last_change) VALUES (NEXT VALUE FOR bank_seq, :oib, :shortName, :name, :street, :town, :postalCode, :homepageUrl, CURRENT_TIMESTAMP)";
SqlParameterSource parameterSource = new BeanPropertySqlParameterSource(
bank);
getSimpleJdbcTemplate().update(sql, parameterSource);
}
#Override
public void update(Bank bank) {
String sql = "UPDATE BANK SET oib=:oib, short_name=:shortName, name=:name, street=:street, town=:town, postal_code=:postalCode, homepage_url=:homepageUrl, last_change=CURRENT_TIMESTAMP WHERE id=:id";
SqlParameterSource parameterSource = new BeanPropertySqlParameterSource(
bank);
getSimpleJdbcTemplate().update(sql, parameterSource);
}
#Override
public void delete(String id) {
String sql = "DELETE FROM BANK WHERE id=:id";
getSimpleJdbcTemplate().update(sql,
new MapSqlParameterSource("id", id));
}
#Override
public Bank findById(String id) {
String sql = "select b.ID, b.OIB, b.SHORT_NAME, b.NAME, b.STREET, b.TOWN, b.POSTAL_CODE, b.HOMEPAGE_URL, b.LAST_CHANGE, CASE WHEN count(f.id) = 0 THEN 0 ELSE 1 END AS ready " +
"from BANK WHERE b.ID = :id";
return getSimpleJdbcTemplate().queryForObject(sql,
BeanPropertyRowMapper.newInstance(Bank.class),
new MapSqlParameterSource("id", id));
}
}
The easy way to do this is:(source)
public void setName(int id, String name) {
this.jdbcTemplate.update("update mytable set name = ? where id = ?",
new Object[] {name, new Integer(id)});
}

Resources