Servlet(六):连接数据库,完整的CRUD

JSP+Servlet实现CRUD(异步) JDBC+JSP+Servlet+Maven+异步(实现CRUD) 阅读详情

Servlet的知识点大致讲完了,今天补充下与之相关的一些小知识,然后做一个完整的小例子。

一、MVC设计模式

1、MVC设计模式是什么?

在了解MVC之前,先聊聊Model1、Model2开发模式。

Model1开发模式中,使用jsp页面嵌套一些java代码、代码块,既处理请求,又处理数据,将java代码和html代码高度耦合在一起,对于后期的维护和拓展非常不便,这就是Model1开发模式。

Model2开发模式,引入了分层思想,即MVC模式,将代码进行了分层,降低了耦合度,方便后期的维护和扩展。

MVC模式,其中M是Model的缩写,表示模型,在应用中包含业务处理层和数据访问层。数据访问层主要是对数据库的一些操作的封装。业务处理层应用JavaBean构建, JavaBean主要是用作将从View层获取的数据和数据库的数据进行桥接。

V是View的缩写,表示视图,视图提供了可交互的用户界面,向用户显示模型数据,通常使用jsp和HTML搭建。

C是Controller的缩写,表示控制层,负责调度,是模型和视图的桥梁。

2、为什么要用MVC设计模式?

一是程序耦合度较低,方便修改和维护;二是可扩展性高,方便后期的业务扩展;三是可重用性高,可以重复使用已有的控制层,减少重复代码。

二、完整的CRUD

1、新建一个Maven项目,建好目录结构

项目结构使用了上面提到的MVC分层结构,如下图所示

 

2、配置web.xml和pom.xml文件

web.xml文件是配置servlet的,pom.xml是配置所需要的jar包。

  <servlet>
      <servlet-name>servlet</servlet-name>
      <servlet-class>web.EmployeeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>servlet</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
  <dependencies>
      <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.8</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency> 
  </dependencies>

3、连接数据库

先建库,再建表,然后插入原始数据。

