问题
I'm developing an app for DB querying, using Spring Boot and JDBCTemplates.
The problem is this: if I have to ask the db on a single table, I have no problems. But, if I have a join, how can I perform this task?
More specifically, the SQL commands to create tables are these:
CREATE TABLE firewall_items
(
id INT NOT NULL AUTO_INCREMENT,
firewall_id INT NOT NULL,
date DATE,
src VARCHAR(15),
src_port INT,
dst VARCHAR(15),
dst_port INT,
protocol VARCHAR(4),
PRIMARY KEY(id)
);
CREATE TABLE firewalls (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
ip VARCHAR(15) NOT NULL,
info TEXT,
PRIMARY KEY(id)
);
The correspondings java class are these:
import java.util.Date;
public class FirewallItems
{
private Date date;
private String id;
private String protocol;
private String src;
private String dst;
private String src_port;
private String dst_port;
private String firewall_id;
public FirewallItems() {}
public FirewallItems(Date data, String identificativo, String protocollo, String sorgente, String destinazione,
String porta_sorgente, String porta_destinazione, String firewall_id)
{
super();
this.date = data;
this.id = identificativo;
this.protocol = protocollo;
this.src = sorgente;
this.dst = destinazione;
this.src_port = porta_sorgente;
this.dst_port = porta_destinazione;
this.firewall_id = firewall_id;
}
/**
* Return the date of the report
* @return date
*/
public Date getDate()
{
return date;
}
/**
* Set the date of the report
* @param date the report's date
*/
public void setDate(Date date)
{
this.date = date;
}
/**
* Return the id of the report
* @return id
*/
public String getId()
{
return id;
}
/**
* Set the id of the report
* @param id the report's id
*/
public void setId(String id)
{
this.id = id;
}
/**
* Return the protocol cecked by report
* @return protocol
*/
public String getProtocol()
{
return protocol;
}
/**
* Set the protocol cecked by report
* @param protocol
*/
public void setProtocol(String protocol)
{
this.protocol = protocol;
}
/**
* Return the source of firewall's drop
* @return Src
*/
public String getSrc()
{
return src;
}
/**
* Set the source of firewall's drop
* @param src the firewall's source drop
*/
public void setSrc(String src)
{
this.src = src;
}
/**
* Return the firewall's destionation drop
* @return dst
*/
public String getDst()
{
return dst;
}
/**
* Set the firewall's destination drop
* @param dst the firewall's destination drop
*/
public void setDst(String dst)
{
this.dst = dst;
}
/**
* Return the source's port
* @return src_port
*/
public String getSrc_port()
{
return src_port;
}
/**
* Set the source's port
* @param src_port the source's port
*/
public void setSrc_port(String src_port)
{
this.src_port = src_port;
}
/**
* Return the destination's port
* @return dst_port
*/
public String getDst_port()
{
return dst_port;
}
/**
* Set the destination's port
* @param dst_port the destination's port
*/
public void setDst_port(String dst_port)
{
this.dst_port = dst_port;
}
/**
* Return the id of firewall associated to report
* @return firewall_id
*/
public String getFirewall_id()
{
return firewall_id;
}
/**
* Set the id of firewall associated to report
* @param firewall_id the id of firewall associated to report
*/
public void setFirewall_id(String firewall_id)
{
this.firewall_id = firewall_id;
}
}
public class Firewall
{
private String id;
private String ip;
private String info;
private String name;
/**
* Empty constructor, which instantiates a Firewall specimen without setting default values
*/
public Firewall() {}
/**
* Constructor instantiating a Firewall specimen specifying its initial values
*
* @param id the firewall's id code
* @param ip the firewall's ip code
* @param info the info about firewall
* @param name firewall's name
*/
public Firewall(String id, String ip, String info, String nome)
{
super();
this.id = id;
this.ip = ip;
this.info = info;
this.name = nome;
}
/**
* Return the firewall's id
* @return id
*/
public String getId()
{
return id;
}
/**
* Set firewall's id
* @param id the firewall's id
*/
public void setId(String id)
{
this.id = id;
}
/**
* Return the firewall's ip
* @return ip
*/
public String getIp()
{
return ip;
}
/**
* Set firewall's ip
* @param ip the firewall's ip
*/
public void setIp(String ip)
{
this.ip = ip;
}
/**
* Return firewall's info
* @return info
*/
public String getInfo()
{
return info;
}
/**
* Set firewall's info
* @param info firewall's info fields
*/
public void setInfo(String info)
{
this.info = info;
}
/**
* Return firewall's name
* @return name
*/
public String getName()
{
return name;
}
/**
* Set firewall's name
* @param name firewall's name
*/
public void setName(String name)
{
this.name = name;
}
}
The constraint is that firewall_Items.firewall_id = firewall.id (so, these are the variables that i must use to perform join).
Now, if i want perform this query:
SELECT info, src
FROM firewalls, firewall_items
WHERE firewall_items.firewall_id = firewalls.id;
How my java code must be, using jdbctemplate? Should i add to firewall class a collection to collect object of FirewallsItems, like an ArrayList?
Note1: i must use jdbctemplate project specifications. I can't use Hibernate or other instruments.
Note2: I know what rowmapper and resultset are, i regolary use them with query on a single table. What i nedd is to understand how to use them for a query with join, like that of the example.
Thanks a lot in advance for response!
回答1:
you should use the JOIN keyword to join your tables before you query them. Like so:
String query= "SELECT firewall_items.src, firewalls.info
FROM firewall_items
JOIN firewalls
ON firewall_items.firewalls_id = firewalls.id"
List<Item> items = jdbcTemplate.query(
query,
new MapSqlParameterSource(),
new FirewallInfoRowMapper()
);
Where Item is your retrieved object. You decide what that is.
Look at this article for more info
EDIT:
In response to your further inquiry. Above is the amended usage of jdbcTemplate, below you can find the classes you need. This requires you to have Spring. I've assumed that if you're using jdbcTemplate you already have Spring.
Below is a cheat sheet, but please look at this site and learn more about querying databases with java Spring and jdbcTemplates.
The correct implementation for a row mapper is like so :
public class FirewallInfoRowMapper implements RowMapper<FirewallInfo>{
@Override
public FirewallInfo mapRow(ResultSet rs, int rowNum) throws SQLException{
return new FirewallInfo(rs.getString("src"), rs.getString("info"))
}
}
public class FirewallInfo{
private String src;
private String info;
public FirewallInfo(String src, String info){
this.src = src;
this.info = info;
}
{}<<< Getters and Setters Here
}
回答2:
I know its late. There aren't a lot of good tutorial out there so incase someone else needs to know how to execute join query with spring and jdbc template. This is the way I did mine. First ensure to import the following jars in your dao class like so
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
Then in your FirewallDao class, do something like
public List<Firewall> getData(){
return template.query("SELECT firewalls.info, firewall_items.src FROM firewalls INNER JOIN firewall_items ON firewall_items.firewall_id = firewalls.id",new RowMapper<Firewall>(){
public Firewall mapRow(ResultSet rs, int row) throws SQLException {
Firewall f =new Firewall();
f.setInfo(rs.getString(1));
f.setSrc(rs.getString(2));
return f;
}
});
}
In you controller, something like
@Autowired
FirewallDao dao;
@RequestMapping("/viewinfo")
public ModelAndView viewinfo(){
List<Firewall> list=dao.getData();
return new ModelAndView("viewinfo","list",list);
}
in ur view, do something like
<table border="2" width="70%" cellpadding="2">
<tr><th>Info</th><th>Src</th></th><th>Edit</th></tr>
<c:forEach var="f" items="${list}">
<tr>
<td>${f.info}</td>
<td>${f.src}</td>
</tr>
</c:forEach>
</table>
来源:https://stackoverflow.com/questions/43636833/spring-jdbctemplates-execute-a-query-with-join