在创建jsp项目中解决无法连接数据库以及junit问题

💻博主现有专栏:

                C51单片机(STC89C516),c语言,c++,离散数学,算法设计与分析,数据结构,Python,Java基础,MySQL,linux,基于HTML5的网页设计及应用,Rust(官方文档重点总结),jQuery,前端vue.js,Javaweb开发,Python机器学习等
🥏主页链接:

                Y小夜-CSDN博客

目录

🎯项目例子

🎃项目结构

🎃所用到的方法以及类

✨Bookinfo类

✨DataBase类

 ✨Product类

 ✨ProductDao类

 ✨ProductDaoImp类

 ✨ProductTest类

✨product.jsp类

 🎃所实现的页面效果

🎯报空指针或连接不了数据库相关错误

🎃问题描述

🎃 解决方案

🎯Junit不在对应运行类上

🎃问题描述

🎃解决方法


🎯项目例子

🎃项目结构

这个是是我们项目的大体结构

🎃所用到的方法以及类

✨Bookinfo类

        这是一个用于表示图书信息的 Java 类 Bookinfo。它包含了图书的一些基本属性,比如书籍编号、书名、状态、借出日期和数量等。

        这个类提供了一系列的 getter 和 setter 方法,用于获取和设置对象的属性。构造函数 Bookinfo(String bookid, String bookname, int count) 用于初始化图书对象的部分属性,其中 bookid、bookname 和 count 是必填的参数。

package book;
public class Bookinfo {
    String bookid;
    String bookname;
    int bookstate;
    String lenddate;
    int count;

    public String getBookid() {
        return bookid;
    }

    public void setBookid(String bookid) {
        this.bookid = bookid;
    }

    public String getBookname() {
        return bookname;
    }

    public void setBookname(String bookname) {
        this.bookname = bookname;
    }

    public int getBookstate() {
        return bookstate;
    }

    public void setBookstate(int bookstate) {
        this.bookstate = bookstate;
    }

    public String getLenddate() {
        return lenddate;
    }

    public void setLenddate(String lenddate) {
        this.lenddate = lenddate;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public Bookinfo(String bookid, String bookname, int count) {
        this.bookid = bookid;
        this.bookname = bookname;
        this.count = count;
    }
}

✨DataBase类

        这段代码是一个用于数据库操作的 Java 类 DataBase。它封装了一些常见的数据库操作,包括连接数据库、执行更新操作、执行查询操作以及关闭数据库连接。

        在这个类中,首先定义了数据库的连接信息,包括 URL、用户名、密码以及驱动类。然后,在静态代码块中加载数据库驱动类。

