So I have this sql query:
"select company, surveys.surveyID, questionID, question, questionScore FROM surveys INNER JOIN (SELECT * FROM companies INNER JOIN "
+ "(SELECT * FROM questions INNER JOIN categories "
+ "ON questions.catID = categories.catID) AS cats "
+ "ON companies.questionID = cats.questionID) AS yes "
+ "ON yes.surveyID = surveys.surveyID WHERE company=?"
'cats' and 'yes' have no meaning and are just victums of my extremely verbose naming scheme.
company is just a string.
The table it returns would look like this:
---------------------------------------------
|companyName|surveyID|questionID|questionScore|
---------------------------------------------
The primary key for this table is (companyName, surveyID AND QuestionID) because each company can have multiple surveys, each survey has a number of questions.
Then I have this class:
public class Company
{
private String companyName;
private String surveyorName;
private String surveyorTitle;
private int surveyID;
private Map<Integer,Integer> questions;
public Company(String name, String surveyor, String surveyerTitle,
int surveyID, Map<Integer, Integer> questions)
{
this.companyName = name;
this.surveyorName = surveyor;
this.surveyorTitle = surveyerTitle;
this.surveyID = surveyID;
this.questions = questions;
}
With a all the getters and setters
For example, say there is a company Mens Insamen. SurveyID is 1.
So
Mens Insamen 1 q1 3
Mens Insamen 1 q2 1
etc...
Now I need to populate a List of Company objects with the data from the sql query. I have tried for a while but couldn't really come up with anything.
If it is (unsurprisingly) unclear (fokol (no) coffee) I can improve it at some point.
Thanks in advance
create class CompanyMapper have a method inside it, pass that method the SQL ResultSet as input, loop thru it and create a list of Company and return it.
class CompanyMapper{
public List<Company> getCompanies(ResultSet rs){
ArrayList<Company> compList = new ArrayList<Company>();
while(...rs has entry...){
//Add new Company to the list
}
return compList;
}
It's really difficult to tell, what you have so far from the question, but if you want to populate a list of your custom objects, then you need to do something like this:
public List<Company> getCompanies() throws SQLException
{
List<Company> result = new ArrayList<Company>();
Connection connection = DriverManager.getConnection(...);
Statement statement = connection.createStatement();
ResultSet set = statement.executeQuery("your query here");
set.beforeFirst();
while(set.next())
{
String textData = set.getString("columnname");
int integerData = set.getInt("columnname");
// you can also use set.getString(columnindex);
Company company = new Company();
company.set(...);
result.add(company);
}
connection.close();
return result;
}
You can achive this simply using arraylist and your while loop
Create your arraylist for compines just outside the loop and add each Company object to this array list using the loop
ArrayList<Company> compList = new ArrayList<Company>();
while{
/*read values to variables and create an object of Company
then add to arraylist as follows **/
Company comp = new Company (name, surveyor, surveyerTitle,surveyID,questions);
compList.add(comp);
}
1- You should create a connection to the database using,
Class.forName(DB_LIBRARY);
connection = DriverManager.getConnection(CONNECTION_PARAMETRS);
Note that you need to replace DB_LIBRARY with the valid driver's library, and CONNECTION_PARAMETERS with your database connection setting (eg. host name, user name, password, ..etc).
2- create a statement, and return a result set
Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery(your_select_query);
3- loop through the result set and fetch data
Company company;
while(rs.next()){
company = new Company(rs.getString(1),
rs.getString(2),
rs.getString(3),
rs.getInt(4),
new HashMap<Integer, Integer>().put(rs.getInt(5), rs.getInt(6)
}
Note that you can use columns name or their number, also you may use an ArrayList if you want to fetch more than one record, as following
ArrayList<Company> companies = new ArrayList<Company>();
while(rs.next()){
companies.add(new Company(rs.getString(1),
rs.getString(2),
rs.getString(3),
rs.getInt(4),
new HashMap<Integer, Integer>().put(rs.getInt(5), rs.getInt(6));
}
Related
Requirement : I have a file from which I need to add the assistant employee id corresponding to it's manager into db. So in file I am getting login id of assistant. I need to pass the login id to db in order to fetch the corresponding employee id of the assistant and add into the list which I am getting from file.
// code for getting employee from file - returns a list
private void setAssistantEmployeeId(List<E> empFile){
List<E> empFilter = empFile.stream().filter(emp -> emp.getLoginId()!=null).collect(Collectors.toList());
String sql = "SELECT ID FROM EMPLOYEE WHERE LOGIN_ID = ";
List<E> tempList = new ArrayList<>(empFilter);
for(E emp : empFilter){
tempList.addAll(jdbcTemplate.query(sql+emp.getLoginId(), (resultset,i)->{
emp.setAssistantEmployeeId(resultset.getString("ID"));
return emp;
}));
}
}
The above code is working as expected but it's taking lot of time to execute. I need some help to optimize this code. Can someone please help me in optimizing this code?
Thank you.
private void setAssistantEmployeeId(List<E> empFile) throws SQLException {
List<E> empFilter = empFile.stream().filter(emp -> emp.getLoginId()!=null).collect(Collectors.toList());
//1. query all LOGIN_ID
String sql = "SELECT ID, LOGIN_ID FROM EMPLOYEE WHERE LOGIN_ID IN (" + empFilter.stream().map(emp -> emp.getLoginId())
.collect(Collectors.joining("','")) + ")";
// create map[LOGIN_ID, ID]
ResultSet rs = runQuery(sql); // execute this query in your way
Map<String, String> id_loginId = new HashMap<>();
while (rs.next()) {
id_loginId.put(rs.getString("LOGIN_ID"), rs.getString("ID"));
}
// 3. assign ID value
empFilter.forEach(e -> {
e.setAssistantEmployeeId(id_loginId.getOrDefault(e.getLoginId(), ""));
});
}
I'm new to java and I need help with displaying a joined table/query in jtable.
First, I have done displaying data from 1 table which is:
Select data from 1 table
insert the result to its entity and insert each one of it to a List
return the list to view and insert row to jtable
I am using a DAO pattern, which has a factory, interface, implement, entity and view.
So what if I select data from other table?
Here is my get method in implement for getting book
public List get(String find) {
try {
ps = db.connect().prepareStatement("SELECT * FROM books WHERE title like ? ");
ps.setString(1, "%" + find + "%");
status = db.execute(ps);
if (status) {
books = db.get_result();
listBooks = new ArrayList<>();
while (books.next()) {
entity_books b = new entity_books();
b.setId(books.getInt(1));
b.setId_category(books.getInt(2));
b.setTitle(books.getString(3));
listBooks.add(b);
}
books.close();
return listBooks;
}
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return null;
}
and then in my view:
listBooks = booksDAO.get(find.getText());
model = (DefaultTableModel) book_table.getModel();
model.setRowCount(0);
listBooks.forEach((data) -> {
model.addRow(new Object[]{
data.getId(),
data.getId_category(),
data.getTitle(),
});
});
This works fine, but I want the query to join table so I can see the category name instead of just ID category. I can do the query, but how do I apply that to my code?
Here is the query for joined table
select title,category from book b
join category c on c.id = b.id_category
Normally if I select only 1 table, I would insert it to its entity ( book table -> book entity ), so how do I handle this with multiple tables?
I didn't use prepared statement, but this code works on my end.
String sql = "SELECT * FROM customer c JOIN company cmp ON c.company_idcompany = cmp.idcompany";
ResultSet rs = stmt.executeQuery(sql);
//STEP 5: Extract data from result set
while (rs.next()) {
//Retrieve this from customer table
int id = rs.getInt("idcustomer");
//Retrieve this from customer table
String username = rs.getString("company_username");
//Display values
System.out.println("ID: " + id);
System.out.println("Username: " + username);
}
There are three tables <Table 1>, <Table 2> and <Table 3>
My SQL is something like this:
"Select table1.col1, table1.col2, table1.col3, table2.col4, table2.col5, table2.col6,
table3.col7, table3.col8 from Table 1 as table1
LEFT JOIN Table 2 as table2 on (table1.col1 = table2.col4)
LEFT JOIN Table 3 as table3 on (table1.col1 = table3.col8)"
The normal way to get the resultset is:
public List getExportDataList() throws ClassNotFoundException, SQLException {
Connection connect = null;
String url = "jdbc:.....";
String username = "username ";
String password = "password ";
try {
connect = DriverManager.getConnection(url, username, password);
} catch (SQLException ex) {
System.out.println("in exec");
System.out.println(ex.getMessage());
}
List dataList = new ArrayList<>();
PreparedStatement pstmt = connect.prepareStatement(
THE SQL CODE SHOWN ABOVE
}
ResultSet rs = pstmt.executeQuery();
while(rs.next()){
Table1 table1 = new Table1();
table1.setCOL1(rs.getString("col1"));
table1.setCOL2(rs.getString("col2"));
dataList.add(table1);
}
rs.close();
pstmt.close();
connect.close();
return dataList;
}
so that the "dataList" can be used to display the data in Primefaces dataTable.
However, this way only can save the columns in Table1 to the "dataList". I tried to dataList.add(table2) as well as dataList.add(table3) at the same time, but there is an error : "/reportGenerate.xhtml #50,75 value="#{reportData.dateCreated}": The class 'net.picary.model.Liaison' does not have the property 'dateCreated'."
Can someone tell me how to save all the selected columns from the three tables into "dataList"? Or any alternative way to achieve it?
error: "/reportGenerate.xhtml #50,75
value="#{reportData.dateCreated}": The class
'net.picary.model.Liaison' does not have the property 'dateCreated'."
Your problem is not with Query or JDBC, you should to make sure that attribute dateCreated exist in your net.picary.model.Liaison class with getter and setter like this :
private Date dateCreated;
public String name;
public String experience;
public Date getDateCreated() {
return dateCreated;
}
public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
So when your page reportGenerate.xhtml try to load this attribute it not find it, because :
Not exist in your class
It exist but it is private and without getter and setter.
So make sure that your attribute exist and have gtter and setter, this can solve your error.
EDIT
You have two choices :
When you get your result you should to use 3 List of type table1, table2, table3 and fill them in the same loop like this :
List dataList1 = ...;
List dataList2 = ...;
List dataList3 = ...;
while(rs.next()){
table1 = new Table1();
table1.setCOL1(rs.getString("col1"));
...
dataList1.add(table1);
table2 = new Table2();
table2.setCOL1(rs.getString("col1"));
...
dataList2.add(table2);
table3 = new Table3();
table3.setCOL1(rs.getString("col1"));
...
dataList3.add(table3);
}
and in your xhtml page you had to use this three List instead to one
Create a new Object which combine this three Table like this :
class MyObject {
private Table1 table1;
private Table2 table2;
//constructor
//getters and setters
}
Then create a List<MyObject> list = ....; and set information in each table.
Hope you get my point, good luck
First, Check whether column names (col1,col2,col3,..) are with same name in your code in java with all the three db tables (table1,table2,table3).
(ie)
...
Table1 table1 = new Table1();
table1.setCOL1(rs.getString("col1"));
table1.setCOL2(rs.getString("col2"));
dataList.add(table1);
....
In the above code check you have "col1" is in same name with db column in Table1,Table2,Table3.If the column name(s) is different in database and in your code ,add aliases to your MySQL query and match it with same name in your java code.
If the column name matches, then set the column value for your table 2 and 3.
Then, add it to your Datalist.
....
....
table2.setCOL1(rs.getString("col1"));
dataList.add(table2);
....
and so on. Also, check you have added try/catch for your code to avoid exceptions like Nullpointer,SQLException etc.. which may arise during SQL transactions.
This is my function to get all rows from table player.
public List<Player> getAllPlayer() {
String sql = "SELECT * FROM PLAYER";
List<Player> lstPlayers = getJdbcTemplate().query(
sql, new BeanPropertyRowMapper(Player.class)
);
return lstPlayers;
}
I want to get data from another table 'student' using this same function.
Is it possible to get data from both table using same function by changing the
above code something like below ?
public List<Object> getData(String TableName) {
String sql = "SELECT * FROM " + TableName;
List<Object> lstPlayers = getJdbcTemplate().query(
sql, new BeanPropertyRowMapper(Object.class)
);
return lstPlayers;
}
You could do something like the following
List<Player> players = getData(Player.class);
List<Student> students = getData(Student.class);
public List<T> getData(Class<T> clazz) {
String sql = "SELECT * FROM " + clazz.getSimpleName();
List<T> lstPlayers = getJdbcTemplate().query(
sql,
new BeanPropertyRowMapper(clazz));
return lstPlayers;
}
However in real life there's not much advantage. It's not that common to want to load all the contents of a database table at once due to performance and other reasons, so this method won't be as helpful as you think.
I want to create a list with my database field values.
There are 2 columns, name and surname.
I want to create a list that stores all names in name column in a field and then add to my DTO.
Is this possible?
Steps you can follow: -
First you need to have a List<String> that will store all your names. Declare it like this: -
List<String> nameList = new ArrayList<String>();
Now, you have all the records fetched and stored in ResultSet. So I assume that you can iterate over ResultSet and get each values from it. You need to use ResultSet#getString to fetch the name.
Now, each time you fetch one record, get the name field and add it to your list.
while(resultSet.next()) {
nameList.add(resultSet.getString("name"));
}
Now, since you haven't given enough information about your DTO, so that part you need to find out, how to add this ArrayList to your DTO.
The above list only contains name and not surname as you wanted only name. But if you want both, you need to create a custom DTO (FullName), that
contains name and surname as fields. And instantiate it from
every ResultSet and add it to the List<FullName>
JDBC unfortunately doesn't offer any ways to conveniently do this in a one-liner. But there are other APIs, such as jOOQ (disclaimer: I work for the company behind jOOQ):
List<DTO> list =
DSL.using(connection)
.fetch("SELECT first_name, last_name FROM table")
.into(DTO.class);
Or Spring JDBC
List<DTO> list =
new JdbcTemplate(new SingleConnectionDataSource(connection, true))
.query("SELECT first_name, last_name FROM table", (rs, rowNum) ->
new DTO(rs.getString(1), rs.getString(2));
Or Apache DbUtils:
List<DTO> list =
new QueryRunner()
.query(connection,
"SELECT first_name, last_name FROM table",
new ArrayListHandler())
.stream()
.map(array -> new DTO((String) array[0], (String) array[1]))
.collect(Collectors.toList());
I've used Java 8 for the Spring JDBC / Apache DbUtils examples, but it can be done with older versions of Java as well.
It is. What have you tried ?
To access the database, you need to use JDBC and execute a query, giving you a ResultSet.
I would create an class called FullName with 2 String fields name and surname. Just populate these in a loop using
rs.getString("NAME"); // column name
rs.getString("SURNAME");
e.g.
List<FullName> fullnames = new ArrayList<FullName>();
while (rs.next()) {
fullnames.add(new FullName(rs));
}
Note that I'm populating the object via the ResultSet object directly. You may choose instead to implement a constructor taking the 2 name fields.
Note also that I'm creating a Fullname object. So the firstname/surname are kept separate and you have the freedom to add initials etc. later. You may prefer to rename this Person and that will give you the freedom to add additional attributes going forwards.
What worked for me is:
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
ArrayList<String> resultList= new ArrayList<>(columnCount);
while (rs.next()) {
int i = 1;
while(i <= columnCount) {
resultList.add(rs.getString(i++));
}
}
return resultList;
This worked for me->
private List<Object[]> convertResultsetToObject(ResultSet rs) throws SQLException {
List<Object[]> results = new ArrayList<Object[]>();
int count = 0;
if(rs != null) {
ResultSetMetaData rsm = rs.getMetaData();
count = rsm.getColumnCount();
}
while(rs != null && rs.next()) {
Object [] obj = new Object[count];
int temp = 1;
while(temp <= count) {
obj[temp - 1] = rs.getObject(temp);
temp++;
}
results.add(obj);
}
return results;
}