CREATE TABLE employee(
    id varchar(36) NOT NULL,
    name varchar(50),
    gender varchar(4),
    birthday DATE,
    email varchar(20),
    salary varchar(20),
    remark varchar(200),
    PRIMARY KEY (`id`)  
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into employee values ('5476cbc52c084d56a8d2492a372450a3','小川94','男','2000-05-25','1340059045@qq.com','10000','无');

编写DBUtil类,连接数据库

/**
 * 管理数据库连接
 * @author 小川94
 * @date 2018年6月11日
 */
public class DBUtil {
    
    private static String user ="";
    private static String password = "";
    private static String url = "";
    private static String driver = "";
    private static Connection conn = null;
    
    /**
     * 获取数据库连接
     * @return Connection
     */
    public static Connection getConnection(){
        try{
            // 读取配置文件
            user = ConfigUtil.getConfigValue("jdbc.user");
            password = ConfigUtil.getConfigValue("jdbc.password");
            url = ConfigUtil.getConfigValue("jdbc.jdbcUrl");
            driver = ConfigUtil.getConfigValue("jdbc.driverClass");
            // 加载驱动
            Class.forName(driver);
            conn = DriverManager.getConnection(url, user, password);
        }catch(Exception e){
            System.out.println("数据库连接异常");
            e.printStackTrace();
        }
        return conn;
    }
    
    /**
     * 关闭数据库连接
     * @param conn
     */
    public static void closeConnection(Connection conn){
        if(conn != null){
            try{
                conn.close();
            }catch(SQLException e){
                System.out.println("数据库关闭异常");
                e.printStackTrace();
            }
        }
    }
    
}

其中使用了读取配置文件的ConfigUtil类

/**
 * 读取配置文件
 * @author 小川94
 * @date 2018年6月11日
 */
public class ConfigUtil {

    public static String getConfigValue(String tagName) {
        String tagValue = null;
        Properties prop = new Properties();
        try {
            ClassLoader classLoader = ConfigUtil.class.getClassLoader(); 
            // 读取配置文件dbconfig.properties
            InputStream in = classLoader.getResourceAsStream("dbconfig.properties");
            prop.load(in); // 加载属性列表
            Iterator<String> it = prop.stringPropertyNames().iterator();
            while (it.hasNext()) {
                if (it.next().equals(tagName)) {
                    tagValue = prop.getProperty(tagName);
                }
            }
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return tagValue;
    }
    
}

4、编写实体类

/**
 * 实体类
 * @author 小川94
 * @date 2018年6月11日
 */
public class Employee {
    
    private String id; // 主键
    private String name; // 姓名
    private String gender; // 性别
    private String email; // 邮箱
    private String salary; // 薪水
    private String remark; // 备注
    private Date birthday; // 出生日期
    
    public Employee(){
        
    }
    
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getSalary() {
        return salary;
    }
    public void setSalary(String salary) {
        this.salary = salary;
    }
    public String getRemark() {
        return remark;
    }
    public void setRemark(String remark) {
        this.remark = remark;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    
    /**
     * 重写toString方法,方便junit测试
     */
    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + name + ", gender=" + gender +  ", birthday=" + birthday 
                +", salary=" + salary + ", email=" + email + ", remark=" + remark + "]";
    }
    
}

5、查询数据

查询数据功能,一是查询出所有数据,二是需要考虑页面的查询条件,需要两者结合考虑。

控制层使用了反射机制,使用一个Servlet处理多个请求,减少代码重复。

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取请求的URI地址信息
        String url = request.getRequestURI();
        // 截取其中的方法名
        String methodName = url.substring(url.lastIndexOf("/")+1, url.lastIndexOf("."));
        Method method = null;
        try {
            // 使用反射机制获取在本类中声明了的方法
            method = getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            // 执行方法
            method.invoke(this, request, response);
        } catch (Exception e) {
            throw new RuntimeException("调用方法出错!");
        }
    }
    /**
     * 查询employee表中的所有数据
     * @return List<Employee> 包含所有员工信息的list
     */
    public List<Employee> queryAllEmployee(String name, String salary, String salary2) {
        Connection conn = null;
        List<Employee> employees = new ArrayList<Employee>();
        try{
            // 连接数据库
            conn = DBUtil.getConnection();
            if (StringUtil.isEmpty(conn)) {
                throw new Exception("数据库连接失败");
            }
            // 编写sql语句
            String sql = "SELECT * FROM EMPLOYEE";
            String str = "";
            if(StringUtil.isNotEmpty(name) || StringUtil.isNotEmpty(salary) || StringUtil.isNotEmpty(salary2)){
                if(StringUtil.isNotEmpty(name)){
                    str = " WHERE NAME LIKE '%"+name+"%'";
                }
                if(StringUtil.isNotEmpty(salary)){
                    if(str.length() == 0){
                        str = " WHERE SALARY > " + salary;
                    }else{
                        str = str + " AND SALARY > " + salary;
                    }
                }
                if(StringUtil.isNotEmpty(salary2)){
                    if(str.length() == 0){
                        str = " WHERE SALARY < " + salary2;
                    }else{
                        str = str + " AND SALARY < " + salary2;
                    }
                }
            }
            // 创建一个 PreparedStatement 对象,初始化sql语句
            PreparedStatement ps = conn.prepareStatement(sql+str);
            // 获取执行sql语句后的结果集
            ResultSet rs = ps.executeQuery();
            Employee emp = null;
            // 遍历结果集,添加到list中
            while (rs.next()) {
                emp = new Employee();
                emp.setId(rs.getString("id"));
                emp.setName(rs.getString("name"));
                emp.setGender(rs.getString("gender"));
                emp.setEmail(rs.getString("email"));
                emp.setBirthday(rs.getDate("birthday"));
                emp.setRemark(rs.getString("remark"));
                emp.setSalary(rs.getString("salary"));
                employees.add(emp);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接
            if (StringUtil.isNotEmpty(conn)) {
                DBUtil.closeConnection(conn);
            }
        }
        return employees;
    }

编写控制层代码

    private void queryEmp(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        EmployeeDao dao = new EmployeeDao();
        request.setCharacterEncoding("utf-8");
        String name = request.getParameter("name");
        String salary = request.getParameter("salary");
        String salary2 = request.getParameter("salary2");
        List<Employee> employees = dao.queryAllEmployee(name, salary, salary2);
        request.setAttribute("employees", employees);
        request.getRequestDispatcher("queryList.jsp").forward(request, response);
    }

6、新增数据

本质是提交表单数据到后台,通过Model层处理数据。

    /**
     * 新增员工信息
     * @param emp
     */
    public int addEmployee(Employee emp){
        if(StringUtil.isEmpty(emp)){
            throw new RuntimeException("参数为空!");
        }
        Connection conn = null;
        int result = 0;
        try{
            conn = DBUtil.getConnection();
            if(StringUtil.isEmpty(conn)){
                throw new Exception("数据库连接失败!");
            }
            String sql = "INSERT INTO EMPLOYEE VALUES (?,?,?,?,?,?,?) ";
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1, StringUtil.getUUID());
            ps.setString(2, emp.getName());
            ps.setString(3, emp.getGender());
            ps.setDate(4, emp.getBirthday());
            ps.setString(5, emp.getEmail());
            ps.setString(6, emp.getSalary());
            ps.setString(7, emp.getRemark());
            result = ps.executeUpdate();
        }catch(Exception e){
            e.printStackTrace();
        } finally {
            // 关闭数据库连接
            if (StringUtil.isNotEmpty(conn)) {
                DBUtil.closeConnection(conn);
            }
        }
        return result;
    }
    /**
     * 新增(修改)员工信息,根据id是否为空判断新增操作、修改操作
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    private void addEmp(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        EmployeeDao dao = new EmployeeDao();
        request.setCharacterEncoding("utf-8");
        Employee emp = new Employee();
        String id = request.getParameter("id");
        if (StringUtil.isEmpty(id) || "null".equals(id)) {
            try {
                emp.setId(StringUtil.getUUID());
                emp.setName(request.getParameter("name"));
                emp.setGender(request.getParameter("gender"));
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                java.util.Date date =  sdf.parse(request.getParameter("birthday"));
                java.sql.Date birthday = new java.sql.Date(date.getTime());
                emp.setBirthday(birthday);
                emp.setEmail(request.getParameter("email"));
                emp.setSalary(request.getParameter("salary"));
                emp.setRemark(request.getParameter("remark"));
            } catch (Exception e) {
                e.printStackTrace();
            }
            dao.addEmployee(emp);
            response.sendRedirect("queryList.jsp");
        } else {
            modifyEmpInfo(request, response);
        }
    }

7、修改数据

修改数据,我们共用了新增数据的jsp页面,使用了js方法来控制页面的数据展示和可修改性,同时后台需要对新增和修改的数据处理逻辑拆分。

    /**
     * 根据员工信息id来修改相关内容
     * @param id
     * @return
     */
    public boolean modifyEmployeeById(Employee emp){
        if(StringUtil.isEmpty(emp)){
            throw new RuntimeException("参数为空!");
        }
        Connection conn = null;
        boolean flag = false;
        try{
            conn = DBUtil.getConnection();
            if(StringUtil.isEmpty(conn)){
                throw new Exception("数据库连接失败!");
            }
            String sql = "UPDATE EMPLOYEE SET EMAIL=? , SALARY=? , REMARK=? WHERE ID=? ";
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1, emp.getEmail());
            ps.setString(2, emp.getSalary());
            ps.setString(3, emp.getRemark());
            ps.setString(4, emp.getId());
            int result = ps.executeUpdate();
            if (result == 1) {
                flag = true;
            }
        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接
            if (StringUtil.isNotEmpty(conn)) {
                DBUtil.closeConnection(conn);
            }
        }
        return flag;
    }

