从CDI bean

时间:2015-11-20 17:19:36

标签: jsf jpa primefaces

Primefaces 5.3 glassfish 4.1

以下是我的实体管理

@Stateless
public class ManagerTask {

@PersistenceContext(unitName="task")
private EntityManager em;

ManagerTask(){} 

public List<Task> findAllTask() {

    TypedQuery<Task> q =  em.createNamedQuery("Task.findAll",Task.class);
    List<Task> taskList = q.getResultList();

    return taskList;

}   

现在在我的CDI bean中我想调用findAllTask​​()方法获取taks列表然后在我的jsf中使用它来创建数据表

方法1:

CDI Bean

@Named(value="bt") 
@ViewScoped 
public class BeanTask {
@SuppressWarnings("unused")
private static final long serialVersionUID = 1L; 


private ManagerTask mt;

private List<Task> tl;
private List<Task> filteredtl;
private ArrayList<SelectItem> regions;

public BeanTask() {
    // TODO Auto-generated constructor stub

}

@Inject
public BeanTask(ManagerTask mt) {
    this.mt=mt;
    tl=mt.findAllTask();
}

JSF

<p:dataTable id="tb1" var="tk" value="#{bt.tl}"
            rowIndexVar="rowindex" styleClass="fixed-size" 
            filteredValue="#{bt.filteredtl}"
            >

这是我以前使用的方法,但我意识到构造函数被多次调用,导致执行多个重复查询,并且正如一个成员在这里提出的一个不同的问题所示,没有业务逻辑应该进入构造函数一个cdi bean我转移到方法2

方法2:

CDI Bean

@Inject
private ManagerTask mt;

private List<Task> tl;
private List<Task> filteredtl;
private ArrayList<SelectItem> regions;

public BeanTask() {
    // TODO Auto-generated constructor stub

}


public List<Task> getalltasks() {
    tl=mt.findAllTask();  




    return tl; 
}

JSF

<p:dataTable id="tb1" var="tk" value="#{bt.getalltasks()}"
            rowIndexVar="rowindex" styleClass="fixed-size" 
            filteredValue="#{bt.filteredtl}"
            >

我认为第二种方法可能是正确的方法,但我遇到的问题是,如果我尝试排序数据表的列,它不适用于第二种方法,我从其他问题中发现这里是因为该方法每次都在查询数据库,而不是使用存储的值linked here。方法1排序工作。

有一种完全不同的方式我应该这样做或我错过了什么

1 个答案:

答案 0 :(得分:0)

我无法通过您发布的示例代码获得完整的想法,但即便如此,我还是为您提供了使用列过滤功能的示例。

<强>服务

@Stateless
public class TaskManager {

    @PersistenceContext(unitName = "task")
    private EntityManager em;

    public List<Task> findAll() {
        return em.createNamedQuery("Task.findAll", Task.class).getResultList();
    }   

    public void save(Task task) {
        em.persist(task);
    }
}

<强>控制器

一个简单的控制器,为PrimeFaces的dataTables设置了适当的过滤器。 每当发生会改变数据库状态的事件(如保存,更新或删除)时,只需从数据库重新加载数据。为此,我喜欢使用单独的方法,例如下面的reset()方法。

@Named
@ViewScoped 
public class TaskBean {

    private static final long serialVersionUID = 1L; 

    @Inject
    private TaskManager taskManager;

    // Filtered entity list
    private List<Task> filteredTasks;

    // Main entity list
    private List<Task> tasks;

    // Main entity
    private Task task;

    @PostConstruct
    public void init() {
        reset();
    }

    private void reset() {
        tasks = taskManager.findAll();
    }

    public void create() {
         task = new Task();
    }

    public void save() {
        taskManager.save(task);
        reset(); 
    }

    public Task getTask() {
        return task;
    }

    public List<Task> getTasks() {
        return tasks;
    }

    public List<Task> getFilteredTasks() {
         return filteredTasks;
    }   

    public void setFilteredTasks(List<Task> filteredTasks) {
        this.filteredTasks = filteredTasks;
    }   
}

查看

一个简单的表单示例

请注意,它会在保存事件后更新taskDataTable

<h:form id="taskForm" prependId="false">
    <p:inputText id="taskFormName" label="Name" value="#{taskBean.task.name}" />
    <!-- more fields here ... -->
    <p:commandButton id="taskFormSave" actionListener="#{taskBean.save}" value="Save" update="taskDataTable" />
</h:form>

带有列过滤的dataTable

<p:dataTable id="taskDataTable" value="#{taskBean.tasks}" filteredValue="#{taskBean.filteredTasks}" var="row">
    <p:column headerText="Name" filterBy="#{row.name}" filterMatchMode="contains">
        <h:outputText value="#{row.name}" />
    </p:column>
    <!-- more columns here ... -->
</p:dataTable>