        该类提供了 getConnection() 方法用于获取数据库连接,executeUpdate(String sql, Object...args) 方法用于执行更新操作(如插入、更新、删除等),executQuery(String sql, Object...args) 方法用于执行查询操作,并返回查询结果集,最后提供了 closeAll() 方法用于关闭数据库连接、PreparedStatement 对象和 ResultSet 对象。

这个类的设计使得数据库操作更加方便和简洁,同时也提高了代码的可维护性。

package book;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DataBase {
    static String url="jdbc:mysql://localhost:3306/bookstore";
    static String user="root";
    static String password="200454";
    static String driverClass="com.mysql.cj.jdbc.Driver";

    protected  Connection con=null;
    protected PreparedStatement ps=null;
    protected ResultSet rs=null;
    static{
        try {
            Class.forName(driverClass);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    public void getConnection(){

        try {
            if(con==null||con.isClosed())
                con=DriverManager.getConnection(url, user, password);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public int executeUpdate(String sql,Object...args){
        int result=0;
        getConnection();
        try {
            ps=con.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i+1, args[i]);
            }
            result=ps.executeUpdate();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return result;
    }

    public ResultSet executQuery(String sql,Object...args){
        getConnection();
        rs=null;
        try {
            ps=con.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i+1, args[i]);
            }
            rs=ps.executeQuery();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return rs;
    }

    public void closeAll(){

        try {
            if(rs!=null){
                rs.close();
                if(ps!=null){
                    ps.close();
                }
                if(con!=null){
                    con.close();
                }
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

 ✨Product类

        这段代码定义了一个名为 Product 的类,表示商品对象。该类具有私有属性 productidcategorynamedescn,分别表示商品的编号、类别、名称和描述。

        该类提供了公共的 getter 和 setter 方法来访问和设置这些属性的值。此外,还覆盖了 toString() 方法,以便在需要打印该对象时能够提供有意义的输出。

        这个类的设计符合面向对象的原则,使得在应用程序中可以方便地创建和操作商品对象。

package book;

public class Product {
    private String productid;
    private String category;
    private String name;
    private String descn;
    public String getProductid() {
        return productid;
    }
    public void setProductid(String productid) {
        this.productid = productid;
    }
    public String getCategory() {
        return category;
    }
    public void setCategory(String category) {
        this.category = category;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescn() {
        return descn;
    }
    public void setDescn(String descn) {
        this.descn = descn;
    }
    @Override
    public String toString() {
        return "Product [productid=" + productid + ", category=" + category
                + ", name=" + name + ", descn=" + descn
                + "]";
    }
}

 ✨ProductDao类

        这段代码定义了一个接口 ProductDao,用于商品的数据访问对象(DAO)。该接口规定了一组方法,用于对商品进行增加、更新、删除和查询等操作。

具体来说,接口中声明了以下方法:

  1. add(Product entity):向数据库中添加商品信息,并返回受影响的行数。
  2. update(Product entity):更新数据库中的商品信息,并返回受影响的行数。
  3. delete(String pid):根据商品编号从数据库中删除对应的商品信息,并返回受影响的行数。
  4. findByCatid(String catid):根据商品类别编号查询数据库中对应的商品信息,并返回结果列表。
  5. findByName(String name):根据商品名称查询数据库中对应的商品信息,并返回结果列表。
  6. findall():查询数据库中所有商品的信息,并返回结果列表。

        这些方法定义了对商品信息进行常见操作的接口,具体的实现可以根据具体的数据库访问框架来完成。通常,这个接口会被一个具体的类来实现,该类负责与数据库进行交互,执行具体的数据库操作。

package book;
import java.util.List;

public interface ProductDao {
    public int add(Product entity);
    public int update(Product entity);
    public int delete(String pid);
    //public List<Product> findAll();
    public List<Product> findByCatid(String catid);
    public List<Product> findByName(String name);
    public List<Product> findall();

}

 ✨ProductDaoImp类

        这段代码实现了 ProductDao 接口的具体方法,在数据库中对商品信息进行增删改查操作。

  1. add(Product entity) 方法用于向数据库中添加商品信息。
  2. update(Product entity) 方法用于更新数据库中的商品信息。
  3. delete(String pid) 方法用于根据商品编号从数据库中删除对应的商品信息。
  4. findByCatid(String catid) 方法用于根据商品类别编号查询数据库中对应的商品信息。
  5. findByName(String name) 方法用于根据商品名称查询数据库中对应的商品信息。
  6. findall() 方法用于查询数据库中所有商品的信息。

        这些方法中,通过执行 SQL 语句并处理查询结果集,将数据库中的商品信息转换为 Product 对象并添加到列表中返回。

        需要注意的是,代码中使用了继承关系,ProductDaoImp 类继承自 DataBase 类。在 ProductDaoImp 中直接调用了 executeUpdateexecutQuery 方法,这些方法应该是 DataBase 类中的实现。具体的数据库操作在 DataBase 类中实现。

package book;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

//import rjxy.entity.account;

public class ProductDaoImp  extends DataBase implements ProductDao  {
    @Override
    public int add(Product entity) {
        String sql="insert into product values(?,?,?,?)";
        return
                this.executeUpdate(sql,
                        entity.getProductid(),entity.getCategory()
                        ,entity.getName(),entity.getDescn());
    }
    @Override
    public int update(Product entity) {
        String sql="update product set category=?,name=?,descn=? where productid=?";
        return
                this.executeUpdate(sql,entity.getCategory()
                        ,entity.getName(),entity.getDescn(),
                        entity.getProductid());
    }
    @Override
    public int delete(String pid) {
        String sql="delete from product where productid=?";
        return
                this.executeUpdate(sql, pid);
    }
    @Override
    public List<Product> findByCatid(String catid) {
        String sql="select * from product where category=?";
        List<Product> list=new ArrayList<Product>();
        this.rs=this.executQuery(sql,catid);
        try {
            while(rs.next()) {

                Product p=new Product();
                p.setCategory(rs.getString("category"));
                p.setDescn(rs.getString("descn"));
                p.setName(rs.getString("name"));
                p.setProductid(rs.getString("productid"));

                list.add(p);
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return list;
    }
    @Override
    public List<Product> findByName(String name) {
        String sql="select * from product where name like ?";
        this.rs=this.executQuery(sql,name);
        List<Product> list=new ArrayList<Product>();
        try {
            while(rs.next()) {

                Product p=new Product();
                p.setCategory(rs.getString("category"));
                p.setDescn(rs.getString("descn"));
                p.setName(rs.getString("name"));
                p.setProductid(rs.getString("productid"));

                list.add(p);
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return list;
    }


    public List<Product> findall() {
        // TODO Auto-generated method stub

        String sql=" select * from product";
        this.rs=this.executQuery(sql);
        List<Product> list=new ArrayList<>();
        Product p=null;
        try {
            while(rs.next()) {
                p=new Product();
                p.setCategory(rs.getString("category"));
                p.setDescn(rs.getString("descn"));
                p.setName(rs.getString("name"));
                p.setProductid(rs.getString("productid"));

                list.add(p);

            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return list;
    }


}

 ✨ProductTest类

        这段代码是一个简单的测试类 ProductTest,用于测试 ProductDaoImp 类中的 findall() 方法。

        在 findall() 方法中,首先调用 ProductDaoImp 类的 findall() 方法获取数据库中所有商品的信息,然后遍历返回的商品列表,并打印每个商品的信息。最后调用 closeAll() 方法关闭数据库连接。

        这个测试方法可以帮助验证 findall() 方法是否能够正确地从数据库中获取所有商品的信息,并且是否能够正常地打印出来。

package book;

import java.util.List;

import org.junit.Test;

public class ProductTest {

    ProductDaoImp pdi = new ProductDaoImp();
    @Test
    public void findall() {
        List<Product> list = pdi.findall();
        for (Product product : list) {
            System.out.println(product);
        }
        pdi.closeAll();
    }
}

✨product.jsp类

        这段代码是一个简单的 JSP 页面,用于显示数据库中的产品信息。

        首先,通过 ProductDaoImp 类获取所有产品的信息,并将结果存储在 list 中。

然后,页面使用 Bootstrap 框架创建了一个简单的表格,用于显示产品信息。表格包括了产品的编号、名称、描述、类别以及操作列。

        在 Java 代码块中使用了 JSP 的循环语句遍历 list 中的产品信息,并将每个产品的属性填充到表格中相应的位置。同时,为每个产品添加了修改和删除的链接。

        需要注意的是,在 <link><script> 标签中引入了 Bootstrap 和 jQuery 库,确保页面样式和功能的正常显示和运行。

​
<%@ page language="java" contentType="text/html; charset=utf-8"
         pageEncoding="utf-8"%>
<%@ page import="book.Product" %>
<%@ page import="book.ProductDaoImp" %>
<%@ page import="java.util.List" %>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport"  content="width=device-width,initial-scale=1">
    <title>Insert title here</title>
    <link rel="stylesheet" href="css/bootstrap.css" type="text/css"/>
    <script type="text/javascript"  src="js/jquery-1.11.3.min.js"></script>
    <script type="text/javascript" src="js/bootstrap.js"></script>
</head>
<body>
<!--以表格形式来显示图书信息 -->
<%
    ProductDaoImp pdi=new ProductDaoImp();
    List<Product> list=pdi.findall();
%>
<div class=""><a href="#">添加产品</a></div>
<div class="row" style="height:500px; text-align:center;">
    <div class="col-md-10 col-md-push-1">
        <table class="table table-striped">
            <tr>
                <td>图书编号</td>
                <td>图书名称</td>
                <td>图书描述</td>
                <td>图书类别</td>
                <td>操作</td>
            </tr>
            <% for(Product p:list){%>
            <tr>
                <td><%=p.getProductid() %></td>
                <td><%=p.getName() %></td>
                <td><%=p.getDescn() %></td>
                <td><%=p.getCategory() %></td>
                <td><a href="#">修改</a><a href="#">删除</a></td>
            </tr>
            <%} %>
        </table>a
    </div>
</div>
</body>
</html>

​

 🎃所实现的页面效果

🎯报空指针或连接不了数据库相关错误

🎃问题描述

ChatGPT给出的答案:

        这个错误是由于在执行 ProductDaoImp.findall() 方法时出现了空指针异常(NullPointerException)。具体地,异常堆栈信息显示在 ProductDaoImp 类的 findall() 方法的第 72 行出现了空指针异常。

空指针异常通常是因为尝试在空对象上调用方法或访问属性而引起的。在你的情况下,可能有几种原因导致了空指针异常:

  1. 数据库连接问题:如果在 DataBase.executQuery() 方法中出现了空指针异常,可能是因为数据库连接没有正确地建立或者被关闭了。你需要确保数据库连接正常并且可用。

  2. 查询返回空值:如果 ProductDaoImp.findall() 方法返回了空值(即没有查询到任何数据),而你的代码没有处理这种情况,尝试在空列表上执行操作可能导致空指针异常。你需要在使用返回的列表之前进行空值检查。

  3. 程序逻辑问题:可能是由于代码逻辑错误导致的。在调用 ProductDaoImp.findall() 方法之前,你可能需要确保所有必要的依赖项都已经正确地设置和初始化。

要解决这个问题,你可以:

  • 在程序中添加适当的空值检查,以防止空指针异常的发生。
  • 检查数据库连接是否正确建立,并确保查询方法能够正常执行并返回正确的结果。
  • 检查代码逻辑,确保所有依赖项都被正确初始化和设置。

🎃 解决方案

其实这个问题就是因为我们的web文件类中缺少关于连接数据库的jar包

在文件夹中找到我们的jar包,一般都在C:\Program Files (x86)\MySQL\Connector J 8.0

把他复制一下,让粘贴在我们WEB-INT下的lib文件夹内

在运行一下项目,应该就ok了

🎯Junit不在对应运行类上

🎃问题描述

运行wrok2模块下的test程序,但是Junit总是默认在work3下

🎃解决方法

我并没研究出调默认的方法,有好的方法的友友可以分享到评论区

我的方法,就是每次运行其他模块测试代码时,调一下配置:

点击三角符号,然后选择Mofify Run Configuration 

在这里可以选择你要运行的模块和类,点击OK

再次运行,就可以完成测试了

  • 29
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 23
    评论
首先,我们需要设计一个图书管理系统的注册web页面,可以参考以下代码: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>图书管理系统注册</title> </head> <body> <h1>欢迎注册图书管理系统</h1> <form action="register.jsp" method="post"> <label for="username">用户名:</label> <input type="text" id="username" name="username"><br> <label for="password">密码:</label> <input type="password" id="password" name="password"><br> <label for="confirm_password">确认密码:</label> <input type="password" id="confirm_password" name="confirm_password"><br> <label for="email">邮箱:</label> <input type="email" id="email" name="email"><br> <input type="submit" value="注册"> </form> </body> </html> ``` 接下来,我们需要编写register.jsp用户注册程序,并使用junit+cactus进行单元自动化测试。可以参考以下代码: ```jsp <%@ page import="java.sql.*" %> <%@ page import="javax.sql.*" %> <%@ page import="javax.naming.*" %> <%@ page import="javax.servlet.http.*" %> <%@ page import="junit.framework.*" %> <%@ page import="org.apache.cactus.*" %> <% public class RegisterTest extends TestCase { public void testRegister() throws Exception { HttpServletRequest request = new MockHttpServletRequest(); HttpServletResponse response = new MockHttpServletResponse(); Register servlet = new Register(); servlet.doPost(request, response); // 验证注册结果 assertEquals("success", request.getAttribute("result")); } } public class Register extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); String confirm_password = request.getParameter("confirm_password"); String email = request.getParameter("email"); if (username == null || password == null || confirm_password == null || email == null) { request.setAttribute("result", "error"); return; } if (!password.equals(confirm_password)) { request.setAttribute("result", "error"); return; } // 连接数据库,执行插入操作 Context ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/bookstore"); Connection conn = ds.getConnection(); PreparedStatement ps = conn.prepareStatement("INSERT INTO users(username, password, email) VALUES (?, ?, ?)"); ps.setString(1, username); ps.setString(2, password); ps.setString(3, email); int result = ps.executeUpdate(); if (result == 1) { request.setAttribute("result", "success"); } else { request.setAttribute("result", "error"); } } } %> ``` 以上代码,我们使用了MockHttpServletRequest和MockHttpServletResponse来模拟HttpServletRequest和HttpServletResponse对象,并使用junit.framework.TestCase来编写测试用例。在测试用例,我们首先创建了HttpServletRequest和HttpServletResponse对象,然后调用Register的doPost方法进行注册,最后使用assertEquals方法来验证注册结果。在Register的doPost方法,我们首先获取用户提交的参数,并进行检查,然后连接数据库并执行插入操作,最后将结果存储到request

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Y小夜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值