编写控制层代码

    private void modifyEmpInfo(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        request.setCharacterEncoding("utf-8");
        EmployeeDao dao = new EmployeeDao();
        Employee emp = new Employee();
        try{
            emp.setId(request.getParameter("id"));
            emp.setName(request.getParameter("name"));
            emp.setGender(request.getParameter("gender"));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            java.util.Date date =  sdf.parse(request.getParameter("birthday"));
            java.sql.Date birthday = new java.sql.Date(date.getTime());
            emp.setBirthday(birthday);
            emp.setEmail(request.getParameter("email"));
            emp.setSalary(request.getParameter("salary"));
            emp.setRemark(request.getParameter("remark"));
        }catch(Exception e){
            e.printStackTrace();
        }
        boolean flag = dao.modifyEmployeeById(emp);
        if(!flag){
            request.setAttribute("msg", "修改员工信息失败!");
            request.getRequestDispatcher("error.jsp").forward(request, response);
        }else{
            response.sendRedirect("queryList.jsp");
        }
    }

8、删除数据

删除数据,我们需要拿到所要删除数据的id。

    /**
     * 根据员工信息的id删除数据
     * @param id
     * @return
     */
    public boolean deleteEmployeeById(String id){
        if(StringUtil.isEmpty(id)){
            throw new RuntimeException("参数为空!");
        }
        Connection conn = null;
        boolean flag = false;
        try{
            conn = DBUtil.getConnection();
            if(StringUtil.isEmpty(conn)){
                throw new Exception("连接数据库失败!");
            }
            String sql = "DELETE FROM EMPLOYEE WHERE ID = ?";
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1, id);
            int result = ps.executeUpdate();
            if(result == 1){
                flag = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接
            if (StringUtil.isNotEmpty(conn)) {
                DBUtil.closeConnection(conn);
            }
        }
        return flag;
    }

