java - 在 Vaadin 网格中显示来自 SQL 的数据

标签 java spring-boot vaadin vaadin-grid

我试图在网格中显示 SQL 表数据,但似乎没有任何效果。你能指出我错在哪里吗?

我在互联网上找到了很多方法,但没有一个对我有用。希望您能找到问题并帮助我。

我正在使用:带有 Spring boot 的 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 将为 null,这就是 updateGrid 抛出 NullPointerException 的原因。

此外,作为旁注,请从成员字段中删除 @Autowired 注释。您混合两种不同的 Autowiring 方式,一种是 Autowiring 字段

@Autowired
private CustomerService service;

public MainView() { ... }

在这种情况下,Spring 将自动为您设置该值,并且它不会作为参数传递给构造函数。但是,Spring 在构造函数之后设置它,因此您不能在构造函数或从构造函数调用的任何方法中使用它。

另一种方法是构造函数 Autowiring ,这是您应该做的。在这种情况下,Spring 将 bean 传递给构造函数,但如果需要,您需要自己设置成员字段。

private CustomerService service;

@Autowired
public MainView(CustomerService service) {
    this.service = service;
    ...
}

您并不严格需要在构造函数之前使用 @Autowired 注释,没有它它也可以工作,但如果您愿意,可以将它放在那里以保持清晰。

关于java - 在 Vaadin 网格中显示来自 SQL 的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58144026/

相关文章:

java - GWT - 从小部件获取按钮的 "addClickHandler"

vaadin - Vaadin 的列表/中继器组件

java - 调整大小时 JDesktopPane 的内容消失 - Java Swing

java - Android 自定义 ListView

java - Spring Boot 401身份验证错误的日志用户名/密码

java - Spring Boot 中 Rest Api 的计数器指标

spring-boot - 如何将 @Transcational 与 spring-data-cosmosdb 一起使用?

java - "Can' 注销时将节点从一个状态树移动到另一个状态树

java - 如何使用 Vaadin 8.1 在树形网格中设置多个级别?

java - 处理 Tapestry 布局中的事件