Best SQL Option for Performance - java

I currently need to execute a database query that involves data from three separate tables.
(bases,member,sell_transaction)
The bases table looks like the following
base_id(PK) name state
The member table looks like the following
id(PK) last_name username email first_name
The sell_transaction table has the following schema
transaction_id(PK) city
state
base_id
date id
agentId
NOTE- these tables contain more columns, but they are irrelevant, so I am going to save the time and not write them out.
I am working on a transaction inquiry that involves data from all of these tables. I need to return this data in a TransactionItem that I am populating from these three tables
The TransactionItem as a Pojo looks like the following
public TransactionItem(){
private String firstName;
private String lastName;
private String email;
private String baseName;
private String city;
private String state;
private Date date;
public String getFirstName(){
return firstName;
}
public String setFirstName(String firstName){
this.firstName = firstName;
}
...
...///The rest of the getters and setters
...
...
}
Currently I am doing three separate selects from each table, which is taking longer then I would like. I would image that there is a way I could use a join or nested select statements,etc.
The data and conditions and their corresponding tables are as follows
I need...
first_name, last_name,id from member
I need
name and state from bases where base_id from sell_transaction is equal to base_id from bases
Again there is more that I need, but it is redundant to name them off, The idea should still be clear, I need to query data that is dependent on each other. I am not sure performance wise what is the best performance option. The amount of data that is being traversed could end up being very large or very small(not sure if that matters).
select
b.name,b.state,
s.city,s.state,s.duty,s.branch,s.date,
m.first_name,m.last_name,m.email,m.phone,m.id,s.transaction_id
from
bases as b, sell_transaction as s, member as m
where
s.agentId is null and
s.username = m.username and
b.base_id = s.duty

select first_name, last_name, member.id member_id, bases.name, bases.state
from bases, sell_transaction, member
where sell_transaction.base_id = bases.base_id
and member.id = sell_transaction.agentId;
I am going out on a limb here and guessing that agentID is the connection to member from sell_transaction, but it's not clear or obvious, and possibly incorrect (unless you clarify your data model).

Related

JDBC ResultSet - Many To Many