编写控制层代码

    private void deleteEmp(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        EmployeeDao dao = new EmployeeDao();
        request.setCharacterEncoding("utf-8");
        String id = request.getParameter("id");
        boolean flag = dao.deleteEmployeeById(id);
        if(!flag){
            request.setAttribute("msg", "删除员工信息失败!");
            request.getRequestDispatcher("error.jsp").forward(request, response);
        }else{
            request.getRequestDispatcher("queryList.jsp").forward(request, response);
        }
    }

9、查看数据

查看数据的本质是将数据查询出来,回显到页面。

    /**
     * 根据员工信息id查询完整员工信息
     * @param id
     * @return
     */
    public Employee queryEmpById(String id) {
        if (StringUtil.isEmpty(id)) {
            throw new RuntimeException("参数为空!");
        }
        Connection conn = null;
        Employee emp = new Employee();
        try {
            conn = DBUtil.getConnection();
            if (StringUtil.isEmpty(conn)) {
                throw new RuntimeException("数据库连接失败!");
            }
            String sql = "SELECT * FROM EMPLOYEE WHERE ID=?";
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1, id);
            ResultSet rs = ps.executeQuery();
            if(StringUtil.isEmpty(rs)){
                throw new RuntimeException("查询信息失败!");
            }
            while (rs.next()) {
                emp.setId(rs.getString("id"));
                emp.setName(rs.getString("name"));
                emp.setGender(rs.getString("gender"));
                emp.setEmail(rs.getString("email"));
                emp.setBirthday(rs.getDate("birthday"));
                emp.setRemark(rs.getString("remark"));
                emp.setSalary(rs.getString("salary"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接
            if (StringUtil.isNotEmpty(conn)) {
                DBUtil.closeConnection(conn);
            }
        }
        return emp;
    }

编写控制层代码

    private void queryEmpInfo(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        EmployeeDao dao = new EmployeeDao();
        request.setCharacterEncoding("utf-8");
        String id = request.getParameter("id");
        Employee emp = dao.queryEmpById(id);
        request.getSession().setAttribute("Emp", emp);
        request.getRequestDispatcher("empInfo.jsp").forward(request, response);
    }

10、单元测试

使用Junit包,来完成相应的功能方法测试。

View Code

11、编写View层

查询页面jsp编写

View Code

新增(修改)jsp页面编写

View Code

查看信息jsp页面编写

View Code

错误信息jsp页面

View Code

三、测试

测试结果如下图所示,对于分页展示数据的问题,下次再单独处理。



文章首发于我的个人公众号:悦乐书。喜欢分享一路上听过的歌,看过的电影,读过的书,敲过的代码,深夜的沉思。期待你的关注!

公众号后台输入关键字“Java学习电子书”,即可获得12本Java学习相关的电子书资源,如果经济能力允许,还请支持图书作者的纸质正版书籍,创作不易。

Servlet系列教材 (十九)- CRUD - 用Servlet 做增删改查CRUD一套 每个不同的操作,都需要一个对应的Servlet,除了做Hero之外,还会做到其他的一些表的相关操作,所以好的规范会对将来的维护更有好处。本章节将介绍如何与JDBC结合,通过servlet查询数据库,根据查询结果,得到一个html页面,显示数据库中的内容。做一个Hero的维护页面需要一些通用的操作,比如增加,删除,编辑,修改,查询等。的可运行项目,配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。不同,其作用的web应用在tomcat中运行起来后,能够找到jar包中的类。 阅读详情

相关推荐

Java Web数据库操作实战项目:连接与CRUD

数据定义语言(DDL)用于定义或修改数据库中的数据结构,包括创建、删除或修改数据库中的表和索引等。DDL主要包含以下几种命令:CREATE:创建新的数据库结构,如表、索引或视图。ALTER:修改现有的数据库结构。DROP:删除整个数据库结构,包括表、索引或视图。DDL语句会直接改变数据库模式,通常不需要事务处理,因为它们是自动提交的。下面是一个简单的例子来说明DDL的使用:上述代码创建了一个名为employees的表,其中包含四个字段:id(主键)、name。

weixin_36299472的博客 760

Servlet学习的一个简单小实战(配合数据库登录案例)

前言:学习Servlet也有一段时间了,但是总感觉走马观花,学一学还是对实际操作不是很懂,最近在看学习视频中有介绍可以自己做一个连接数据库的登录小实战,就当是复习复习之前的JDBC编程那块,也顺便巩固了下Servlet中request和respons这边的常用操作。 问题分析:基本上就是先写一个页面,其中包含输入账号密码,通过表单数据来进行跟MySQL数据库进行对接,判断输入的账号密码是否在数据库...

Harbor 223

JSP与数据库CRUD操作实践指南

JavaServer Pages(JSP)是Java EE技术中用于简化Web页面开发的一种技术。通过将Java代码嵌入到HTML页面中,JSP文件被服务器在运行时翻译成Servlet,从而实现动态内容的生成。与直接使用Servlet相比,JSP更便于页面设计人员进行页面的布局和内容更新,同时兼顾了后端逻辑的强大处理能力。请求转发(Request Forwarding)是指在一个Web应用程序中,当一个Servlet或JSP页面处理完一个请求后,将请求和响应对象传递给另一个资源继续处理的过程。

weixin_36231030的博客 1080

使用Servlet连接数据库进行查询

确保JDBC驱动已经正确添加到项目的类路径中。在处理数据库连接和查询时,注意异常处理,确保资源能够正确关闭,避免资源泄露。为了提高性能和安全性,可以考虑使用连接池和预处理语句(在生产环境中,数据库连接信息(如用户名和密码)应该存储在安全的配置文件中,而不是硬编码在Servlet中。这个过程展示了Java Web应用中Servlet与数据库交互的基本模式,是构建Web应用时常用的技术之一。

weixin_57350343的博客 981

JSP和Servlet结合SQL Server 2005的CRUD操作指南

在Web开发领域,JSP(Java Server Pages)是一个重要的技术,它允许开发者将Java代码嵌入到HTML页面中,从而实现动态网页内容的生成。JSP在服务器端执行,其生成的动态内容会被发送到客户端浏览器。本章节将介绍JSP的基础知识,为接下来深入学习JSP与Servlet的交互打下基础。Servlet是Java语言编写的服务器端程序,它能够处理客户端的请求,并且生成响应。它是Java Servlet API的一部分,主要用于扩展基于Java的Web服务器的功能。

weixin_34725745的博客 978

实战指南:深度剖析Servlet+JSP+JDBC技术栈下的用户CRUD操作

基于Servlet+JSP+JDBC的完整的用户信息操作-CRUD项目总结

weixin_52937170的博客 1210

Servlet入门----连接MySql数据库,实现登录验证操作

连接数据库,实现登录验证一个简单的运用Servlet+JSP+MySQL的登录小程序! 工程目录结构如下图所示: 第一步:创建数据库login,新建登录表login_info,表内包含两个字段: username和password。 PS:我是用的Navicat for MySQL工具建的表,省时省力哈哈 第二步:构建User.java类,存放username和password.代码如下:

Hangele的博客 2万+

OpenVPN 新增 windows 客户端

虚拟私人网络(Virtual Private Network,简称VPN)是一种网络技术,它允许用户通过公共网络(如互联网)建立一个安全的连接通道。本文介绍如何添加 windows 客户端。

利昂的技术存档 3777

Servlet数据库连接池

一个动态的网站频繁地从数据库中取得数据来构成html页面。每一次请求一个页面都会发生数据库操作。但连接数据库却是一个需要消耗大量时间的工作,因为请求连接需要建立通讯,分配资源,进行权限认证。这些工作很少能在一两秒内完成。所以,建立一个连接,然后再后续的查询中都使用此连接会大大地提高性能。因为servlet可以在不同的请求间保持状态,因此采用数据库连接池是一个直接的解决方案。   Servlet在服务器的进程空间中驻留,可以方便而持久地维护数据库连接。接下来,我们介绍一个完整的连接池的实现。在实现中,有一个

sky2line的专栏 1164

2025华东杯A/B/C题解题思路+可运行代码参考

这些因素包括但不限于:助滑坡的坡度、运动员的质量、滑雪板的接触面与雪地的摩擦力、空气阻力系数、运动员的体型和衣物形态等。助滑坡是运动员滑行至起跳台前的最后一段坡道,这一段坡道的坡度、长度和运动员的姿势会直接影响到起跳时的初始速度。运动员的滑行速度不仅受助滑坡的坡度影响,还受到摩擦力、空气阻力和重力等多方面因素的影响。通过合理的姿势调整,运动员能够有效减少空气阻力,增加身体的重力加速度,进而提升滑行速度。助滑坡的角度通常介于10°到12°之间,而运动员的滑行速度将受到重力、摩擦力和空气阻力的共同作用。

qq_52590045的博客 1799

ROS通信机制深度解析:为什么话题订阅模型比服务调用更适合你的机器人项目?

本文深入解析ROS通信机制,重点探讨话题订阅模型相较于服务调用在机器人项目中的优势。通过性能对比和架构分析,揭示话题模型在异步通信、系统解耦和实时数据处理方面的卓越表现,特别适合传感器数据流和高频控制场景。文章还提供了实际案例和高级应用技巧,帮助开发者优化机器人系统设计。

weixin_29172963的博客 100

【Java Web】JDBC 连接 MySQL 实现数据库 CRUD(增删改查)详解

本文通过完整代码演示了如何用 JDBC 操作 MySQL 实现增删改查,并配合流程图、表结构图解释了其执行过程。在实际项目中,我们应结合连接池 + PreparedStatement + DAO 封装,从而让代码更安全、更高效、更易维护。

2302_79797878的博客 1486

手把手教你 Ubuntu 24.04 离线安装 Ollama

本文介绍 Ubuntu 下离线安装 Ollama 并使用 Ollama 部署 llama3.1-70b 大模型

举世誉之而不加劝,举世非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。 1021

JavaWeb — Servlet — CRUD

list.html页面中的内容所有的双引号要替换成单引号,因为out.print("")这里有一个双引号,容易冲突。详情是需要连接数据库的,所以这个超链接点击之后也是需要执行一段java代码的。现在写完这个功能之后,你会有一种感觉,感觉开发很繁琐,只使用servlet写代码太繁琐了。使用纯粹的Servlet完成单表【对部门的】的增删改查操作。分析list.html页面中哪部分是固定死的,哪部分是需要动态展示的。向webapp中添加连接数据库的jar包(mysql驱动)这里的问号,必须是英文的问号。...

weixin_62838185的博客 573

将Windbg附加到软件进程上排查异常闪退的问题

使用Windbg和Process Explorer排查因为内存泄漏导致的软件异常闪退问题。

dvlinker的技术专栏 1万+

4.4 线上vs离线:使用 Langfuse 实现智能体的全方位无死角评估

本文介绍了如何利用Langfuse工具实现AI智能体的全方位评估,包括线上和离线两种评估方式。线上评估通过收集用户实时反馈(如点赞/点踩)来监控真实表现,而离线评估则通过创建标准化数据集进行批量测试和自动评分。文章详细演示了如何为"旅小智"AI应用添加反馈功能、创建评估数据集,并利用Langfuse SDK进行自动化评估和分析。通过这两种评估方式的结合,开发者可以建立数据驱动的AI质量保障体系,实现持续优化和版本迭代。

yonggeit的博客 3318

使用Servlet实现增删改查(CRUD)操作

insertUser方法从请求中获取用户输入的name和email,插入到数据库中。updateUser方法从请求中获取用户ID、name和email,更新数据库中的相应记录。DOCTYPE html>在Java Web开发中,Servlet是一种重要的服务器端组件,用于处理客户端的请求并生成响应。本文将介绍如何使用Servlet实现基本的增删改查(CRUD)操作,并提供示例代码和详细的分段解析。我们将实现一个名为`UserServlet`的Servlet,它可以处理用户的增删改查操作。

palitlai的博客 1443

在 SAP 里玩转 FTP:标准程序 RSFTP00x 全景解析与落地实践

摘要:SAP系统通过封装的标准FTP程序(RSFTP001-008)提供便捷的文件传输能力,适用于各类集成场景。关键点包括:1)依赖SAPFTP可执行程序和RFC目的地;2)使用RSFTP005进行前置检查并生成RFC配置;3)标准报表各司其职,如RSFTP002用于命令测试、RSFTP007/008提供参考实现;4)开发时组合FTP_CONNECT/COMMAND/DISCONNECT等函数模块。特别注意前台(SAPFTP)与后台(SAPFTPA)的环境差异,这是常见故障点。该方案通过标准化工具链显著降低

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 211

