Create a Search Function¶
This section describes the search function based on an example application.
- Description of the function to be created
- Enter the search condition in the “Project Name(プロジェクト名)” field of the side menu and click the “Search(検索)” button.
- The search results by project name are displayed.
- Clear the project name and click on the “Start this year(今年開始)” link in the “Search by period(期間からさがす)” column.
- Projects with a project start date of this year are displayed.
Perform a search¶
The basic implementation method of the search function is described in the following order:
- Create a form
Create a form that accepts the search condition.
- ProjectSearchForm.java
public class ProjectSearchForm extends SearchFormBase implements Serializable { // Partial excerpt /** Project name */ @Domain("projectName") private String projectName; /** Project start date (FROM) */ @Domain("date") private String projectStartDateBegin; // Getter and setter are omitted
- Key points of this implementation
- All properties that accept input values should be declared as string type. For more information, see how to set validation rules.
- Create a JSP for the search condition input
Creates a JSP for the search condition input.
- /src/main/webapp/WEB-INF/view/common/sidemenu.jsp
<n:form method="GET" action="list"> <!-- Omitted --> <label for="projectName" class="control-label">Project name</label> <div> <n:text id="projectName" name="searchForm.projectName" size="25" maxlength="64" cssClass="form-control" errorCss="input-error form-control" placeholder="Project name"/> <n:error errorCss="message-error" name="searchForm.projectName" /> </div> <!-- Omitted --> <div align="center"> <input type="submit" id="search" class="btn btn-primary" value="Search" /> </div> </n:form>
- Key points of this implementation
- When sending a request by GET, specify GET in the method attribute of form tag. In the case of GET, custom tags cannot be used for buttons and links, so the buttons and links must be created in HTML. For more information, see Using GET request.
- Create a search condition bean
Creates a bean that sets the search conditions and hands over to Universal DAO. Bean property should be of the type that is compatible with the definition (type) of the corresponding condition column.
- ProjectSearchDto.java
public class ProjectSearchDto implements Serializable { // Partial excerpt /** Project name */ private String projectName; /** Project start date (FROM) */ private java.sql.Date projectStartDateBegin; // Getter and setter are omitted
- Key points of this implementation
- Use BeanUtil to transfer values from the form to search condition Bean. Since BeanUtil transfers items with the same property name, it is necessary to match the property names of the items used as search conditions in the form and search condition Bean.
- When values are transferred using BeanUtil the property can be transferred with a type conversion for properties that are compatible. For more information, see type conversion rules.
- Bean property is defined by Java type that matches the corresponding column type.
- Create a SQL for search
Create a SQL for searching.
- Project.sql
SEARCH_PROJECT = SELECT PROJECT_ID, PROJECT_NAME, PROJECT_TYPE, PROJECT_CLASS, PROJECT_START_DATE, PROJECT_END_DATE, VERSION FROM PROJECT WHERE USER_ID = :userId AND $if(clientId) {CLIENT_ID = :clientId} AND $if(projectName) {PROJECT_NAME LIKE :%projectName%} AND $if(projectType) {PROJECT_TYPE = :projectType} AND $if(projectClass) {PROJECT_CLASS IN (:projectClass[])} AND $if(projectStartDateBegin) {PROJECT_START_DATE >= :projectStartDateBegin} AND $if(projectStartDateEnd) {PROJECT_START_DATE <= :projectStartDateEnd} AND $if(projectEndDateBegin) {PROJECT_END_DATE >= :projectEndDateBegin} AND $if(projectEndDateEnd) {PROJECT_END_DATE <= :projectEndDateEnd} $sort(sortId){ (idAsc PROJECT_ID) (idDesc PROJECT_ID DESC) (nameAsc PROJECT_NAME, PROJECT_ID) (nameDesc PROJECT_NAME DESC, PROJECT_ID DESC) (startDateAsc PROJECT_START_DATE, PROJECT_ID) (startDateDesc PROJECT_START_DATE DESC, PROJECT_ID DESC) (endDateAsc PROJECT_END_DATE, PROJECT_ID) (endDateDesc PROJECT_END_DATE DESC, PROJECT_ID DESC) }
- Key points of this implementation
- To prevent SQL injection, SQL is written in an external file. For more information, see Manage SQL in files.
- Bind the value to SQL using the bean property name. For more information, see Execute SQL with Bean object as input.
- To include only the items specified on the search screen in the conditions, build a SQL statement using the $if syntax.
- To make the sort key selectable from the screen, use the $sort syntax to construct an SQL statement.
- Implementation of a business action
Implement a search process for a business action.
- Create a business action method
Create a method to search based on the search conditions given on the screen.
- ProjectAction.java
@InjectForm(form = ProjectSearchForm.class, prefix = "searchForm", name = "searchForm") @OnError(type = ApplicationException.class, path = "/WEB-INF/view/project/index.jsp") public HttpResponse list(HttpRequest request, ExecutionContext context) { ProjectSearchForm searchForm = context.getRequestScopedVar("searchForm"); ProjectSearchDto searchCondition = BeanUtil.createAndCopy(ProjectSearchDto.class, searchForm); List<Project> searchList = searchProject(searchCondition, context); context.setRequestScopedVar("searchResult", searchList); return new HttpResponse("/WEB-INF/view/project/index.jsp"); }
- Key points of this implementation
- The search condition is validated by adding InjectForm as the search condition is not guaranteed to be safe with input values from outside.
- Form validated by InjectForm can be acquired from the request scope.
- Copies the form value to the search condition bean using BeanUtil.
- Create a private method to perform a search
This method searches the database by specifying the SQL mentioned above.
- ProjectAction.java
private List<Project> searchProject(ProjectSearchDto searchCondition, ExecutionContext context) { LoginUserPrincipal userContext = SessionUtil.get(context, "userContext"); searchCondition.setUserId(userContext.getUserId()); return UniversalDao .page(searchCondition.getPageNumber()) .per(20L) .findAllBySqlFile(Project.class, "SEARCH_PROJECT", searchCondition); }
- Key points of this implementation
- To execute the preceding SQL statement, specify SQLID (or “SEARCH_PROJECT” in the case of the preceding SQL) as the second argument of UniversalDao#findAllBySqlFile.
- Search for paging can be performed using the UniversalDao#per method and UniversalDao#page. For more information, see narrow the search for paging.
- Create a search result display part
Implements the process to display the search results registered in the request scope on the screen in JSP.
- /src/main/webapp/WEB-INF/view/project/index.jsp
<!-- Search result --> <app:listSearchResult> <!-- Attribute value specification of app:listSearchResult is omitted --> <!-- Omitted --> <jsp:attribute name="headerRowFragment"> <tr> <th>Project ID</th> <th>Project name</th> <th>Project type</th> <th>Project start date</th> <th>Project end date</th> </tr> </jsp:attribute> <jsp:attribute name="bodyRowFragment"> <tr class="info"> <td> <!-- Create the URL to which the project ID was added --> <!-- Transition to the project detail screen --> <n:a href="show/${row.projectId}"> <n:write name="row.projectId"/> </n:a> </td> <!-- Omitted --> <td> <n:write name="row.projectName" /> </td> <!-- Omitted --> <td> <n:write name="row.projectStartDate" valueFormat="dateTime{yyyy/MM/dd}"/> </td> <!-- Omitted --> </tr> </jsp:attribute> </app:listSearchResult>
- Key points of this implementation
To include a parameter in the URL of the GET request, such as a link to the detail screen, create using <c:url> tag of JSTL or EL expression.
Since the routing is configured as follows in the Example application, a URL with a project ID at the end is associated with “ProjectAction#show”. For more information, see library README documentation (external site) .
- routes.xml
<routes> <match path="/action/:controller/:action/:projectId"> <requirements> <requirement name="projectId" value="\d+$" /> </requirements> </match> <!-- Other settings are omitted --> </routes>
The write tag is used to output the value. To output the value in a format such as “date” or “amount”, specify the format with the valueFormat attribute. For more information, see Output of values after formatting.
For information on how to use <app:listSearchResult>, see Display a List of Search Results.
This completes the description of the search function.