Greeting to all,
As I'm learning Java, JDBC and MySQL
I reach one point where I would like to perform the following
I have 2 entites
class User {
private Long id;
private String username;
...
...
private Set<Team> teams;
Constructors /
Getter/Setter
Second Entity
class Team {
private Long id;
private String name;
private Set<Users> users
Constructors/Getter/Setters
in my mysql there are 3 tables corresponding to User/Team and hybrid table where is the relationship between them users_teams holding user_id and team_id
My question is is there is a way when I call a sql query to select 1 team and all users in that particular team and get the info with ResultSet and build the Team object with the set of the users
or I need to do couple of sql queries to get the info separately and build the object later ?

Map result of a sql query to pojo using spring Data JPA

I am a student learning Spring data jpa. I am trying to solve some of practice coding questions. I have a question which i could not find answer to.
I have a database table by name MYDB which has fields:
(id, firstname, lastname, rollno, major, country)
And i have an sql query like this:
select Count(*) as counts, lastname as last_name, major as major_field from MYDB group by country
The above query returns three fields: counts(which is not a db column), last_name and major_field.
I have a POJO like this:
public class MyPojo {
private int counts;
private String lastName;
private String majorField;
// Getters and Setters of all data members here
...................
}
My question is how do i map the result that i got from sql query to my POJO? I need to assign:
counts = counts(from sql query), lastName = last_name(from sql query), majorField = major_field(from sql query).
I am stuck at this point and do not know how to implement further to map result of sql query to POJO:
public interface MyRepo extends JpaRepository<MyPojo, String> {
#Query(value=MY_SQL_QUERY, nativeQuery = true)
List<MyPojo> findAll();
}
Ultimately i need to convert MyPojo to a Json object, but i know how to do that part. I am only stuck without ideas about assigning result of sql query to pojo.
Problem solved using interface-based projections:
https://www.baeldung.com/jpa-queries-custom-result-with-aggregation-functions#solution_interface_jpa
Use the javax.persistence #Column annotation to specify which values from the query are used to populate the fields of the Java object:
public class MyPojo {
#Column(name = "counts")
private int counts;
#Column(name = "last_name")
private String lastName;
... and so on
}
Here is a great tutorial on the annotations:
https://www.javaworld.com/article/3373652/java-persistence-with-jpa-and-hibernate-part-1-entities-and-relationships.html
You have to use TypedQuery and give your class name for executing and mapping your query result into pojos

how to insert data in 2 tables at a time using selectKey in myBatis

I need to store data in 2 tables using myBatis select key and Java,can anyone please help how to do this.My table structures are:
Temp Sect
id name created_at sid sectName duration priorty
now i need to insert name,sectName,duration,priority in Temp and Sect tables,the code which i wrote was:
#Insert("insert into Temp (name) values(#{name})")
#SelectKey(statement="call identity()", keyProperty="id", before=false,
resultType=int.class)
public int insertTemp(Name name);
#Insert("insert into sect (name,duration.priority) values(#{name}, #
{duration},#{priority})")
#SelectKey(statement="call next value for TestSequence",
keyProperty="nameId", before=true, resultType=int.class)
public int insertSect(sectName name);
And my POJO classes are:
Public Temp{
private int id;
private String name;
private int creat_at;
//setters getters
}
Public Temp{
private int sid;
private String sectName;
private int duration;
private int priority;
//setters getters
}
Please someone tell me how to write that query and the command which i wrote was correct or wrong?
Your model is slightly confusing. I'll assume that f second Temp was supposed to be named "Sect"
You actually use flag before = true in insertSect. You can use this like that:
//First insert into db
#Insert("insert into sect (**id**, name,duration.priority) values(**#{id}**, #{name}, #
{duration},#{priority})")
(...)
public int insertSect(sectName name);
//second insert
#Insert("insert into Temp (**id**, name) values(**#{id}**, #{name})")
//there's no select key anymore
public int insertTemp(**#Param("name")** Name name, **#Param("id") id**);
//and calling it
mapper.insertSect(sect)
sect.getId() //will return ID returned by "call next value for TestSequence"
mapper.insertTemp(name, sect.getId())
The '**' character used to bring attention to changes in your code. Unfortunately SO don't bold text in code section.
It is also possible to use one insert if you don't need to have created ID in more that one object after insert.
#Insert("insert into Temp(id, name) values (#{sect.id}, #{name});
insert into Sect(id, name, ...) values (#{sect.id}, #{sect.name}, ...)")
#SelectKey(statement="call next value for TestSequence",
keyProperty="sect.id", before=true, resultType=int.class)
public void insert(#Param("sect") Sect sect, #Param("name") String name)
If you need to use two different keys, the best way will be to use one method, which will call two inserts and just annotate it as #Transcational, so failure on second insert will rollback second, f.e.
#Transactional
void insert(...) {
mapper.firstInsert(...)
mapper.secondInsert(...)
}
If it isn't what you wanted, please clarify - for now your question (and model) is a little confusing.

MySQL - INSERT row with SELECT sub-query to fill foreign key while making sure SELECT returns a value

I have three tables
STUDENT - student_id, first_name, second_name, class_id (FK)
CLASS - class_id, year, special, school_id (FK)
SCHOOL - school_id, name, address
These tables correspond to Java classes...
class student {
private String firstName;
private String secondName;
private Class class;
}
class Class {
private int year;
private boolean special;
private School school;
}
class School {
private String name;
private String address;
}
I want to INSERT Student into DB.
How could I do that when:
I don't know which entries are already in DB.
I want to do it with as few queries as possible.
Is there any faster way than this?
query - INSERT INTO School VALUES ... ON DUPLICATE KEY UPDATE ... (while name + address will be unique composite key)
query - INSERT INTO Class VALUES ... ON DUPLICATE KEY UPDATE ... (while year + special + school_id will be unique composite key)
query - INSERT INTO Student VALUES ... ON DUPLICATE KEY UPDATE ... (while first_name + second_name + class_id will be unique composite key)
Second and Third query would use sub-queries or LAST_INSERT_ID() from previous query (but that's not usable in cases when more FK's are present)
EDIT: I'm NOT using ORM... just low level JDBC

Whats the best way to forma list of objects from different tables using Hibernate and spring

I am trying to create a list of objects that contains different types of logs from my db. I would like to build the list such that the order is by most recently made (a date created field that's in each of the tables).
So is the only way to do it by getting each list (4 different kinds of logs) and then cycle through them and put them in the new list by comparing them and getting the most recent one each time? This seems like it could take a long time if the list are really long which they may or may not be.
IS there a better way to do it with Hibernate where I could put all the tables together and have it do the work for me? The tables don't share any keys or anything for a normal join?
Any suggestions would be helpful.
contactLog
has columns (Id, memberId, phonenumber, email, address, dateChanged)
salaryLog
has columns (Id, memberId, salary, dateChanged)
relationsLog
has columns (Id, memberId, relationId, dateChanged)
personalInfoLog
has columns (Id, memberId, height, weight, eyeColor, hairColor, dateChanged)
The purpose of these logs is to indicate anytime someone changes information and Im trying to provide the user with a audit page that will show all changes to these different objects.
I suggest using UNION, but if I'm not mistaken, HQL does not support UNION, so you'll have to use native query and result transformer. Here's a sample:
public class Log {
private Long id;
private Long memberId;
private String logType;
private Date dateChanged;
// getters & setters here
}
public class LogService {
#PersistenceContext
private EntityManager em;
public List<Log> getLogs(){
final Session sess = em.unwrap(Session.class);
final SQLQuery query = session.createSQLQuery(
"select id,memberId,'CONTACT' as logType, dateChanged from contactLog"+
"union select id,memberId,'SALARY' as logType,dateChanged from salaryLog"+
"union select id,memberId,'RELATIONS' as logType,dateChanged from relationsLog"+
"union select id,memberId,'PERSONAL INFO' as logType,dateChanged from personalInfoLog "+
"order by dateChanged desc";
);
query.setResultTransformer(Transformers.aliasToBean(Log.class));
return query.list();
}
}
Notice that only common columns are selected (because you must select the same number of columns from each table when using union).
If you want to view the full details of the log, just use the id to load the specific log and the log type to know from which table you would have to look for the full information.
or
You could modify the query to concat all the changed information into one column for all the tables (which means adding a new field in Log.class).
public class Log {
private Long id;
private Long memberId;
private String logType;
private Date dateChanged;
private String changedInfo;
// getters & setters here
}
"select id,memberId,'CONTACT' as logType, dateChanged, phonenumber||','||email||','||address as changedInfo from contactLog"+
"union select id,memberId,'SALARY' as logType,dateChanged,salary as changedInfo from salaryLog"+
"union select id,memberId,'RELATIONS' as logType,dateChanged,relationId as changedInfo from relationsLog"+
"union select id,memberId,'PERSONAL INFO' as logType,dateChanged, height||','|| weight||','|| eyeColor||','|| hairColor as changedInfo from personalInfoLog "+
"order by dateChanged desc
An another approch will be to create a view on your database, and use spring and hibernate as usual.

Categories

Resources