jsp+servlet+jdbc 实现crud

史上最简单的jsp+servlet+jdbc实现CRUD项目,已经经历了千锤百炼的测试与修改,健壮性一级棒!没有任何问题。而且简明易懂,内附大量注释,是不可多得的好例子。为了保证简单,甚至没有把每个servlet里的jdbc连接单独拿出来,直观。数据库也一并给出。使用本项目时,首先访问的登录页面,即:http://localhost:8080/demo1/login.jsp,用户名root,密码r

Kei's Blog 1871

sas协议(SAS PL-3)之Zoning功能

1 Zoning overview SAS zoning is implemented by a set of zoning expander devices with zoning enabled that define a zoned portion of a service delivery subsystem (ZPSDS)服务子系统. The zoning expander devices control whether a phy is permitted to participate in

sinat_37817094的博客 1534

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Jsp,Servlet连接数据库

这里我使用的是JDBC连接数据库,需要把JDBC的Jar包放到WEB-INF/lib下,Jar包点击:下载。 Jsp连接: 第一步:在使用数据库连接的jsp页面加入以下代码: 第二步:连接驱动 <!-- JDBC 驱动名及数据库 URL 数据库的用户名与密码,需要根据自己的设置 useUnicode=true&characterEncoding=utf-8 防止中文乱码,

