Java持久性API(JPA)第3讲——使用查询

 
目标:掌握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 = ?1
1表示第一个参数。
在位置参数中,可以使用多个参数,可以用不同的数字表示。同一个参数可以在查询中出现多次。
名字参数
在名字参数种,使用“:”号加上参数的名字的方式表示参数。
例,根据用户类型查询用户。
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接口部分。
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值