I've the following query:
select u from User u where upper(u.name) like upper(?1)
How this would be, but ignoring the accents in u.name and ?1?
I have found a way to implement this. Basically there are 2 steps:
normalize the parameter (in your case 1) and
normalize the data from the DB
Example
public User getByName(String paramName) {
.....
}
Original HQL Query :
String queryString = "select u from User u where u.name : =paramName";
New Query:
paramName = normalizer(paramName );
String queryString = "select u from User u where " + replacer(u.name) +" : =paramName";
And the 2 methods:
public static String normalizer(String s) {
return Normalizer.normalize(s, Normalizer.Form.NFD).replaceAll("[^\\p{ASCII}]", "");
}
public String replacer(String param) {
String t1 = "àâäçéèëêùûüôöïî";
String t2 = "aaaceeeeuuuooii";
String s = param;
for (int i = 0; i < t1.length(); i++) {
s = "replace(" + s + ",'" + t1.charAt(i) + "','" + t2.charAt(i) + "')";
}
return s;
}
What database are you using? In most of them you can send a specific SQL command to set the collation.
In portuguese, i missed the accents in some characters, so i added more characters in the replacer method:
public String replacer(String param) {
String t1 = "áãàâäçéèëêùûüúóôöïîíÁÀÂÄÃÇÉÈËÊÙÛÜÚÓÔÖÏÎÍ";
String t2 = "aaaaaceeeeuuuuoooiiiAAAAÃCEEEEUUUUOOOIII";
String s = param;
for (int i = 0; i < t1.length(); i++) {
s = "replace(" + s + ",'" + t1.charAt(i) + "','" + t2.charAt(i) + "')";
}
return s;
}
With CriteriaBuilder you can use the following Specification
public static Specification<User> byNameIgnoringCaseAndAccents(String paramName) {
return (root, cq, cb) -> {
String paramNameNormalized = paramName != null ? normalize(paramName.toLowerCase()) : null;
String characters = "áãàâäçéèëêùûüúóôöïîíÁÀÂÄÃÇÉÈËÊÙÛÜÚÓÔÖÏÎÍ";
String replacements = "aaaaaceeeeuuuuoooiiiAAAAÃCEEEEUUUUOOOIII";
Expression<String> replacedName = root.get("name");
for (int i = 0; i < characters.length(); i++) {
replacedName = cb.function("REPLACE", String.class, replacedName, cb.literal(characters.charAt(i)), cb.literal(replacements.charAt(i)));
}
replacedName = cb.lower(replacedName);
return cb.like(cb.literal(paramNameNormalized), cb.concat("%", cb.concat(replacedName, "%")));
};
}
public static String normalize(String s) {
return s != null ? Normalizer.normalize(s, Normalizer.Form.NFD).replaceAll("[^\\p{ASCII}]", "") : s;
}
Related
I tried to make an exporting data to PDF but when I try to export it, the pdf can't show up like "no data found"
this code on bean
public JasperPrint exportTo() {
if(this.listReportMaster == null || this.listReportMaster.isEmpty()){
FacesMessage messageFailed = new FacesMessage(FacesMessage.SEVERITY_INFO,"Info","No data found");
RequestContext.getCurrentInstance().showMessageInDialog(messageFailed);
return null;
}
String path = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/resources/report/PRPKReportPDF.jasper");
JRBeanCollectionDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(this.listReportMaster);
try {
JasperPrint jasperPrint = JasperFillManager.fillReport(path, null, beanCollectionDataSource);
return jasperPrint;
} catch (JRException e) {
e.printStackTrace();
return null;
}
}
public void exportToPdf(ActionEvent actionEvent){
if(this.lazyMasterReportDataModel != null){
System.out.println("masuk exporttopdf");
String sql = ((LazyMasterReportDataModel) this.lazyMasterReportDataModel).getSqlReportPrint();
List<Object> listObject = ((LazyMasterReportDataModel) this.lazyMasterReportDataModel).getObjectSqlListReportPrint();
this.listReportMaster = reportMasterPRPKController.getPRPKForReport(sql, listObject);
JasperPrint jasperPrint = exportTo();
String fileName = "PRPKNew_Report".concat("_").concat(".pdf");
if(jasperPrint != null) reportMasterPRPKController.exportToPDF(fileName, jasperPrint);
else System.out.println("jasperprint null");
}else{
System.out.println("keluar exporttopdf");
FacesMessage messageFailed = new FacesMessage(FacesMessage.SEVERITY_INFO,"Info","No data found");
RequestContext.getCurrentInstance().showMessageInDialog(messageFailed);
}
}
every I try to export it, always show "no data found" which is the program run this code FacesMessage messageFailed = new FacesMessage(FacesMessage.SEVERITY_INFO,"Info","No data found"); and which meam the "this.lazyMasterReportDataModel" is null but when I check it again, there's nothing wrong on code, I don't know if it have a wrong code or deficiency code
this the lazy code
List<ReportMasterPRPK> listMasterPRPK = new ArrayList<>();
ReportMasterPRPKQuery reportMasterPRPKQuery = new ReportMasterPRPKQuery();
Page page = new Page();
String order = "GROUP a.prpk_number, a.prpk_type_id, a.created_date, a.pic_prpk_id, a.business_unit_id, a.pic_department_id, a.prpk_desc, a.prpk_request, a.prpk_background, a.prpk_analysis_benefit, a.priority_level_id, a.cost, b.prpk_type_name, c.business_unit, d.department_name, e.priority_name, f.user_name ORDER BY a.created_date ";
String columname = "";
String sql = "";
List<Object> objectSqlList = new ArrayList<>();
String sqlReport = "";
String sqlReportPrint = "";
List<Object> objectSqlListReport = new ArrayList<>();
List<Object> objectSqlListReportPrint = new ArrayList<>();
String flag;
public LazyMasterReportDataModel() {
}
public LazyMasterReportDataModel(String flag) { //ini
this.flag = flag;
}
public LazyMasterReportDataModel(String sqlReport, List<Object> objectSqlListReport) {
this.sqlReport = sqlReport;
this.objectSqlListReport = objectSqlListReport;
}
#Override
public List<ReportMasterPRPK> load(int first, int pageSize, String sortField, SortOrder sortOrder,
Map<String, Object> filters) {
page.setLimit(pageSize);
page.setOffset(first);
if(this.sqlReport != null){
this.sql = this.sqlReport;
this.objectSqlList = this.objectSqlListReport;
}else{
sql = "";
objectSqlList = new ArrayList<>();
//objectSqlList.clear();
}
if(flag != null){ //ini
if(flag.equals("no selected")){
sql = sql+" AND c.is_selected = 'n' ";
}
}
if (filters != null){
for(String key: filters.keySet()){
String filterColumnName = "";
for(Field field : ReportMasterPRPK.class.getDeclaredFields()){
if(field.getName().equals(key)) filterColumnName = field.getAnnotation(Column.class).value();
}
if(filters.get(key) instanceof String){
if("receivedDate".equals(key)){
if(((String)filters.get(key)).trim().length() > 20){
String startDate = "'" + filters.get(key).toString().substring(0, 10) + "'";
String endDate = "'" + filters.get(key).toString().substring(11, 21) + "'";
sql = sql + " AND " + filterColumnName + " BETWEEN " + startDate + " AND " + endDate+ " ";
}
}else{
if(((String) filters.get(key)).trim().length() > 0){
sql = sql+"AND "+filterColumnName+" ILIKE ? ";
String value = "%"+filters.get(key)+"%";
objectSqlList.add(value);
}
}
}else{
if(((String[]) filters.get(key)).length > 0){
sql = sql+" AND "+filterColumnName+" in ";
String value = "(";
for(String string : (String[]) filters.get(key)){
value = value+"'"+string+"',";
}
value = value.substring(0, value.length()-1)+") ";
sql = sql + value;
}
}
}
}
if(sortField != null){
for(Field field : ReportMasterPRPK.class.getDeclaredFields()){
if(field.getName().equals(sortField)) columname = field.getAnnotation(Column.class).value();
}
if(sortOrder.toString().equals("ASCENDING")) order = " ASC";
else order = " DESC";
sql = sql+" GROUP a.prpk_number, a.prpk_type_id, a.created_date, a.pic_prpk_id, a.business_unit_id, a.pic_department_id, a.prpk_desc, a.prpk_request, a.prpk_background, a.prpk_analysis_benefit, a.priority_level_id, a.cost, b.prpk_type_name, c.business_unit, d.department_name, e.priority_name, f.user_name ORDER BY "+columname+" "+order;
System.out.println("sql sort: "+sql+" : "+objectSqlList.size());
}else{
sql = sql + order;
}
sqlReportPrint = sql;
objectSqlListReportPrint = objectSqlList;
this.listMasterPRPK = reportMasterPRPKQuery.retrivePage(page, sql, objectSqlList.toArray());
int dataSize = reportMasterPRPKQuery.retrieveMaxRow(sql, objectSqlList.toArray());
this.setRowCount(dataSize);
//objectSqlList.clear();
if(this.sqlReport != null){
this.sql = this.sqlReport;
this.objectSqlList = this.objectSqlListReport;
}else{
sql = "";
objectSqlList.clear();
}
order = "GROUP a.prpk_number, a.prpk_type_id, a.created_date, a.pic_prpk_id, a.business_unit_id, a.pic_department_id, a.prpk_desc, a.prpk_request, a.prpk_background, a.prpk_analysis_benefit, a.priority_level_id, a.cost, b.prpk_type_name, c.business_unit, d.department_name, e.priority_name, f.user_name ORDER BY a.created_date ";
return listMasterPRPK;
}
public List<ReportMasterPRPK> calculateRownum(List<ReportMasterPRPK> listMasterPRPK, int first){
int i = 1;
for (ReportMasterPRPK masterPRPK : listMasterPRPK) {
masterPRPK.setRownum(first + i);
i++;
}
return listMasterPRPK;
}
public String getSqlReportPrint() {
return sqlReportPrint;
}
public void setSqlReportPrint(String sqlReportPrint) {
this.sqlReportPrint = sqlReportPrint;
}
public List<Object> getObjectSqlListReportPrint() {
return objectSqlListReportPrint;
}
public void setObjectSqlListReportPrint(List<Object> objectSqlListReportPrint) {
this.objectSqlListReportPrint = objectSqlListReportPrint;
}
sorry before, if my english is to bad, but I hope you understand about what I mean...
thanks before...
I'm using a spring framework and the code I'm using won't work or check if the query is null, though I used a .isEmpty() method it doesn't mean that the query is empty. I wanted to make sure that my query is empty because a part of my code does invoke an id in which case I didn't even though its null so please help me T.T
public List<Object> searchEmployee(EmployeeSearchDto data) {
Session session = sessionFactory.openSession();
final String CRITERIA_EMPLOYEEID = "emp.employeeID =:id";
final String CRITERIA_EMPLOYEEID2 = "emp.employeeID LIKE:id";
final String CRITERIA_POSITION= "emp.positionID =:posID";
final String CRITERIA_DEPARTMENT="emp.departmentID =:deptID";
final String CRITERIA_WORKPLACE = "emp.workplaceID =:workID";
Boolean selected_dept = false;
Boolean selected_pos = false;
Boolean selected_work = false;
Boolean input_empID = false;
Boolean input_empName = false;
firstName = "";
middleName = "";
lastName = "";
completeName = "";
firstLastName = "";
List<String> criteria = new ArrayList<>();
List<Object> employees = null;
// checking the fields if all the fields is empty
try{
//one by one check the select field
String query = "Select"
+ " emp.employeeID,"
+"emp.firstName,"
+"emp.middleName,"
+"emp.lastName,"
+"pos.positionName,"
+"dept.deptName,"
+"work.workplaceName"
+"from Employee emp "
+ "INNER JOIN Department dept "
+ "ON emp.departmentID = dept.deptID "
+ "INNER JOIN Position pos "
+ "ON emp.positionID = pos.positionID "
+ "INNER JOIN Workplace work "
+ "ON emp.workplaceID = work.workplaceID ";
if(!data.isEmpty()) {
query = query.concat("WHERE ");
if(data.getEmployeeID()!="" && data.getEmployeeID()!=null) {
criteria.add(CRITERIA_EMPLOYEEID2);
System.out.println("Employee IDs");
input_empID = true;
}
if(data.getEmployeeName()!="" && data.getEmployeeName()!=null){
criteria.add(nameCriteriaHelper(data.getEmployeeName()));
System.out.println("Employee Name AKOOO");
input_empName = true;
}
if(data.getDepartmentID()!=0) {
criteria.add(CRITERIA_DEPARTMENT);
System.out.println("Dept ID ");
selected_dept = true;
}
if(data.getPositionID()!=0) {
criteria.add(CRITERIA_POSITION);
System.out.println("POS ID ");
selected_pos = true;
}
if(data.getWorkplaceID()!=0) {
criteria.add(CRITERIA_WORKPLACE);
selected_work = true;
}
query = query.concat(String.join(" OR ", criteria));
}
query = query.concat(" ORDER BY emp.joinDate DESC");
System.out.println("QUERY: " + query);
Query q = session.createQuery(query);
if(input_empID) {
q.setParameter("id", "%" + data.getEmployeeID() + "%");
}
if(input_empName) {
if(searchbyOne)
q.setParameter("inputName", "%" + data.getEmployeeName() + "%");
if(searchbyFandL)
q.setParameter("firstLastName", "%" +firstLastName+ "%");
if(searchbyCompName)
q.setParameter("completeName", "%" +completeName+ "%");
}
if(selected_dept) {
q.setParameter("deptID", data.getDepartmentID());
}
if(selected_pos) {
q.setParameter("posID", data.getPositionID());
}
if(selected_work) {
q.setParameter("workID", data.getWorkplaceID());
}
employees = (List<Object>) q.list();
}catch(Exception e){
e.printStackTrace();
}finally{
session.close();
}
return employees;
}
public String nameCriteriaHelper(String name) {
searchbyOne = false;
searchbyFandL = false;
searchbyCompName = false;
final String noOfTokens_1 = "CONCAT(emp.lastName,' ',emp.firstName, ' ',emp.middleName) LIKE :inputName";
final String noOfTokens_2 = "(CONCAT(emp.lastName, ' ', emp.firstName) LIKE :firstLastName "
+ "OR CONCAT(emp.firstName, ' ', emp.lastName) LIKE :firstLastName)";
final String noOfTokens_3 = "CONCAT(emp.lastName,' ',emp.firstName, ' ',emp.middleName) LIKE :completeName";
StringTokenizer stringTokenizer = new StringTokenizer(name);
int no_of_tokens = stringTokenizer.countTokens();
switch(no_of_tokens) {
case 1: searchbyOne = true;
return noOfTokens_1;
case 2: firstName = stringTokenizer.nextToken();
lastName = stringTokenizer.nextToken();
firstLastName = lastName + " " + firstName;
searchbyFandL = true;
return noOfTokens_2;
default: int counter = 0;
while( counter < (no_of_tokens - 2)) {
firstName = firstName.concat(stringTokenizer.nextToken() + " ");
counter++;
}
firstName = stringTokenizer.nextToken();
middleName = stringTokenizer.nextToken();
lastName = stringTokenizer.nextToken();
completeName = lastName + " " + firstName + " " + middleName;
searchbyCompName = true;
return noOfTokens_3;
}
You're using wrong order and wrong function to compare string:
Replace:
data.getEmployeeID()!="" && data.getEmployeeID()!=null
With
data.getEmployeeID() != null && !data.getEmployeeID().equals("")
Comparing string must use equals(). And check for null should be done first, before accessing the equals method
You should correct other conditions as above too.
Actually, the logic that Mr. Nguyễn provided here is faulty. An object or variable cannot both be null and initialized to a default value (such as foo == "") at the same time.
At the time of the logic check, if the String is in fact null, the second half of the logic statement will engage, checking to see if the String is equal to "", which will throw a null pointer exception. Instead of checking for both at the same time, check for one and then check for the other like so:
//since two logic checks are being performed,
//it is advantageous to put the data from the query
//into memory so you don't have to get the
//same result twice
String foo = data.getEmployeeID();
if (foo != null)
{
if (!(foo.equals("")))
{
//the result is neither null or empty
}
else
{
//the result is not null but it is empty
}
}
else
{
//the result is null
}
Why doesn't this query work?
query = "SELECT itm.itemId, itm.itemModel, itm.itemDescription, "
+ " itmImages.imageFileName, part.participant_id "
+ " FROM Users user "
+ " INNER JOIN user.participant part "
+ " INNER JOIN part.addresses addr "
+ " INNER JOIN part.item itm "
+ " INNER JOIN itm.itemImages itmImages "
+ " WHERE user.userType LIKE '%borrow%') AND itm.itemDescription LIKE '%mower%') AND addr.addressType = 'primary'";
It always returns all items, disregards itemDescription LIKE... I checked the database and all of the join ids are fine
This works:
query = "SELECT user"
+ " FROM Users user "
+ " INNER JOIN user.participant part "
+ " INNER JOIN part.addresses addr "
+ " WHERE user.userType LIKE '%borrow%') AND addr.addressType = 'primary'";
I have a table Users. It has a one-to-many association with table Participant.
In Users.java I have..
private Set<Participant> participant = new HashSet<Participant>();
with
#OneToMany
#JoinTable(name = "echomarket.hibernate.Participant")
#JoinColumn(name = "user_id")
public Set<Participant> getParticipant() {
return participant;
}
public void setParticipant(Set<Participant> participant) {
this.participant = participant;
}
This join works fine.
In Participant.java I have
private Set<Addresses> addresses = new HashSet<Addresses>();
with
#OneToMany
#JoinTable(name = "echomarket.hibernate.Addresses")
#JoinColumn(name = "participant_id")
public Set<Addresses> getAddresses() {
return addresses;
}
public void setAddresses(Set<Addresses> addresses) {
this.addresses = addresses;
}
And
private Set item = new HashSet();
With
#OneToMany
#JoinTable(name = "echomarket.hibernate.Items")
#JoinColumn(name = "participant_id")
public Set<Items> getItem() {
return item;
}
No association statement with regard to Users.
In Addresses.java I make no associations.
In Items.java I have
private Set<ItemImages> itemImages = new HashSet<ItemImages>();
with
#OneToMany
#JoinTable(name = "echomarket.hibernate.ItemImages")
#JoinColumn(name = "itemId")
public Set<ItemImages> getItemImages() {
return itemImages;
}
public void setItemImages(Set<ItemImages> itemImages) {
this.itemImages = itemImages;
}
In ItemImages.java I make no associations...
Very much thanks for your help. If you need more information, please just ask...
Liz
Couldn't get the above INNER JOIN query to work-- intended for a search that involves many tables. I tested each JOIN independently successfully, but together the JOIN does not work. Also had problems with query recognizing LIKE statement. I worked really hard to find solutions. So I rewrote with the following, data gathering is split in two query calls. The following works:
public String SearchResults() {
Session sb = null;
Transaction tx = null;
String queryString = "";
String forceString = this.found_zip_codes;
List results = null;
String fromStatement = "";
if (this.lenderOrBorrower == 2) {
this.which = "borrow";
} else {
this.which = "lend";
}
this.imageLibrary = this.which + "_images";
fromStatement = " SELECT part "
+ " FROM Participant part "
+ " INNER JOIN part.addresses addr "
+ " WHERE addr.addressType = 'primary' ";
if (ubean.getComDetailID() != null) {
fromStatement = fromStatement + " AND part.communityId = \'" + ubean.getComDetailID() + "\' ";
} else {
fromStatement = fromStatement + " AND part.communityId = ''";
}
if (this.postalCode.isEmpty() == false) {
fromStatement = fromStatement + " OR addr.postalCode LIKE \'" + this.postalCode + "%\'";
}
try {
sb = hib_session();
tx = sb.beginTransaction();
results = sb.createQuery(fromStatement).list();
tx.commit();
} catch (Exception ex) {
tx.rollback();
Logger.getLogger(SearchesBean.class.getName()).log(Level.SEVERE, null, ex);
} finally {
tx = null;
sb = null;
}
String[] pids = new String[results.size()];
String hold_pid = "";
if (results != null) {
if (results.size() > 0) {
for (int i = 0; i < results.size(); i++) {
Participant cArray = (Participant) results.get(i);
if (cArray.getParticipant_id().isEmpty() == false) {
hold_pid = "\'" + cArray.getParticipant_id() + "\'";
pids[i] = hold_pid;
}
}
hold_pid = String.join(",", pids);
}
}
results = null;
fromStatement = " FROM Items itm WHERE itm.itemType = :which "
+ (hold_pid.isEmpty() ? "" : " AND itm.participant_id IN ( " + hold_pid + " )");
if ((this.startDate.isEmpty() == false) && (this.endDate.isEmpty() == false)) {
try {
queryString = queryString + " OR ";
queryString = queryString + " ( itm.dateCreated >= \'" + this.startDate + "\' AND itm.dateCreated <= \'" + this.endDate + "\' ) ";
} catch (Exception ex) {
Logger.getLogger(SearchesBean.class.getName()).log(Level.INFO, null, ex);
}
}
forceString = this.keyword;
if (forceString.isEmpty() == false) {
queryString = queryString + " OR ";
queryString = queryString + " (itm.itemDescription like \'%" + forceString + "%\' OR itm.itemModel like \'%" + forceString + "%\')";
}
if ((this.categoryId != -2)) {
queryString = queryString + " OR";
queryString = queryString + " itm.categoryId = " + this.categoryId;
}
fromStatement = fromStatement + queryString;
try {
sb = hib_session();
tx = sb.beginTransaction();
results = sb.createQuery(fromStatement).setParameter("which", this.which).list();
tx.commit();
} catch (Exception ex) {
tx.rollback();
Logger.getLogger(SearchesBean.class.getName()).log(Level.SEVERE, null, ex);
} finally {
tx = null;
sb = null;
}
this.itemDetail = results;
return "search";
}
I've made a search tool in java.
String query = "SELECT * FROM Customer WHERE 1 = 1 ";
if (!firstname.isEmpty()) query += "AND cName = '" + firstname + "' ";
if (!lastname.isEmpty()) query += "AND cLastName = '" + lastname + "' ";
if (!epost.isEmpty()) query += "AND cEpost = '" + epost + "' ";
if (!phonenumber.isEmpty()) query += "AND cPhonenumber '" + phonenumber + "' ";
That ouput this if all of those paramerets has values:
SELECT * FROM Customer WHERE 1 = 1
AND cName = 'test'
AND cLastName = 'test1'
AND cEpost = 'test2'
AND cPhonenumber 'test3'
This way I can get better results by filling in more data, but i can still choose to not do.. I need a solution for JPA for this.. any tips?
Thanks!
EDIT: End result based on the answer below:
public static List<Customer> searchCustomersByParameters(String firstname, String lastname,
String epost, String phonenumber) {
String sql = "SELECT c FROM Customer c WHERE 1 = 1 ";
if (!firstname.isEmpty()) sql += "AND c.cName = :firstname ";
if (!lastname.isEmpty()) sql += "AND c.cLastName = :lastname ";
if (!epost.isEmpty()) sql += "AND c.cEpost = :epost ";
if (!phonenumber.isEmpty()) sql += "AND c.cPhonenumber = :phonenumber";
Query q = em.createQuery(sql);
if (!firstname.isEmpty()) q.setParameter("firstname", firstname);
if (!lastname.isEmpty()) q.setParameter("lastname", lastname);
if (!epost.isEmpty()) q.setParameter("epost", epost);
if (!phonenumber.isEmpty()) q.setParameter("phonenumber", phonenumber);
return q.getResultList();
}
While it is of course possible to create dynamic SQL using string concatenation as suggested in this answer, a more type safe and less risky (in terms of SQL injection) approach is to use the JPA criteria API
public static List<Customer> searchCustomersByParameters(String firstname, String lastname,
String epost, String phonenumber) {
var qb = em.getCriteriaBuilder();
var query = qb.createQuery(Customer.class);
var root = query.from(Customer.class);
query.select(root);
if (!firstname.isEmpty()) query.where(qb.equal(root.get("cName"), firstName));
if (!lastname.isEmpty()) query.where(qb.equal(root.get("cLastName"), lastname));
if (!epost.isEmpty()) query.where(qb.equal(root.get("cEpost "), epost ));
if (!phonenumber.isEmpty()) query.where(qb.equal(root.get("cPhonenumber "), phonenumber));
return em.createQuery(query).getResultList();
}
... or if you don't strictly need to use JPQL you could also use a third party SQL builder like jOOQ:
public static List<Customer> searchCustomersByParameters(String firstname, String lastname,
String epost, String phonenumber) {
return
ctx.selectFrom(CUSTOMER)
.where(!firstname.isEmpty() ? CUSTOMER.CNAME.eq(firstname) : noCondition())
.and(!lastname.isEmpty() ? CUSTOMER.CLASTNAME.eq(lastname) : noCondition())
.and(!epost.isEmpty() ? CUSTOMER.CEPOST.eq(epost) : noCondition())
.and(!phonenumber.isEmpty() ? CUSTOMER.CPHONENUMBER.eq(phonenumber) : noCondition())
.fetchInto(Customer.class);
}
Disclaimer: I work for the company behind jOOQ
use ? and set Parameters for preventing sql injection and in JPA you can use native sql as old way you do and also JPQL.Generate your sql by conditions and set your parameters.I use here where 1=1 condition to easy append next conditions by and.Otherwise you will have difficulties for appending "where" to your sql.
by native:
public static List<YourEntity> getFromTable(String name,String surname) {
EntityManager em = PersistenceManager.instance().createEntityManager();
try {
String sql = " select * from table where 1=1 ";
if(name!=null && !name.trim().isEmpty()){
sql +=" and name = :name";
}
if(surname!=null && !surname.trim().isEmpty()){
sql +=" and surname = :surname";
}
Query q = em.createNativeQuery(sql);
if(name!=null && !name.trim().isEmpty()){
q.setParameter("name", name);
}
if(surname!=null && !surname.trim().isEmpty()){
q.setParameter("surname", surname);
}
List<YourEntity> l = q.getResultList();
return l;
} finally {
em.close();
}
}
By jpql:
public static List<YourEntity> getFromTable(String name,String surname) {
EntityManager em = PersistenceManager.instance().createEntityManager();
try {
String sql = " select e from YourEntity e where 1=1 ";
if(name!=null && !name.trim().isEmpty()){
sql +=" and e.name = :name";
}
if(surname!=null && !surname.trim().isEmpty()){
sql +=" and e.surname = :surname";
}
Query q = em.createQuery(sql);
if(name!=null && !name.trim().isEmpty()){
q.setParameter("name", name);
}
if(surname!=null && !surname.trim().isEmpty()){
q.setParameter("surname", surname);
}
List<YourEntity> l = q.getResultList();
return l;
} finally {
em.close();
}
}
I'm working a project(Full source code here) and as part of the project, I've created a Database class to make interfacing with the SQLite database easier and cleaner. I'm currently attempting to write a method that will use SELECT along with the given parameters to return a string array containing the results. The issue that I'm having is that when I run the program to test it, Eclipse throws java.sql.SQLException: no such column: 'MOVES'
But, when I look at the database in a GUI, it clearly shows the column that I'm trying to access, and when I execute just the sql in the same program, it's able to return the data.
This is the method that I've written so far:
public String[] get(String what, String table, String[] conds) {
try {
if (what.equals("*")) {
throw new Exception("'*' selector not supported");
}
c.setAutoCommit(false);
stmt = c.createStatement();
String sql = "SELECT " + what.toUpperCase() + " FROM " + table.toUpperCase();
if (conds.length > 0) {
sql += " where ";
for (int i = 0; i < conds.length; i++) {
if (i == conds.length - 1) {
sql += conds[i];
break;
}
sql += conds[i] + " AND ";
}
}
sql += ";";
System.out.println(sql);
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
if (table.toUpperCase().equals("DEX")) {
String id = "";//rs.getInt("id") + "";
String species = rs.getString("species");
String type1 = rs.getString("type1");
String type2 = rs.getString("type2");
String hp = rs.getInt("hp") + "";
String atk = rs.getInt("atk") + "";
String def = rs.getInt("def") + "";
String spa = rs.getInt("spa") + "";
String spd = rs.getInt("spd") + "";
String spe = rs.getInt("spe") + "";
String ab1 = rs.getString("ab1");
String ab2 = rs.getString("ab2");
String hab = rs.getString("hab");
String weight = rs.getString("weight");
return new String[] { id, species, type1, type2, hp, atk, def, spa, spd, spe, ab1, ab2, hab,
weight };
} else if (table.toUpperCase().equals("MOVES")) {
String name = rs.getString("NAME");
String flags = rs.getString("FLAGS");
String type = rs.getString("TYPE");
String full = rs.getString("LONG");
String abbr = rs.getString("SHORT");
String acc = rs.getInt("ACCURACY") + "";
String base = rs.getInt("BASE") + "";
String category = rs.getInt("CATEGORY") + "";
String pp = rs.getInt("PP") + "";
String priority = rs.getInt("PRIORITY") + "";
String viable = rs.getInt("VIABLE") + "";
return new String[] { name, acc, base, category, pp, priority, flags, type, full, abbr, viable };
} else if (table.toUpperCase().equals("LEARNSETS")) {
String species = rs.getString("SPECIES");
String moves = rs.getString("MOVES");
return new String[] { species, moves };
} else {
throw new Exception("Table not found");
}
}
rs.close();
stmt.close();
c.close();
} catch (Exception e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
System.exit(0);
}
return null;
}
Screencaps:
UPDATE:
I wanted to double-check that the database viewer I was using wasn't messed up, so I opened up the terminal and ran
sqlite3 git/Pokemon/data.db
pragma table_info(MOVES);
Receiving this in response:
0|SPECIES|TEXT|0||0
1|MOVES|TEXT|0||0
Finally figured it out, for anybody else having this issue, make sure that the data you're trying to get from the result set is actually included in it. For example, if I call SELECT SPECIES FROM DEX; the result set won't contain other things like id, type, or any of those other columns, it will ONLY contain the species column. I'm not sure why it took me so long to figure this out, but there you have it.