知足常乐 4318

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

java crud_完整的CRUD——javaweb

1,总体架构index是进去的页面,可以跳转Insert的增加页面,operatePerson是根据传进来的URI来判断增删改查的页面,DbManager.java是封装的数据库操作类, Pagination.java是页脚的信息栏2,index页面final int pageSize = 5;//一页显示多少纪录int pageNum = 1;//当前页数int pageCount = 1;//...

weixin_35149268的博客 678

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

JSP Servlet JDBC MySQL CRUD 示例教程

4.输入项目名称为“jsp-servlet-jdbc-mysql-example”;集合列表、插入、更新、删除(或CURD操作-创建、更新、读取和删除)。上面的页面用于创建新用户和编辑同一用户的两种功能。8.创建用户列表JSP页面-user-list.jsp。9.创建用户表单JSP页面-user-form.jsp。创建用户列表JSP页面-user-list.jsp。创建用户表单JSP页面-user-form.jsp。作为页面控制器来处理来自客户端的所有请求。...

allway2的博客 1039

Servlet 数据库访问

是指在 Servlet 中通过 Java Database Connectivity (JDBC) API 连接和操作数据库,实现数据的增删改查(CRUD)。本教程假设您已了解 JDBC 基础,并配置好数据库驱动(如 MySQL 的 mysql-connector-java.jar)。以下以 MySQL 数据库为例,演示如何在 Servlet 中连接数据库并进行查询和插入操作。在 Servlet 中访问数据库时,中文可能出现乱码问题。:在插入中文姓名时,确保参数正确编码,即可避免乱码。防止 SQL 注入。

likuoelie的博客 888

使用Servlet做一个单表的CRUD

使用Servlet做一个单表的CRUD

欢迎阅读我的博客 490
上一篇: Servlet(五):一个Servlet处理多个请求
下一篇: Java反射机制小结和实际操作
程序员小川
博客等级 码龄10年 47粉丝 305原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值