Java 创建与数据库对话的自定义标记

Java 创建与数据库对话的自定义标记,java,spring,jsp,jsp-tags,Java,Spring,Jsp,Jsp Tags,我想创建一个自定义标记,它与数据库对话,从表中检索记录,然后显示在jsp页面上 我用的是弹簧。和Eclipselink作为JPA提供商。我写了一个自定义类 package com.persistent.testjpa.taghandlers; import java.io.IOException; import java.util.Date; import java.util.List; import javax.servlet.jsp.JspException; import javax.

我想创建一个自定义标记,它与数据库对话,从表中检索记录,然后显示在jsp页面上

我用的是弹簧。和Eclipselink作为JPA提供商。我写了一个自定义类

package com.persistent.testjpa.taghandlers;

import java.io.IOException;
import java.util.Date;
import java.util.List;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;

import org.springframework.beans.factory.annotation.Autowired;

import com.persistent.testjpa.dao.MyUserDao;
import com.persistent.testjpa.domain.MyAuthorities;


public class MyListTagHandler extends SimpleTagSupport {

    private String tableName;
    private MyUserDao dao;

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public void doTag() throws JspException, IOException {
        System.out.println("Indise Do Tag Method");
        JspWriter out = getJspContext().getOut();
        if (tableName != null) {
            System.out.println("Table Name : "+getTableName());
            out.println("<html><body>");
            out.println("Today's Date is "+ new Date());

            out.println("</body></html>");
        }  else {
            out.println("<html><body>");
            out.println("Please Enter Table Name");
            out.println("</body></html>");
        }
    }

    @Autowired
    public void setDao(MyUserDao dao) {
        this.dao = dao;
    }

    public List<MyAuthorities> getList(){
        return dao.list();
    }

}
package com.persistent.testjpa.taghandlers;
导入java.io.IOException;
导入java.util.Date;
导入java.util.List;
导入javax.servlet.jsp.JspException;
导入javax.servlet.jsp.JspWriter;
导入javax.servlet.jsp.tagext.SimpleTagSupport;
导入org.springframework.beans.factory.annotation.Autowired;
导入com.persistent.testjpa.dao.MyUserDao;
导入com.persistent.testjpa.domain.MyAuthorities;
公共类MyListTagHandler扩展了SimpleTagSupport{
私有字符串表名;
私密的MyUserDao;
公共字符串getTableName(){
返回表名;
}
public void setTableName(字符串tableName){
this.tableName=tableName;
}
public void doTag()抛出JSPEException,IOException{
System.out.println(“indie-Do-Tag方法”);
JspWriter out=getJspContext().getOut();
if(tableName!=null){
System.out.println(“表名:+getTableName());
out.println(“”);
out.println(“今天的日期是”+新日期());
out.println(“”);
}否则{
out.println(“”);
out.println(“请输入表名”);
out.println(“”);
}
}
@自动连线
公共void setDao(MyUserDao){
this.dao=dao;
}
公共列表getList(){
返回dao.list();
}
}
当我尝试访问Dao对象时,代码抛出一个NullPointer异常

有人能告诉我怎么了吗


谢谢

最干净的方法可能是使用jstl/sql中的标准现有标记,并制作一个简单的标记文件,而不是标记类:

    <%@taglib  prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
    <%@taglib  prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@attribute name="table" required="true"%>    
    <sql:query var="temporary">
        select * from ${table}
    </sql:query>
    <table border="1">
        <tr>
            <c:forEach items="${temporary.columnNames}" var="temporary_value">
                <th>${temporary_value}</th>
            </c:forEach>
        </tr>
        <c:forEach items="${temporary.rowsByIndex}" var="temporary_row">

            <tr>
                <c:forEach items="${temporary_row}" var="temporary_value">
                    <td>${temporary_value}</td>
                </c:forEach>
            </tr>
        </c:forEach>
    </table>

从${table}中选择*
${临时值}
${临时值}
如果将代码作为dbtable.tag放在WEB-INF/tags中,则可以这样使用:

<%@taglib  prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<sql:setDataSource dataSource="jdbc/mydb" scope="request" />
<tags:dbtable table="customers"/>

对数据库的引用必须在web.xml中进行,并且必须在类路径中的某个位置具有标准JSTL JAR

注意,像这样构建sql需要经常注意,因为不允许sql注入

在您的设计中,以下两者之间存在着巨大的张力:

  • 静态类型、面向对象和分层-使用Spring/daos/JPA显示
  • 模型1体系结构,平面(而非分层)设计,将HTML与逻辑相结合-通过希望按需创建查询来显示,显示“记录”(而非“查看对象图”),将业务查询放置在HTML模板中等
这两种方法都可以(取决于您试图解决的问题和应用程序的范围),但它们确实不能很好地混合。现在看来,这两种方法都有缺点,但都没有好处

我建议你:

  • 放弃Spring和daos,使用纯jstl/sql;这将使您的应用程序成为围绕数据库的一个简单、薄的层;您可以自由地使用视图和存储过程来封装真正的逻辑;许多大型应用程序都是这样工作的,特别是那些由具有强大数据库技能的人编写的应用程序
  • 放弃“神奇桌牌”的想法;制作一组JavaBean,这些JavaBean不是万能的,而是针对特定任务定制的。让它们由Spring注入,使用DAO、声明性事务划分等。这将使您的代码更长,通用性更低,但(如果做得好的话)在未来几年更容易维护
不能对标记类使用Spring自动布线。看。嗨,谢谢你抽出时间。我读了你提到的帖子。它说我们需要在控制器中设置对象。我想让一个通用标记名为myList,它有一个名为tablename的属性。如果我传入一个现有的表名,它应该连接到数据库,获取记录并显示在JSP页面上。你能为我提供一些如何实现这一目标的指导吗?