我正在尝试在数据库中进行的查询中使用一个线程,该查询可以生成许多记录,我不知道是否有必要,但是当我尝试实现该线程时,它不返回该列表中的值(没有线程,它通常返回值)
我的控制器:在这里,我调用我的方法,该方法将具有我的DAO类数据库的以下列表:
public ObservableList<Requisicao> atualizarTabela() {
RequisicaoDAO dao = new RequisicaoDAO();
requisicoes = FXCollections.observableArrayList(dao.getList());
return requisicoes;
}
我的方法DAO:
public class RequisicaoDAO {
private Connection con;
Alerts alerts = new Alerts();
public RequisicaoDAO() {
this.con = new ConnectionFactory().getConnection();
}
private static RequisicaoDAO aRequisicaoDAO;
public static RequisicaoDAO getInstancia() {
if (aRequisicaoDAO == null) {
aRequisicaoDAO = new RequisicaoDAO();
}
return aRequisicaoDAO;
}
public List<Requisicao> getList() {
List<Requisicao> requisicoes = new ArrayList<>();
new Thread() {
@Override
public void run() {
String sql = "SELECT * FROM equipamento_requisicao equipreq INNER JOIN equipamento_user equipuser ON (equipreq.idequipamento_user = equipuser.id_equipamento_do_usuario) INNER JOIN usuario user ON (user.id_usuario=equipuser.idusuario) INNER JOIN equipamentos equip ON (equip.id_equipamentos = equipuser.idequipamentos) INNER JOIN detalhe_status dStatus ON (dStatus.idequipamento_requisicao= equipreq.id_equipamento_requisicao) INNER JOIN status_requisicao statusreq on (statusreq.id_status= dStatus.idstatus) INNER JOIN permissao p ON(user.idpermissao= p.id_permissao) INNER JOIN departamentos dp ON(user.iddepartamento = dp.id_departamentos) INNER JOIN chefe_departamento cp ON(dp.id_chefe = cp.id_chefe) where statusreq.categoria='Ativa' ";
try {
PreparedStatement stmt = con.prepareStatement(sql);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
Usuario usuario = new Usuario();
usuario.setNome(rs.getString("user.nome"));
usuario.setId(rs.getLong("user.id_usuario"));
usuario.setMatricula(rs.getString("user.matricula"));
// FIM TABELA USUARIO
//equipamento // equipamento user tabelas
Equipamentos equipamento = new Equipamentos();
equipamento.setEquipamento_nome(rs.getString("equip.equipamento_nome"));
equipamento.setSerial_equipamento(rs.getString("equipuser.serial_equipamento"));
equipamento.setId_equipamento_do_Usuario(rs.getLong("equipreq.idequipamento_user"));
//status tabela
Status status = new Status();
status.setCategoria(rs.getString("statusreq.categoria"));
status.setIdstatus(rs.getInt("statusreq.id_status"));
//status detalhes tabela
Usuario usuarioStatus = new Usuario();//id do usuaro na tabela detalhes status
usuarioStatus.setId(rs.getLong("dStatus.idusuario"));
StatusDetalhes statusDetalhes = new StatusDetalhes();
statusDetalhes.setId_statusdetalhes(rs.getLong("dStatus.id_statusdetalhes"));
statusDetalhes.setData_status(rs.getTimestamp("dStatus.data"));
statusDetalhes.setObservacao_status(rs.getString("dStatus.observacao"));
statusDetalhes.setIdUsuario(usuarioStatus);
statusDetalhes.setIdStatus(status);
// Id da requisicao na tabela detalhes status
Requisicao requisicaoStatus = new Requisicao();
requisicaoStatus.setId(rs.getLong("dStatus.idequipamento_requisicao"));
//requisicao tabela
Requisicao req = new Requisicao();
req.setId(rs.getLong("equipreq.id_equipamento_requisicao"));
req.setNome(rs.getString("equipreq.nome"));
req.setData_criada(rs.getTimestamp("equipreq.data_requisicao"));
req.setMotivo(rs.getString("equipreq.observacao"));
req.setReqEquipamento(equipamento);
req.setReqStatus(status);
req.setReqUsuario(usuario);
req.setReqStatus_Detalhes(statusDetalhes);
requisicoes.add(req);
}
stmt.close();
rs.close();
} catch (SQLException ex) {
Logger.getLogger(RequisicaoDAO.class.getName()).log(Level.SEVERE, null, ex);
}
}
}.start();
return requisicoes;
}
}
不会产生任何错误,但是我的表视图中没有显示此列表
我认为问题出在退货单上。但是我解决不了。
最佳答案
问题是,在线程添加任何内容之前,您要返回requisicoes
的值。
因为Thread是异步执行的,所以执行看起来像这样:
因此,查询工作正常(当不使用线程时,您会看到正确的结果),但是由于将(空)列表已复制到新的可观察列表,因此添加了结果,因此将它们添加到列表中较晚。不再影响控制器中的可观察列表。
一种解决方案是在返回列表requisicoes
之前等待线程的执行(通过调用线程的join method。但这会导致方法getList()
花费很多时间(因为它正在等待线程),这可能是您想通过使用线程避免的。
另一个(可能更好)的解决方案是从方法getList()
中删除多线程,并使用Task将多线程添加到您的控制器中。
解决方案如下所示:
public ObservableList<Requisicao> atualizarTabela() {
RequisicaoDAO dao = new RequisicaoDAO();
//create an empty list first
requisicoes = FXCollections.observableArrayList();
//execute the query in the task
Task<List<Requisicao>> task = new Task<List<Requisicao>>() {
@Override
protected List<Requisicao> call() throws Exception {
//getList has no thread anymore
return dao.getList();
}
};
//add the list values to the observable list, when the task succeeds
task.setOnSucceeded(e -> requisicoes.addAll(task.getValue()));
task.setOnFailed(e -> System.out.println("Task failed"));//better do some execption handling here...
//start the task in a new thread
Thread executor = new Thread(task, "get_list_task_thread");
executor.start();
//return the (empty) list, which will be filled when the task (that includes the query) has finished
return requisicoes;
}
如果您以这种方式更改代码(并从方法
getList()
中删除线程,则它应该首先返回一个空的ObservableList
,该空值在任务(包括查询)完成后显示并填充。即,它不会在执行查询时停止FX-Thread的执行,因此UI不会停止。关于java - 在具有数据库数据的列表中使用线程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57033066/