目標:掌握Query介面的使用主要內容包括:u 查詢所有資訊u 使用Query完成分頁u 根據條件查詢u 相關介面方法介紹
1、查詢所有資訊在第一講中查詢所有資訊的代碼如下:List<Userinfo> list = em.createQuery("select u from Userinfo u").getResultList();相當於下面的兩行代碼:Query q = em.createQuery("select u from Userinfo u");List<Userinfo> list =q.getResultList();查詢語句“select u from Userinfo u”不是標準的SQL語句,其中Userinfo是實體類的名字,u相當於對象。查詢的結果是封裝後的對象。這與以前的JDBC是不同的,SQL語句查詢的結果是ResultSet。如果查詢結果是多個,應該使用Query介面的getResultList方法,如果查詢結果只有一個,可以使用Query介面的getSingleResult方法。這種方式的查詢直接在參數中寫查詢語句,還可以把查詢語句單獨寫出來,然後調用。這種方式稱為命名查詢,例如使用命名查詢上面的語句可以寫成下面的樣子:@NamedQuery(name = "findAllUser", query = "SELECT u FROM Userinfo u")name表示該查詢的名字,query是查詢語句本身。命名查詢可以寫在實體類中,第一次課產生的實體類中就有多個命名查詢。對於命名查詢可以使用EntityManager的createNamedQuery方法,要訪問上面的查詢可以使用下面的代碼:Query q = em.createNamedQuery("findAllUser");List<Userinfo> list =q.getResultList();createNamedQuery方法的參數命名查詢的名字。
實驗:把第一次課中的查詢修改成命名查詢。
參考過程:1)修改Userinfo實體類中的如下代碼(紅色部分是新添加的):@NamedQueries( { @NamedQuery(name = "Userinfo.findByUserid", query = "SELECT u FROM Userinfo u WHERE u.userid = :userid"), @NamedQuery(name = "Userinfo.findByUsername", query = "SELECT u FROM Userinfo u WHERE u.username = :username"), @NamedQuery(name = "Userinfo.findByUserpass", query = "SELECT u FROM Userinfo u WHERE u.userpass = :userpass"), @NamedQuery(name = "Userinfo.findByUsertype", query = "SELECT u FROM Userinfo u WHERE u.usertype = :usertype"), @NamedQuery(name = "findAllUser", query = "SELECT u FROM Userinfo u") })2)修改UserManagerBean中的findAllUser方法,修改後的代碼如下: public List<Userinfo> findAllUser(){ // return em.createQuery("select u from Userinfo u").getResultList(); Query q = em.createNamedQuery("findAllUser"); List<Userinfo> list =q.getResultList(); return list; }3)從新部署、測試。
2、使用Query完成分頁分頁顯示就是每次只顯示部分對象的資訊。要顯示哪一部分資訊取決於從什麼地方開始顯示,顯示到什麼地方。Query介面可以控制要擷取的記錄,有兩個方法來設定要擷取的第一條記錄和最後一條記錄。兩個方法的定義分別如下:setMaxResults(int maxResult),參數是要查詢的最大記錄數。setFirstResult(int startposition),參數是第一個要查詢的記錄的位置。通過這兩個屬性完成分頁顯示。
實驗:自己完成使用者資訊列表的分頁顯示,每頁顯示5
條記錄。
提示:在會話Bean
中添加一個根據頁碼查詢的方法,參數是要顯示的頁碼。
3、根據條件查詢根據條件查詢包括查詢語句的構造和查詢條件處理。
3.1 構造查詢語句根據條件查詢,需要在查詢語句中使用變數,可以有兩種方式:位置參數和名字參數。
位置參數在位置參數中,使用“?”號加上參數的序號的方式表示參數。例,根據使用者名稱username查詢使用者。SELECT u FROM Userinfo u where u.username = ?11表示第一個參數。在位置參數中,可以使用多個參數,可以用不同的數字表示。同一個參數可以在查詢中出現多次。
名字參數在名字參數種,使用“:”號加上參數的名字的方式表示參數。例,根據使用者類型查詢使用者。SELECT u FROM Userinfo u WHERE u.usertype = :usertype“:”號後面的usertype就是參數的名字。 不管是位置參數還是名字參數都可以在命名查詢中使用。
3.2 處理查詢條件在執行查詢語句的時候需要為條件賦值,可以通過Query介面的相應方法完成。位置參數和名字參數使用的賦值方法是不同的,並且參數可以是各種類型。用於位置參數的主要方法如下:public Query setParameter(int position,Object value)public Query setParameter(int position,Date value,TemporalType temporalType)public Query setParameter(int position,Calendar value,TemporalType temporalType)用於名字參數的賦值方法基本相同,只是第一個參數用於指定參數的名字。主要方法如下:public Query setParameter(String name,Object value)public Query setParameter(String name,Date value,TemporalType temporalType)public Query setParameter(String name,Calendar value,TemporalType temporalType)例1:使用前面介紹的根據使用者名稱進行查詢的語句。Query q = em.createQuery("SELECT u FROM Userinfo u where u.username = ?1");q = q.setParameter(1,username);List<Userinfo> list =q.getResultList();例2:使用前面介紹的根據使用者類型進行查詢的語句。Query q = em.createQuery("SELECT u FROM Userinfo u WHERE u.usertype = :usertype");q = q.setParameter("usertype",usertype);List<Userinfo> list =q.getResultList();
實驗:在前面的功能中添加根據使用者名稱和使用者類型進行查詢的功能。參考實驗過程及代碼。1)在UserManagerBean中添加根據使用者名稱和根據使用者類型查詢使用者的方法,方法如下: // 根據使用者名稱查詢 public List<Userinfo> findUserByName(String username){ // 使用位置參數 Query q = em.createQuery("SELECT u FROM Userinfo u where u.username = ?1"); // 為參數賦值 q = q.setParameter(1,username); // 得到查詢結果 List<Userinfo> list =q.getResultList(); // 返回查詢結果 return list; } // 根據使用者類型查詢 public List<Userinfo> findUserByType(char usertype){ // 使用具名引數 Query q = em.createQuery("SELECT u FROM Userinfo u WHERE u.usertype = :usertype"); // 為參數賦值 q = q.setParameter("usertype",usertype); // 得到查詢結果 List<Userinfo> list =q.getResultList(); // 返回查詢結果 return list; } 2)在UserManagerRemote中聲明上面的兩個方法,參考代碼如下: public List<Userinfo> findUserByName(String username); public List<Userinfo> findUserByType(char usertype);3)修改FindAllUserServlet,讓該控制器可以完成3種查詢的控制,參考代碼(紅色部分為核心代碼)如下:/* * FindAllUserServlet.java * * Created on 2007年5月21日, 上午6:27 */ package jpa.web; import java.io.*;import java.net.*; import javax.servlet.*;import javax.servlet.http.*;import javax.ejb.EJB;import jpa.UserManagerRemote;import jpa.Userinfo;import java.util.List;import java.util.Iterator; /** * * @author Administrator * @version */public class FindAllUserServlet extends HttpServlet { @EJB UserManagerRemote user; /** Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. * @param request servlet request * @param response servlet response */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String usertype = request.getParameter("usertype"); // 調用業務方法 List<Userinfo> list; // 根據參數確定查詢類型,調用相應的方法 if(username != null) list = user.findUserByName(username); else if(usertype != null) list = user.findUserByType(usertype.charAt(0)); else list = user.findAllUser(); // 把查詢的結果儲存到request中,從而傳遞到頁面 request.setAttribute("userlist",list); // 專向userlist.jsp RequestDispatcher rd = request.getRequestDispatcher("userlist.jsp"); rd.forward(request,response); } // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> /** Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** Returns a short description of the servlet. */ public String getServletInfo() { return "Short description"; } // </editor-fold>}4)添加一個輸入查詢條件和顯示查詢結果的JSP檔案userlist.jsp,參考代碼如下:<%@page contentType="text/html"%><%@page pageEncoding="gb2312"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>使用者資訊</title> </head> <body> <h1>使用者資訊</h1> <br> <form action="FindAllUserServlet" method="POST"> 根據使用者名稱查詢:<input type="text" name="username" /> <input type="submit" value="確定" /> </form> <br> <form action="FindAllUserServlet" method="POST"> 根據類型查詢:<select name="usertype"> <option value="0" selected>普通使用者</option> <option value="1">管理員</option> </select><input type="submit" value="確定" /> </form> <br> <form action="FindAllUserServlet" method="POST"> <input type="submit" value="顯示所有" /> </form> <table border="1"> <thead> <tr> <th>序號</th> <th>使用者ID</th> <th>使用者名稱</th> <th>許可權</th> </tr> </thead> <tbody> <c:forEach varStatus="status" var="user" items="${userlist}"> <tr> <td>${status.index+1}</td> <td>${user.userid}</td> <td>${user.username}</td> <td> <c:if test="${user.usertype==/"0/"}"> 普通使用者 </c:if> <c:if test="${user.usertype==/"1/"}"> 管理員 </c:if> </td> </tr> </c:forEach> </tbody> </table> </body></html>5)部署、測試。
思考:如何在顯示查詢結果的時候把查詢條件也顯示出來?
4、相關介面方法關於Query介面的方法參考書上370頁Query介面部分。關於EntityManager介面的方法參考書上358頁EntityManager介面部分。