I'm learning RESTful webservices from javabrains website. Here there is a section named Comments and this is related to a message, But I'm unable to know How Can I link these both.
Below is my SQL Tables for Messages and comments.
Messages
Comments
Here Basically, both look pretty same(The table design), but the values differ. And I'm using the below method to send the data.
public Comment addComment(long messageId, Comment comment) throws Exception {
Properties properties = new Properties();
properties.load(getClass().getClassLoader().getResourceAsStream("/config.properties"));
String userName = properties.getProperty("user");
String password = properties.getProperty("pass");
String url = properties.getProperty("Sqldburl");
int key = 0;
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
Connection conn = DriverManager.getConnection(url, userName, password);
String query = "select count(*) from Comments";
PreparedStatement ps = conn.prepareStatement(query);
ResultSet rs = ps.executeQuery();
rs.next();
key = rs.getInt(1);
} catch (Exception e) {
System.out.println(e);
}
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
Connection conn = DriverManager.getConnection(url, userName, password);
String query = "insert into Comments(id, message, author) values(?,?,?)";
PreparedStatement ps = conn.prepareStatement(query);
ps.setInt(1, key);
ps.setString(2, comment.getMessage());
ps.setString(3, comment.getAuthor());
ps.executeQuery();
} catch (Exception e) {
System.out.println(e);
}
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
Connection conn = DriverManager.getConnection(url, userName, password);
String query = "select * from Comments where messageId=?";
PreparedStatement ps = conn.prepareStatement(query);
ps.setLong(1, messageId);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
comment.setAuthor(rs.getString("Author"));
comment.setId(rs.getInt("Id"));
comment.setMessage(rs.getString("message"));
}
} catch (Exception e) {
System.out.println(e + "b3");
}
return comment;
}
After writing this code, I've realized that Here I'm adding a comment for sure into Comments table, But it is no where linked to the Messages.
I know a way, that is I've create a new column in the Comments table and using join operation, I need to update the same messageId in comments table. But I want to know if there is a better way of getting this done, without using the concept of joins.
In MessageBean, there is a map declared as below.
private Map<Long, Comment> comments = new HashMap<>();
#XmlTransient
public Map<Long, Comment> getComments() {
return comments;
}
public void setComments(Map<Long, Comment> comments) {
this.comments = comments;
}
can I take any advantage of this to avoid join?
Related
I have many rpt files. I want to change the query for each report using C#. There are several ways to do this changes.
First way:
private void button_Test_Click(object sender, EventArgs e)
{
ReportDocument rptDoc = new ReportDocument();
rptDoc.Load("D:\\Temp_01\\Report1_Test.rpt");
rptDoc.SetDatabaseLogon("User", "Password", "ServName", "DBName");
CrystalDecisions.Shared.ConnectionInfo ConnInf;
ConnInf = rptDoc.Database.Tables[0].LogOnInfo.ConnectionInfo;
String strSQLQuery = "SELECT TOP(123) * FROM sys.all_objects";
String strTableName = rptDoc.Database.Tables[0].Name;
try
{
rptDoc.SetSQLCommandTable(ConnInf, strTableName, strSQLQuery);
rptDoc.VerifyDatabase();
}
catch (Exception ex) { rptDoc.Close(); }
rptDoc.SaveAs("D:\\Temp_02\\Report2_Test.rpt");
rptDoc.Close();
}
It is not the best way. The method SetSQLCommand does not work when the query has any parameters. Even if you set value for each parameter, SetSQLCommand does not work. The example with a parameter which does not work:
private void button_Test_Click(object sender, EventArgs e)
{
ReportDocument rptDoc = new ReportDocument();
rptDoc.Load("D:\\Temp_01\\Report1_Test.rpt");
rptDoc.SetDatabaseLogon("User", "Password", "ServName", "DBName");
CrystalDecisions.Shared.ConnectionInfo ConnInf;
ConnInf = rptDoc.Database.Tables[0].LogOnInfo.ConnectionInfo;
String strSQLQuery = "SELECT TOP(1) * FROM sys.all_objects WHERE name = {?strName}";
String strTableName = rptDoc.Database.Tables[0].Name;
try
{
rptDoc.SetParameterValue("strName", "Text");
rptDoc.SetSQLCommandTable(ConnInf, strTableName, strSQLQuery);
rptDoc.VerifyDatabase();
}
catch (Exception ex) { rptDoc.Close(); }
rptDoc.SaveAs("D:\\Temp_02\\Report2_Test.rpt");
rptDoc.Close();
}
It returns an error. This method does not work with parameters!
Second way:
private void button_Test_Click(object sender, EventArgs e)
{
ReportDocument rptDoc = new ReportDocument();
rptDoc.Load("D:\\Temp_01\\Report1_Test.rpt");
rptDoc.SetDatabaseLogon("User", "Password", "ServName", "DBName");
ISCDReportClientDocument rcd = null;
rcd = rptDoc.ReportClientDocument as ISCDReportClientDocument;
CommandTable rTblOld;
CommandTable rTblNew;
rTblOld = rcd.Database.Tables[0] as CommandTable;
rTblNew = rcd.Database.Tables[0].Clone(true) as CommandTable;
rTblNew.CommandText = "SELECT TOP(1) * FROM sys.all_objects";
try
{
rcd.DatabaseController.SetTableLocationEx(rTblOld, rTblNew);
rcd.VerifyDatabase();
}
catch (Exception ex) { rcd.Close(); }
rcd.SaveAs(rcd.DisplayName, "D:\\Temp_02\\", 1);
rcd.Close();
}
This is also not the best way. The method SetLocalTableEx does a struct of the report is bad. After run SetLocalTableEx, attribute ConnectionInf.UserId have value NULL also the Name of connection
After SetTableLocationEx:
rcd.DatabaseController.SetTableLocationEx(rTblOld, rTblNew);
String UserID;
UserID = rptDoc.Database.Tables[0].LogOnInfo.ConnectionInfo.UserID;
if (UserID == null) MessageBox.Show("UserID has NULL");
UserId has value NULL
Also, before run SetTableLocationEx, Connection Name is MSODBCSQL11
enter image description here
After run SetTableLocationEx, Connection Name is Command
enter image description here
So,
how do dynamic and correctly to change the query in CommandTable for Crystal Reports file?
Thanks,
Artem
You are using command in Crystal Report which is the best way when doing and displaying a data from database to crystal report but unfortunately you do it in Code Behind.
My Question is:
Why don't you do it in Command of Crystal Report itself?
see this link for more info.
I am trying to populate a ComboBox with a list that is populated by a SQL statement.
I tried this:
public void buildData(){
ObservableList<ComboBox> data = FXCollections.observableArrayList();
Connection conn = db.makeConnection();
try{
String SQL = "Select Feature from FeaturesTable Order By Feature";
ResultSet rs = conn.createStatement().executeQuery(SQL);
while(rs.next()){
ComboBox cb = new ComboBox();
cb.featureCombo.set(rs.getString("Feature"));
featureCombo.add(cb);
}
featureCombo.setItems(data);
}
catch(Exception e){
e.printStackTrace();
System.out.println("Error on Building Data");
}
}
I'm getting an error under cb.featureCombo.set of "featureCombo cannot be resolved or is not a field" but featureCombo exists as:
#FXML
private ObservableList<ComboBox> featureCombo;
and then another error under featureCombo.setItems(data); probably because of the same problem.
I'm not set on this method if someone has a better way to do this.
If you desire a ComboBox named featureCombo, you are going to have to declare it as a ComboBox and not as private ObservableList<ComboBox> featureCombo; which is making an ObservableList
Something like
#FXML
ComboBox<String> featureCombo;
Then in your method, you need to make a list of String to populate the ComboBox (you currently have a list of ComboBox)
public void buildData(){
ObservableList<String> data = FXCollections.observableArrayList(); //List of String
Connection conn = db.makeConnection();
try{
String SQL = "Select Feature from FeaturesTable Order By Feature";
ResultSet rs = conn.createStatement().executeQuery(SQL);
while(rs.next()){
data.add(rs.getString("Feature")); //add the String to the list
}
featureCombo.setItems(data); //Set the list of String as the data for your combo box
}
catch(Exception e){
e.printStackTrace();
System.out.println("Error on Building Data");
}
}
We are using java jdk 1.7.0_45, postgresql jdbc connector postgresql-9.3-1100.jdbc41.jar.
Here is a synopsis of our problem, as much as possible of code pasted below.
This code:
ResultSet rs = DbConn.getInstance().doQuery("Select d.deptId from Depts d");
while (rs.next()){
System.out.println(rs.getInt("d.deptId"));
Produces the error:
org.postgresql.util.PSQLException: The column name d.deptId was not found in this ResultSet.
This code:
ResultSet rs = DbConn.getInstance().doQuery("Select d.deptId from Depts d");
while (rs.next()){
System.out.println(rs.getInt("deptId"));
Produces no error.
Is there a way, besides removing the "d." from the first query, to make the first code snippet not throw the error message?
Here is the source code:
public class JoinTest {
#Test
public void test(){
boolean pass = false;
try {
ResultSet rs = DbConn.getInstance().doQuery("Select d.deptId from Depts d");
String label = rs.getMetaData().getColumnLabel(1); // What do you get?
System.out.println("label = " + label);
while (rs.next()){
System.out.println(rs.getInt("d.deptId"));
pass = true;
}
} catch (SQLException e) {
e.printStackTrace();
pass=false;
}
assertTrue(pass);
}
#Test
public void test2(){
boolean pass = false;
try {
ResultSet rs = DbConn.getInstance().doQuery("Select d.deptId from Depts d");
while (rs.next()){
System.out.println(rs.getInt("deptId"));
pass = true;
}
} catch (SQLException e) {
e.printStackTrace();
pass=false;
}
assertTrue(pass);
}
}
public class DbConn {
private static String url = "jdbc:postgresql://server:port/schema";
private static Properties props = new Properties(); {
props.setProperty("user","userid");
props.setProperty("password","passwprd");
}
private Connection conn;
private DbConn(){}
private static DbConn instance;
public static DbConn getInstance() throws SQLException{
if (instance == null){
instance = new DbConn();
instance.conn = DriverManager.getConnection(url, props);
}
return instance;
}
public ResultSet doQuery(String query) throws SQLException{
Logger.log("DbConn.doQuery: " + query);
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(query);
return rs;
}
}
}
The query:
select d.deptId from Depts d
produces a single-column resultset with the result-alias "deptId". There is no "d.deptId" column. If you want one, you can request that as the column alias instead:
select d.deptId AS "d.deptId" from Depts d
PgJDBC can't do anything about this because it has no idea that the resultset column "deptId" is related to the "d.deptId" in the select-list. Teaching it about that would force it to understand way more about the SQL it processes than would be desirable, and lead to maintenance and performance challenges.
The second one works - why isn't that acceptable?
You can also do this:
System.out.println(rs.getInt(1));
If you change the query you have to change the code, too.
I have a problem. When I try to use the "Select distinct" in HSQLDB, the stream of results returns me all rows instead of me returning only distinct rows.
I've tried the following syntax:
SELECT DISTINCT FROM ratings UserID order by UserID;
SELECT DISTINCT (UserID) FROM ratings order by UserID;
SELECT DISTINCT UserID FROM ratings;
SELECT DISTINCT (UserID) FROM ratings;
None of them works. What is the problem?
If anyone able to help me I appreciate.
Thank you.
The function code where I perform the action is as follows:
private void readUserFile(String filename) {
try {
//Verify if file users exists
boolean exists = (new File(filename)).exists();
if (!exists) {
//If file users not exists create one, bases on distinct users that exist in ratings table
ResultSet rsUsers = jdbcTemplate.getDataSource().getConnection().createStatement().executeQuery("SELECT DISTINCT UserID FROM ratings order by UserID;");
List<String> users = new ArrayList<String>();
while (rsUsers.next()) {
users.add(String.valueOf(rsUsers.getInt(1)));
}
rsUsers.close();
//Create and write to file
BufferedWriter f = null;
f = new BufferedWriter(new FileWriter(filename));
for (String user : users) {
f.write(user);
f.newLine();
}
f.close();
}
PreparedStatement prstInsert = con.prepareStatement("INSERT INTO users VALUES (?)");
BufferedReader in = new BufferedReader(new FileReader(filename));
int i = 0;
while (true) {
String s = in.readLine();
if (s == null) { // end of file
log.info("Total imported users: " + i);
break;
}
i++;
int userid = Integer.parseInt(s);
prstInsert.setInt(1, userid);
if (i != 0 && Math.round((double) i / 100) == ((double) i / 100)) {
log.info("Imported users: " + i);
}
prstInsert.executeUpdate();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
I am begginer with ADO.NET , I try update table with DataSet.
O client side I have dataset with one table. I send this dataset on service side (it is ASP.NET Web Service).
On Service side I try update table in database, but it dont 't work.
public bool Update(DataSet ds)
{
SqlConnection conn = null;
SqlDataAdapter da = null;
SqlCommand cmd = null;
try
{
string sql = "UPDATE * FROM Tab1";
string connStr = WebConfigurationManager.ConnectionStrings["Employees"].ConnectionString;
conn = new SqlConnection(connStr);
conn.Open();
cmd=new SqlCommand(sql,conn);
da = new SqlDataAdapter(sql, conn);
da.UpdateCommand = cmd;
da.Update(ds.Tables[0]);
return true;
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (conn != null)
conn.Close();
if (da != null)
da.Dispose();
}
}
Where can be problem?
It is better to look how really ADO.Net dataset works.
http://support.microsoft.com/kb/308507