I am using spring boot and mybatis, my code looks like:
class StudentController {
....
List<Student> listStudent(Student student, Pageable pageable) {
return this.studentService.listStudent(student, pageable)
}
}
class StudentService {
....
List<Student> listStudent(Student student, Pageable pageable) {
return this.studentDao.listStudent(student, pageable)
}
}
class StudentDao {
List<Student> listStudent(Student student, Pageable pageable);
}
the sql xml file looks like:
<select id="listStudent" resultType="student">
select * from student
<where>
<if test="student.age != null">age = #{student.age}</if>
</where>
</select>
client may list student via spring controller or call studentService.listStudent from java code.
the code only can build the equal condition operator sql, e.g. select * from student where age = 10.
how can I build different conditions operator?
Since sometimes client may want to query student whose age > 10 or age < 10 or age between 10 and 12 or other condition operator.
You probably want to add two properties to the Student class, instead of a single age property:
Integer minAge,
Integer maxAge
That way to perform an equals query you set them to the same value, and to perform a range query, you set one or both to a value.
<select id="listStudent" resultType="student">
select * from student
<where>
<if test="student.minAge != null">age > #{student.minAge} </if>
<if test="student.minAge != null && student.maxAge != null"> AND </if>
<if test="student.maxAge != null">age < #{student.maxAge} </if>
</where>
</select>
Related
Using a postgres database, I have the following entity : table cards.combo and column colors VARCHAR[], example of values {'red', 'blue'}
I want to find the Combos that have no colors in common, using the overlap operator (&&)
I can't find out how to formulate the correct nativeQuery, something similar to this :
#Query(nativeQuery = true, value = "SELECT * FROM cards.combo cc WHERE cc.colors && CAST(ARRAY[(:providedColors)] AS VARCHAR[])")
List<Combo> findOverlaps(#Param("providedColors") List<String> providedColors);
In a console, this test works fine :
SELECT * FROM cards.combo cc WHERE cc.colors && CAST(ARRAY['red'] AS VARCHAR[])
The syntax (:param) is supposedly correct with other primitive parameters (int, string). I struggle to get the param providedColors converted to an array[] in the query.
Thanks !
edit : found a workaround :provide colors as a csv string, and use && CAST(STRING_TO_ARRAY((:providedColors),',') AS VARCHAR[])
public interface EmployeeDAO extends JpaRepository<Employee,Integer> {
List<Employee> findByEmployeeNameIn(List<String> names);
// 1. Spring JPA In cause using method name
#Query("SELECT e FROM Employee e WHERE e.employeeName IN (:names)")
// 2. Spring JPA In cause using #Query
List<Employee> findByEmployeeNames(#Param("names")List<String> names);
#Query(nativeQuery =true,value = "SELECT * FROM Employee as e WHERE e.employeeName IN (:names)") // 3. Spring JPA In cause using native query
List<Employee> findByEmployeeName(#Param("names") List<String> names);
}
I'm trying to use Specification interface. So far so good but now I would like to use an optional search criteria.
In the code below if customerId(Long) is null I would like to get all the customers from db and if not only the the customer with the specific Id. Now only works the second part.
Is it possible to get all the customers if the given Id is null?
Thanks in advance!
Specification<Order> customer = (root, query, cb) -> {return cb.equal(root.get("customerId"), customerId);
};
So you need to create a condition to return an empty (default) CriteriaBuilder on null customerId:
Specification<Order> customer = (root, query, cb) -> {
if(customerId == null){
return cb; // return empty CriteriaBuilder
}
return cb.equal(root.get("customerId"), customerId);
};
i have a criteria like
public ArrayList<Student>getStudentsWithPicture(final Student student)
{
final Criteria criteria = session.createCriteria(Student.class).add(and(prepareForSelect()));
criteria.add(Subqueries.gt(1L,getDetached);//the students with a less added picture...
return new ArrayList<Student>(criteria.list());
}
i need the students with a less a picture in the table Pictures but this Database is a legacy one
they store the pictures concatening some fields for the student entity
yes a quite weird
i want something like this
SQL
select
this_.ID as y0_,
this_.C01 as y1_,
this_.C02 as y2_,
this_.C03 as y3_
from
student_table this_
where
(
and this_.C11=true
and 1>=
(
select
count(*)
from
PICTURE_TABLE this_
where
(
this_.C03='concatening'+ this_.ID+ this_.C01+this_.C02+this_.C03//the fields of the student
)
)
)
this is just a understandable example the actual query is a lot worse...
as you can see i want the students with status='true' and they have a less one match on the PICTURE_TABLE but the field C03 from the table is created by concatening the fields of the Student which i have retrieve it as well...
my detached
public DetachedCriteria getWithDetachedMatchStudentWithPictures()
{
final String concatedFields = ...........how i accomplish this??????.................
final DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Pictures.class)
.add(equals("c03",concatedFields))
.setProjection(addProjection("id"))
.setResultTransformer(transformer(Pictures.class));
return detachedCriteria;
}
my question is.
can i concate the fields at runtime..?? using Criteria A.P.I
there is some approach?
thanks a lot
Yes, we can contact multiple columns run time in hibernate.
i have concat columns in my beloved query.
Query query = session.createQuery("SELECT DISTINCT f.fileid , f.filename, f.filetype , f.folderpath , max(f.version) from FileBean f GROUP BY concat(folderpath,filename,'.',filetype)");
result = query.list();
I've searched in the mybatis documentaion and in inet. But couldn't find the sollution.
My goal is:
From myBatis dynamic SQL select return wether
Map <Strinng (Data Base Column), Object (Database Value)> or
List<Object> (Database Values)
without creating pojo as representation of database table.
It should looks like:
1) Dynamic SQL:
<select id="selectRecords" parameterType="Entry" resultType="Map">
SELECT
<foreach item="column" index="index" collection="columns" separator=",">
${column}
</foreach>
from ${tableName}
</select>
2) Parameter that I put into dynamic select:
public class Entry {
private String tableName;
private String[] columns;
//constructor
//getters, setters
}
3) Method that returns map:
Map<String, Object> selectRecords(Entry entry);
The very first example in tutorial shows an example of simple collection that is returned. Here,
<select id="selectPerson" parameterType="int" resultType="hashmap">
SELECT * FROM PERSON WHERE ID = #{id} </select>
This statement is
called selectPerson, takes a parameter of type int (or Integer), and
returns a HashMap keyed by column names mapped to row values.
In this hashmap, Key-Value pairs are "ColumnName"-"Column's Value" pairs. No pojo is used. Your example code seems correct to me, you can print the errors if you get any.
Customer{
String customerName
#OneToMany
Set users;
}
User{
String userName;
}
when i do this:
select c.customerName as customerName ,concat(u.userName) as userNames from Customer c join c.users as u
hibernate don't return the result i expected.
Unfortunately hibernate does not have an SQL aggregate function that combines strings. There is no standard SQL aggregate function for this either so each database tends to have it's own. An example would be NexusDB 3.x's LIST() which compiles a comma-separated list of non-null values in the set.
SELECT c.customerName as customerName , LIST(u.userName) as userNames
FROM Customer c
JOIN c.users as u
GROUP BY c.customerName;