I need to display all the columns from the table in java. So far I have tried resultSet java object but it is not working for me
public class dbtest {
public static Session session = null;
public ArrayList < String > ColValue() throws IOException {
// TODO Auto-generated method stub
FileReader reader = new FileReader("Configuration\\Config.properties");
Properties p = new Properties();
p.load(reader);
String serverIp = p.getProperty("ServerIp");
String keyspace = p.getProperty("ServerPwd");
Cluster cluster = Cluster.builder().addContactPoints(serverIp).withCredentials("user", "password").build();
session = cluster.connect(server);
String query = null;
String cqlStatement = "select * from table_name";
ArrayList < String > casVal1 = new ArrayList < >();
for (Row row: session.execute(cqlStatement)) {
if (!casVal1.contains(query)) {
casVal1.add(query);
}
}
System.out.println(casVal1.size());
System.out.println(casVal1);
return (casVal1);
}
}
Need all the columns in results as outcomes.
You can get the column via the ResultSet.getColumnDefinitions Method
com.datastax.driver.core.ResultSet result = xxxxx;
for (Definition definition : result.getColumnDefinitions()) {
String name = definition.getName();
}
Related
So, I am creating an application in javaFX (for learning purposes only) which mainly consists of a tabpane with sub-fxmls for each tab. Each tab consist of a tableview with data collected from a database. To connect to the database I have a separate connection class that creates a new connection pool using c3p0.
My first question is: Should I create (and close) a new connection for every query I make to the database?
Example: upon entering a new tab I create a new connection, collect the data and then close the connection (with statement and resultset).
If not, how would I do this in a proper and efficient way?
My second question: Currently my application is doing what's described above, but I notice that if I leave the application open for a while, without interacting with it, whenever I start interacting with it again it freezes for a bit before it continues. The current table that is viewed at that time then shows "no data in table", until I switch to another tab and then the data is displayed properly again. Why does this happen?
I am quite new to Java in general, and I couldn't find anything by searching that resembled my problem. My database is a postgres db.
EDIT 1:
Regarding question 2:
I have followed the mvc-pattern for this, not sure if that's a good idea, but that's another question.
There are four classes that play a part in a table's creation, which are:
Controller class:
public class StockController {
//tableview from fxml-file
#FXML
private TableView<List<Object>> stockTable;
//
private BuildDataModel stockData = new BuildDataModel();
//Called from main whenever currently active tab changes to this tab.
public void CreateView(){
String query = "SELECT component.name, stock.* FROM component NATURAL JOIN stock";
stockData.BuildData(stockTable, query);
}
//Called from main whenever currently active tab changes to another tab.
public void DestroyView(){
if(!stockTable.getColumns().isEmpty()) {
stockData.DeleteData();
}
}
}
Model class:
public class BuildDataModel {
private Connection conn;
#FXML
private TableView<List<Object>> tableview;
public TableData data;
private TableData getAllData(String query){
List<List<Object>> data = new ArrayList<>();
List<String> columnNames = new ArrayList<>();
PreparedStatement st = null;
ResultSet rs = null;
try {
conn = PostgresConnection.CreateConnection();
st = conn.prepareStatement(query);
rs = st.executeQuery();
//We create columns
int columnCount = rs.getMetaData().getColumnCount();
for(int i = 1; i <= columnCount; i++) {
String columnName = rs.getMetaData().getColumnName(i);
columnNames.add(columnName);
}
//We populate our tabledata object with the data
while(rs.next()){
List<Object> row = new ArrayList<>();
for(int i = 1; i <= columnCount; i++){
row.add(rs.getObject(i));
}
data.add(row);
}
}
catch (Exception e){
e.printStackTrace();
}
finally {
DbUtils.closeQuietly(conn, st, rs);
}
return new TableData(columnNames, data);
}
//Called from controller class, calls getAllData with the specified query
//and populates tableview based on this.
public void BuildData(TableView<List<Object>> tableview, String query) {
this.tableview = tableview;
try {
data = getAllData(query);
for (int i = 0 ; i < data.getNumColumns(); i++) {
TableColumn<List<Object>, Object> column = new TableColumn<>(data.getColumnName(i));
int columnIndex = i;
column.setCellValueFactory(cellData ->
new SimpleObjectProperty<>(cellData.getValue().get(columnIndex)));
tableview.getColumns().add(column);
}
tableview.getItems().setAll(data.getData());
}
catch (Exception e) {
}
}
public void DeleteData(){
tableview.getColumns().clear();
}}
Connection class:
public class PostgresConnection {
//DB credentials, modify as needed
private static final String HOST = "localhost";
private static final String DATABASE = "<INSERT DATABASE HERE>";
private static final String USERNAME = "<INSERT USERNAME HERE>";
private static final String PASSWORD = "<INSERT PASSWORD HERE>";
//Default postgresql port, don't change unless you know what you're doing.
private static final String PORT = "5432";
private static final String URL = "jdbc:postgresql://" + HOST + ":" + PORT + "/" + DATABASE;
private static final String DRIVER_NAME = "org.postgresql.Driver";
private static Connection conn;
//Disables C3P0-pool logging
static {
Properties p = new Properties(System.getProperties());
p.put("com.mchange.v2.log.MLog", "com.mchange.v2.log.FallbackMLog");
p.put("com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL", "OFF");
System.setProperties(p);
}
private static ComboPooledDataSource cpds = new ComboPooledDataSource();
public static Connection CreateConnection() throws SQLException {
try {
cpds.setDriverClass(DRIVER_NAME);
} catch (PropertyVetoException e) {
e.printStackTrace();
}
cpds.setJdbcUrl(URL);
cpds.setUser(USERNAME);
cpds.setPassword(PASSWORD);
cpds.setMinPoolSize(3);
cpds.setAcquireIncrement(5);
cpds.setMaxPoolSize(100);
cpds.setMaxStatements(180);
return cpds.getConnection();
}}
and DAO:
public class TableData {
private final List<String> columnNames;
private final List<List<Object>> data;
public TableData(List<String> columnNames, List<List<Object>> data) {
this.columnNames = columnNames;
this.data = data;
}
public int getNumColumns() {
return columnNames.size();
}
public String getColumnName(int index) {
return columnNames.get(index);
}
public int getNumRows() {
return data.size();
}
public Object getData(int column, int row) {
return data.get(row).get(column);
}
public List<List<Object>> getData() {
return data;
}
public void removeData(){
data.clear();
columnNames.clear();
}}
I have a database table in which there are already stored some data.
Now I want to have a Vaadin editable Table in my page with the data taken from database and when this Vaadin Table is updated (either add a row or edit the existing ones), the database should be updated aswell.
I was so close to that, but I realized I can't use just an INSERT query because the unique ID constraint is violated.
What can I do in order to achieve that? I really need your help!
The BeanItemContainer:
public BeanItemContainer createContainer() {
BeanItemContainer<Sct> beans = new BeanItemContainer<Sct>(Sct.class);
beans.addNestedContainerProperty("secti.sid");
beans.addNestedContainerProperty("secti.isa");
beans.addNestedContainerProperty("secti.order");
for (int i = 0; i < list.size(); i++) {
PS_SECTION section = list.get(i);
Long ps = section.getPS_SECTION();
String na = section.getNAME();
Long is = section.getISACTIVE();
Long or = section.getVORDER();
Object itemId = beans.addBean(new Sct(na, new BeanSect(ps, is, or)));
}
return beans;
}
Here is the save (update) button when clicked:
ClickListener saveListener = new ClickListener() {
private Long s4 = 0L;
#Override
public void buttonClick(ClickEvent event) {
Collection<?> itemIds = table.getItemIds();
Item item = null;
boolean isSaved = false;
PS_SECTION ps = null;
List<PS_SECTION> newlist = new ArrayList<PS_SECTION>();
int i = 0;
for(Object itemId : itemIds){
ps = new PS_SECTION();
item = table.getItem(itemId);
Long s1 = (Long) item.getItemProperty("ID").getValue();
String s2 = item.getItemProperty("SECTION").getValue().toString();
Long s3 = (Long) item.getItemProperty("ORDER").getValue();
Long s5 = 0L;
ps.setPS_SECTION(s1);
ps.setNAME(s2);
ps.setVORDER(s3);
ps.setISACTIVE(s4);
ps.setISGLOBAL(s5);
newlist.add(ps);
}
try {
// Here I call the query.
isSaved = dao.insertPsSections(newlist);
if (isSaved){
Notification.show("Success ");
unsavedChanges = false;
}
else if (!isSaved){
Notification.show("Problem");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Finally, the query:
public boolean insertPsSections(List<PS_SECTION> pssec) throws SQLException {
Boolean sv = false;
try {
this.setKeepConnOpen(true);
String insertsections = "INSERT INTO PS_SECTION"
+ "(PS_SECTION,NAME,ISACTIVE,ISGLOBAL,VORDER)"
+ "VALUES (?,?,?,?,?)";
for (PS_SECTION j : pssec){
Long section = j.getPS_SECTION();
String name = j.getNAME();
Long isa = j.getISACTIVE();
Long isg = j.getISGLOBAL();
Long order = j.getVORDER();
this.simpleUpdate(insertsections, false, section, name, isa, isg, order);
}
} finally {
this.doCommit();
this.closeConn(true);
sv=true;
}
return sv;
}
Hello am trying to fetch 10 rows of data from Cassandra table. But on each request same 10 row is returning. Please see my logic here. and advise me where am doing wrong here-
public class CustomerRequestDaoImpl implements CustomerRequestDao
{
private static Cluster cluster;
#Resource
private CassandraSessionFactory cassandraSessionFactory;
/** The ProductsByTagDaoImpl session. */
private Session session;
#Override
public List<CustomerRequest> getCustomerRequestData(final String productId, final String receiptPeriod)
{
final int RESULTS_PER_PAGE = 10;
session = cassandraSessionFactory.getSession();
final List<CustomerRequest> customerRequestdata = new ArrayList<CustomerRequest>();
try
{
final PreparedStatement statement =
session.prepare("select * from customer_request where product_id = :id and receipt_period = :receiptPeriod");
final BoundStatement boundStatement = new BoundStatement(statement);
boundStatement.setFetchSize(RESULTS_PER_PAGE);
boundStatement.setString("id", productId);
boundStatement.setString("receiptPeriod", receiptPeriod);
final ResultSet resultSet = session.execute(boundStatement);
final Iterator<Row> iter = resultSet.iterator();
final PagingState nextPage = resultSet.getExecutionInfo().getPagingState();
int remaining = resultSet.getAvailableWithoutFetching();
for (final Row rowdt : resultSet)
{
customerRequestdata.add(constructCustomerReq(rowdt));
if (--remaining == 0)
{
break;
}
}
}
catch (final Exception e)
{
e.printStackTrace();
}
return customerRequestdata;
}
#PostConstruct
public void init()
{
session = cassandraSessionFactory.getSession();
cluster = session.getCluster();
}
}
My Table-
My Table structure:-
CREATE TABLE customer_request (
product_id varchar PRIMARY KEY,
id varchar,
receipt_period varchar,
delivery_method_status varchar,
first_name varchar
);
return Response-
<e>
<deliveryMethodStatus null="true"/>
<firstName null="true"/>
<id>0b0352f6b3904</id>
<lastName Adkin="true"/>
<orderId>FORMS8a04e</orderId>
<orderItemId>FORMS8a04e-1</orderItemId>
<productId>PI_NAME_CHANGE</productId>
<receiptPeriod>2016-02-06</receiptPeriod>
<receivedDate null="true"/>
<requestData null="true"/>
Several remarks:
You should not re-prepare the query each time, it's an
anti-pattern. Prepare the statement only once and re-use it for each method call
The source code you show will always return the first page of
data because you break out of the for loop once remaining
variable counts down to 0. The PagingState object is not used
anywhere ...
You question is not clear either Hello am trying to fetch 10 rows of
data from Cassandra table. But on each request same 10 row is
returning. Which 10 rows do you want ? The first 10 rows ? The
10 rows after a threshold ?
Sample code for paging:
Note: prepared the following query only once: select * from customer_request where product_id = :id and receipt_period = :receiptPeriod LIMIT :lim and pass it along with the method
#Override
public List<Tuple2<String,CustomerRequest>> getCustomerRequestData(final String productId, PreparedStatement ps, final String receiptPeriod, String pagingState)
{
final int PAGE_SIZE = 10;
session = cassandraSessionFactory.getSession();
final List<CustomerRequest> customerRequestdata = new ArrayList<CustomerRequest>();
try
{
final BoundStatement boundStatement = ps.bind(productId, receiptPeriod, PAGE_SIZE);
boundStatement.setPagingState(PagingState.fromString(pagingState));
final ResultSet resultSet = session.execute(boundStatement);
final Iterator<Row> iter = resultSet.iterator();
final PagingState nextPage = resultSet.getExecutionInfo().getPagingState();
int remaining = resultSet.getAvailableWithoutFetching();
for (final Row rowdt : resultSet)
{
customerRequestdata.add(constructCustomerReq(rowdt));
if (--remaining == 0)
{
break;
}
}
}
catch (final Exception e)
{
e.printStackTrace();
}
return new Tuple2<>(nextPage.toString(), customerRe);
Please note the use of Tuple2 class to return the list of results as well as the paging state, serialized as a String to be passed easily to the front-end
I want to create multi parameter search using JDBC prepared statement so as to prevent SQL injection attack and improve performance. As I couldn't find the best way to do it on the net.
I've tried to implement on my own as follow.
In this program I want to allow the user to search an employee by either first name, last name or department id.
I want to know
if my implementation would prevent SQL injection
If I am using prepared statement correctly? I have some doubt on this line
PreparedStatement stat = conn.prepareStatement(sql.toString());
Let's say two users search by using the same parameters, and thus it would result the same
sql string. According to my implementation, would the database have to prepare that sql twice or just once?
public class EmpDAO {
public static List<Employee> findByCriteria(Employee e)
throws SQLException, IOException {
try (Connection conn = getConnection()) {
StringBuilder sql = new StringBuilder("SELECT * FROM Employee ");
//collect user supplied parameters
Map<String, String> params = new HashMap<String, String>();
if (e.getFname() != null && e.getFname().length() != 0) {
params.put(EmpDAO.FNAME, e.getFname());
}
if (e.getLname() != null && e.getLname().length() != 0) {
params.put(EmpDAO.LNAME, e.getLname());
}
if (e.getDepid() > 0) {
params.put(EmpDAO.DEPT_ID, new Integer(e.getDepid()).toString());
}
//construct prepared statement based on the parameters
Set<String> colSet = params.keySet();
if (colSet != null && !colSet.isEmpty()) {
StringBuilder whereClause = new StringBuilder(" WHERE");
String andOp = "";
for (String colName : colSet) {
whereClause.append(andOp);
whereClause.append(" ");
whereClause.append(colName);
whereClause.append("=? ");
andOp = " AND ";
}
sql.append(whereClause);
}
PreparedStatement stat = conn.prepareStatement(sql.toString());
int paramPos = 1;
for (String colName : colSet) {
if (colName.equals(EmpDAO.FNAME)) {
stat.setString(paramPos, params.get(colName));
}
if (colName.equals(EmpDAO.LNAME)) {
stat.setString(paramPos, params.get(colName));
}
if (colName.equals(EmpDAO.DEPT_ID)) {
stat.setInt(paramPos, Integer.parseInt(params.get(colName)));
}
paramPos++;
}
List<Employee> emp1 = new ArrayList<>();
try (ResultSet result = stat.executeQuery()) {
while (result.next()) {
Employee emp = new Employee();
emp.setDepid(result.getInt("DEPT_ID"));
emp.setEmpid(result.getInt("EMP_ID"));
emp.setFname(result.getString("FNAME"));
emp.setJobid(result.getInt("JOB_ID"));
emp.setLname(result.getString("LNAME"));
emp.setMangid(result.getInt("MANAGER_EMP_ID"));
emp.setSalary(result.getInt("SALARY"));
emp1.add(emp);
}
}
return emp1;
}
}
public static Connection getConnection() throws SQLException, IOException {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return DriverManager.getConnection("jdbc:mysql://localhost:3306/test",
"root", "root");
}
public static final String FNAME = "FNAME";
public static final String LNAME = "FNAME";
public static final String DEPT_ID = "FNAME";
}
Yes -- as written this will prevent SQL injection attacks and yes, that is how you use .prepareStatement. You should probably post this code on https://codereview.stackexchange.com/ if you want a critique of how it's done.
I have 15 usernames with me, I need to pull worklog entries of these users and manipulate it from JAVA client
Below are the jar files am using to connect JIRA api and fetch values
The code is pasted below
public class JiraConnector {
JiraRestClient jira;
public JiraConnector() throws URISyntaxException {
String url = prop().getUrl();
String userName = prop().getUser() ;
String password = prop().getpwd() ;
JerseyJiraRestClientFactory clientFactory = new JerseyJiraRestClientFactory();
jira = clientFactory.createWithBasicHttpAuthentication(new URI(url),
userName, password);
System.out.println("Connection established to >> " + url);
}
public void printIssueDetails(String jiraNumber) {
System.out.println("JiraNumber is " + jiraNumber);
Issue issue = jira.getIssueClient().getIssue(jiraNumber, null);
System.out.println(issue.getSummary());
System.out.println(issue.getDescription());
}
public void printUserWorkLog(String userName) {
System.out.println("user details invoked ... ");
User user = jira.getUserClient().getUser(userName, null);
System.out.println(user.getDisplayName());
System.out.println(user.getEmailAddress());
}
For any given username, am able to print his displayName and emailAdress (all those basic infos).
But I need to get the list of worklogs for the given user. Not sure how to proceed
You can find all worklog records for selected issue:
List<Worklog> worklogByIssue = ComponentAccessor.getWorklogManager().getByIssue(issue);
After that you can parse all worklog records to determine for what user this record created:
for (Worklog worklogByIssueItem : worklogByIssue)
{
int timeSpent = worklogByIssueItem.getTimeSpent().intValue();
String worklogAuthorName = worklogByIssueItem.getAuthorObject().getName();
...
}
And last task is search of issues by some params:
public static List<Issue> searchIssues(SearchParametersAggregator searchParams)
{
String jqlQuery = searchParams.getJqlQuery();
String projectId = searchParams.getProjectId();
String condition = createCondition(jqlQuery, projectId);
JqlQueryBuilder jqlQueryBuilder = prepareJqlQueryBuilder(condition);
return searchIssues(jqlQueryBuilder);
}
static List<Issue> searchIssues(JqlQueryBuilder jqlQueryBuilder)
{
Query query = jqlQueryBuilder.buildQuery();
SearchService searchService = ComponentAccessor.getComponent(SearchService.class);
try
{
ApplicationUser applicationUser = ComponentAccessor.getJiraAuthenticationContext().getUser();
User user = applicationUser.getDirectoryUser();
SearchResults searchResults = searchService.search(user, query, PagerFilter.getUnlimitedFilter());
List<Issue> issues = searchResults.getIssues();
return issues;
}
catch (SearchException e)
{
LOGGER.error("Error occurs during search of issues");
e.printStackTrace();
}
return new ArrayList<Issue>();
}
static JqlQueryBuilder prepareJqlQueryBuilder(String condition)
{
try
{
Query query = jqlQueryParser.parseQuery(condition);
JqlQueryBuilder builder = JqlQueryBuilder.newBuilder(query);
return builder;
}
catch (JqlParseException e)
{
throw new RuntimeException("JqlParseException during parsing jqlQuery!");
}
}