在 Vaadin 网格中显示来自 SQL 的数据
Show data from SQL in Vaadin Grid
我试图在我的网格中显示我的 SQL table 数据,但似乎没有任何效果。你能指出我错在哪里吗?
我在互联网上找到了很多方法,但 none 对我有用。希望你能找到问题并帮助我。
我正在使用:带有 Spring 引导的 Vaadin 14
CustomerService.java
@Component
public class CustomerService {
@Autowired
private JdbcTemplate jdbcTemplate;
public List<Customer> findAll() {
return jdbcTemplate.query(
"SELECT ID, FirstName, LastName FROM customer",
(rs, rowNum) -> new Customer(rs.getLong("id"),
rs.getString("First Name"), rs.getString("Last Name")));
}
public void update(Customer customer) {
jdbcTemplate.update("INSERT INTO customer (FirstName,LastName) VALUES(?,?)",customer.getFirstName(),customer.getLastName());
}
}
MainView.Java
public class MainView extends VerticalLayout {
@Autowired
private CustomerService service ;
public Customer customer = new Customer();
private Binder<Customer> binder = new Binder<>(Customer.class);
private TextField firstName = new TextField("First name");
private TextField lastName = new TextField("Last name");
private Grid<Customer> grid = new Grid(Customer.class);
private Button save = new Button("Save", e -> {
try {
binder.writeBean(customer);
saveCustomer();
binder.readBean(new Customer());
} catch (ValidationException ex) {
ex.printStackTrace();
}
});
public MainView(CustomerService service) {
add(
new H1("הוסף לקוח"),
buildForm(),
grid
);
updateGrid(); // update the grid with the sql data
setSizeFull();
}
private void saveCustomer() throws ValidationException {
service.update(customer);
}
private Component buildForm() {
// TextField id = new TextField("ID");
TextField firstName = new TextField("First name");
TextField lastName = new TextField("Last name");
Div errorsLayout = new Div();
binder.forField(firstName)
.bind(
Customer::getFirstName,Customer::setFirstName
);
binder.forField(lastName)
.bind(
Customer::getLastName,Customer::setLastName
);
Button reload = new Button("reload", e ->{
try{
binder.readBean(customer);
} catch (Exception ex) {
ex.printStackTrace();
}
});
// Configure UI components
save.setThemeName("primary");
// Wrap components in layouts
HorizontalLayout formLayout = new HorizontalLayout(grid,firstName,lastName,save,reload);
Div wrapperLayout = new Div(formLayout, errorsLayout);
formLayout.setDefaultVerticalComponentAlignment(Alignment.BASELINE);
wrapperLayout.setWidth("100%");
grid.setColumnReorderingAllowed(true);
return wrapperLayout;
}
private void updateGrid() {
List<Customer> customers = service.findAll();
grid.setItems(customers);
}
我得到的错误:
There was an exception while trying to navigate to '' with the exception message 'Error creating bean with name 'com.packagename.myapp.spring.MainView': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.packagename.myapp.spring.MainView]: Constructor threw exception; nested exception is java.lang.NullPointerException'
您永远不会设置 CustomerService
字段。添加
this.service = service;
到构造函数的开头。否则成员字段 private CustomerService service
将为空,这就是 updateGrid
抛出 NullPointerException
.
的原因
此外,作为旁注,从成员字段中删除 @Autowired
注释。您混合了两种不同的自动装配方式,一种是自动装配字段
@Autowired
private CustomerService service;
public MainView() { ... }
在这种情况下,Spring 会自动为您设置值,并且不会作为参数传递给构造函数。但是,Spring 将它设置在构造函数之后,因此您不能在构造函数中或从构造函数调用的任何方法中使用它。
另一种方法是构造函数自动装配,这是你应该做的。在这种情况下 Spring 将 bean 传递给构造函数,但如果需要,您需要自己设置成员字段。
private CustomerService service;
@Autowired
public MainView(CustomerService service) {
this.service = service;
...
}
构造函数前不需要 @Autowired
批注,没有它也能正常工作,但如果需要,为了清楚起见,可以将它放在那里。
我试图在我的网格中显示我的 SQL table 数据,但似乎没有任何效果。你能指出我错在哪里吗?
我在互联网上找到了很多方法,但 none 对我有用。希望你能找到问题并帮助我。
我正在使用:带有 Spring 引导的 Vaadin 14
CustomerService.java
@Component
public class CustomerService {
@Autowired
private JdbcTemplate jdbcTemplate;
public List<Customer> findAll() {
return jdbcTemplate.query(
"SELECT ID, FirstName, LastName FROM customer",
(rs, rowNum) -> new Customer(rs.getLong("id"),
rs.getString("First Name"), rs.getString("Last Name")));
}
public void update(Customer customer) {
jdbcTemplate.update("INSERT INTO customer (FirstName,LastName) VALUES(?,?)",customer.getFirstName(),customer.getLastName());
}
}
MainView.Java
public class MainView extends VerticalLayout {
@Autowired
private CustomerService service ;
public Customer customer = new Customer();
private Binder<Customer> binder = new Binder<>(Customer.class);
private TextField firstName = new TextField("First name");
private TextField lastName = new TextField("Last name");
private Grid<Customer> grid = new Grid(Customer.class);
private Button save = new Button("Save", e -> {
try {
binder.writeBean(customer);
saveCustomer();
binder.readBean(new Customer());
} catch (ValidationException ex) {
ex.printStackTrace();
}
});
public MainView(CustomerService service) {
add(
new H1("הוסף לקוח"),
buildForm(),
grid
);
updateGrid(); // update the grid with the sql data
setSizeFull();
}
private void saveCustomer() throws ValidationException {
service.update(customer);
}
private Component buildForm() {
// TextField id = new TextField("ID");
TextField firstName = new TextField("First name");
TextField lastName = new TextField("Last name");
Div errorsLayout = new Div();
binder.forField(firstName)
.bind(
Customer::getFirstName,Customer::setFirstName
);
binder.forField(lastName)
.bind(
Customer::getLastName,Customer::setLastName
);
Button reload = new Button("reload", e ->{
try{
binder.readBean(customer);
} catch (Exception ex) {
ex.printStackTrace();
}
});
// Configure UI components
save.setThemeName("primary");
// Wrap components in layouts
HorizontalLayout formLayout = new HorizontalLayout(grid,firstName,lastName,save,reload);
Div wrapperLayout = new Div(formLayout, errorsLayout);
formLayout.setDefaultVerticalComponentAlignment(Alignment.BASELINE);
wrapperLayout.setWidth("100%");
grid.setColumnReorderingAllowed(true);
return wrapperLayout;
}
private void updateGrid() {
List<Customer> customers = service.findAll();
grid.setItems(customers);
}
我得到的错误:
There was an exception while trying to navigate to '' with the exception message 'Error creating bean with name 'com.packagename.myapp.spring.MainView': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.packagename.myapp.spring.MainView]: Constructor threw exception; nested exception is java.lang.NullPointerException'
您永远不会设置 CustomerService
字段。添加
this.service = service;
到构造函数的开头。否则成员字段 private CustomerService service
将为空,这就是 updateGrid
抛出 NullPointerException
.
此外,作为旁注,从成员字段中删除 @Autowired
注释。您混合了两种不同的自动装配方式,一种是自动装配字段
@Autowired
private CustomerService service;
public MainView() { ... }
在这种情况下,Spring 会自动为您设置值,并且不会作为参数传递给构造函数。但是,Spring 将它设置在构造函数之后,因此您不能在构造函数中或从构造函数调用的任何方法中使用它。
另一种方法是构造函数自动装配,这是你应该做的。在这种情况下 Spring 将 bean 传递给构造函数,但如果需要,您需要自己设置成员字段。
private CustomerService service;
@Autowired
public MainView(CustomerService service) {
this.service = service;
...
}
构造函数前不需要 @Autowired
批注,没有它也能正常工作,但如果需要,为了清楚起见,可以将它放在那里。