JAVA——J2EE之Servlet(三) 增删改查CRUD

CRUD是常见的页面功能,即我们常说的增删改查
C - Creation 增加
R - Retrieve 查询
U - Update 修改
D - DELETE 删除

与JDBC结合,通过servlet查询数据库,根据查询结果,得到一个html页面,显示数据库中的内容。
本例借助JDBC的Hero类和HeroDAO类进行数据库查询

一、查询

1.准备实体类Hero

package bean;
public class Hero {
    public int id;
    public String name;
    public float hp;
    public int damage;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public float getHp() {
        return hp;
    }
    public void setHp(float hp) {
        this.hp = hp;
    }
    public int getDamage() {
        return damage;
    }
    public void setDamage(int damage) {
        this.damage = damage;
    }

}

准备DAO 类 HeroDAO
准备一个HeroDAO,提供增加,删除,修改,查询等常规数据库操作方法

package dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import bean.Hero;

public class HeroDAO {

    public HeroDAO() {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public Connection getConnection() throws SQLException {
        return DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8", "root",
                "admin");
    }

    public int getTotal() {
        int total = 0;
        try (Connection c = getConnection(); Statement s = c.createStatement();) {

            String sql = "select count(*) from hero";

            ResultSet rs = s.executeQuery(sql);
            while (rs.next()) {
                total = rs.getInt(1);
            }

            System.out.println("total:" + total);

        } catch (SQLException e) {

            e.printStackTrace();
        }
        return total;
    }

    public void add(Hero hero) {

        String sql = "insert into hero values(null,?,?,?)";
        try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {

            ps.setString(1, hero.name);
            ps.setFloat(2, hero.hp);
            ps.setInt(3, hero.damage);

            ps.execute();

            ResultSet rs = ps.getGeneratedKeys();
            if (rs.next()) {
                int id = rs.getInt(1);
                hero.id = id;
            }
        } catch (SQLException e) {

            e.printStackTrace();
        }
    }

    public void update(Hero hero) {

        String sql = "update hero set name= ?, hp = ? , damage = ? where id = ?";
        try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {

            ps.setString(1, hero.name);
            ps.setFloat(2, hero.hp);
            ps.setInt(3, hero.damage);
            ps.setInt(4, hero.id);

            ps.execute();

        } catch (SQLException e) {

            e.printStackTrace();
        }

    }

    public void delete(int id) {

        try (Connection c = getConnection(); Statement s = c.createStatement();) {

            String sql = "delete from hero where id = " + id;

            s.execute(sql);

        } catch (SQLException e) {

            e.printStackTrace();
        }
    }

    public Hero get(int id) {
        Hero hero = null;

        try (Connection c = getConnection(); Statement s = c.createStatement();) {

            String sql = "select * from hero where id = " + id;

            ResultSet rs = s.executeQuery(sql);

            if (rs.next()) {
                hero = new Hero();
                String name = rs.getString(2);
                float hp = rs.getFloat("hp");
                int damage = rs.getInt(4);
                hero.name = name;
                hero.hp = hp;
                hero.damage = damage;
                hero.id = id;
            }

        } catch (SQLException e) {

            e.printStackTrace();
        }
        return hero;
    }

    public List list() {
        return list(0, Short.MAX_VALUE);
    }

    public List list(int start, int count) {
        List heros = new ArrayList();

        String sql = "select * from hero order by id desc limit ?,? ";

        try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {

            ps.setInt(1, start);
            ps.setInt(2, count);

            ResultSet rs = ps.executeQuery();

            while (rs.next()) {
                Hero hero = new Hero();
                int id = rs.getInt(1);
                String name = rs.getString(2);
                float hp = rs.getFloat("hp");
                int damage = rs.getInt(4);
                hero.id = id;
                hero.name = name;
                hero.hp = hp;
                hero.damage = damage;
                heros.add(hero);
            }
        } catch (SQLException e) {

            e.printStackTrace();
        }
        return heros;
    }

}

2.创建表Hero的SQL

DROP TABLE IF EXISTS `hero`;

CREATE TABLE `hero` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) DEFAULT NULL,
  `hp` float DEFAULT NULL,
  `damage` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

3.为web应用导入mysql-jdbc的jar包(很关键)

为web应用导入mysql-jdbc的jar包与为项目导入mysql-jdbc的jar包不同,其作用的web应用在tomcat中运行起来后,能够找到jar包中的类。
所以需要把 mysq的jar包放在WEB-INF/lib 目录下。
注: 放在WEB-INF/lib 下指的是能够web应用中找到对应的class,如果要在eclipse中做调试,还是需要为项目添加该jar才可以。

4.编写 HeroListServlet

做一个Hero的维护页面需要一些通用的操作,比如增加,删除,编辑,修改,查询等。

每个不同的操作,都需要一个对应的Servlet,除了做Hero之外,还会做到其他的一些表的相关操作,所以好的规范会对将来的维护更有好处。

一般会这样命名,以查询为例 HeroListServlet : [表][行为]Servlet 这样一种命名规则。

所以对于Hero而言就会如此命名:
增加 HeroAddServlet
删除 HeroDeleteServlet
编辑 HeroEditServlet
修改 HeroUpdateServlet
查询 HeroListServlet

在HeroListServlet中,会使用HeroDAO把数据查询出来,然后拼接成一个table用于显示其内容


public class HeroListServlet extends HttpServlet {

    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html; charset=UTF-8");

        List heros = new HeroDAO().list();

        StringBuffer sb = new StringBuffer();
        sb.append("\r\n");
        sb.append("\r\n");

        String trFormat = "\r\n";

        for (Hero hero : heros) {
            String tr = String.format(trFormat, hero.getId(), hero.getName(), hero.getHp(), hero.getDamage());
            sb.append(tr);
        }

        sb.append("
idnamehpdamage
%d%s%f%d
"
); response.getWriter().write(sb.toString()); } }

5、在web.xml中把路径 listHero映射到HeroListServlet上

<servlet>
        <servlet-name>HeroListServletservlet-name>
        <servlet-class>servlet.HeroListServletservlet-class>
    servlet>

    <servlet-mapping>
        <servlet-name>HeroListServletservlet-name>
        <url-pattern>/listHerourl-pattern>
    servlet-mapping> 

重启tomcat,访问

http://127.0.0.1/listHero

二、增加

1.准备增加的页面 addHero.html

在web目录下增加addHero.html

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

表示用UTF-8显示中文,同时浏览器也会使用UTF-8编码提交中文

form:
action设置为addHero路径
method设置为post 也是为了提交中文

2.编写 HeroAddServlet

HeroAddServlet 中根据浏览器传过来的参数创建一个Hero对象。 接着通过HeroDAO把该对象保存到数据库中
最后使用客户端跳转到listHero查看所有的Hero,就能看到新加入的Hero对象了

request.setCharacterEncoding("UTF-8");

表示使用UTF-8的方式获取浏览器传过来的中文

public class HeroAddServlet extends HttpServlet {

    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");

        Hero hero = new Hero();
        hero.setName(request.getParameter("name"));
        hero.setHp(Float.parseFloat(request.getParameter("hp")));
        hero.setDamage(Integer.parseInt(request.getParameter("damage")));

        new HeroDAO().add(hero);

        response.sendRedirect("/listHero");

    }
}

在web.xml中设置路径addHero对应HeroAddServlet

    <servlet>
        <servlet-name>HeroAddServletservlet-name>
        <servlet-class>servlet.HeroAddServletservlet-class>
    servlet>

    <servlet-mapping>
        <servlet-name>HeroAddServletservlet-name>
        <url-pattern>/addHerourl-pattern>
    servlet-mapping>

重启tomcat,访问增加页面

http://127.0.0.1/addHero.html

提交数据,接着客户端跳转到/listHero,就可以显示新增加的这条数据了

三、删除

1.修改HeroListServlet

提供delete超连接
修改HeroLIstServlet,多一个单元格,是一个超链

超链的href属性指向地址 /deleteHero?id=217(每条不同的记录id不一样)

public class HeroListServlet extends HttpServlet {

    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html; charset=UTF-8");

        List<Hero> heros = new HeroDAO().list();

        StringBuffer sb = new StringBuffer();
        sb.append("<table align='center' border='1' cellspacing='0'>\r\n");
        sb.append("<tr><td>idtd><td>nametd><td>hptd><td>damagetd><td>deletetd>tr>\r\n");

        String trFormat = "<tr><td>%dtd><td>%std><td>%ftd><td>%dtd><td><a href='deleteHero?id=%d'>deletea>td>tr>\r\n";

        for (Hero hero : heros) {
            String tr = String.format(trFormat, hero.getId(), hero.getName(), hero.getHp(), hero.getDamage(),hero.getId());
            sb.append(tr);
        }

        sb.append("table>");

        response.getWriter().write(sb.toString());

    }
}

2.配置web.xml

    <servlet>
        <servlet-name>HeroDeleteServletservlet-name>
        <servlet-class>servlet.HeroDeleteServletservlet-class>
    servlet>

    <servlet-mapping>
        <servlet-name>HeroDeleteServletservlet-name>
        <url-pattern>/deleteHerourl-pattern>
    servlet-mapping

3.编写HeroDeleteServlet

public class HeroDeleteServlet extends HttpServlet {

    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        int id = Integer.parseInt(request.getParameter("id"));

        new HeroDAO().delete(id);

        response.sendRedirect("/listHero");

    }
}

四、编辑

1.修改HeroListServlet

新增加一列 edit,里面放上指向 /editHero的超链

public class HeroListServlet extends HttpServlet {

    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html; charset=UTF-8");

        List<Hero> heros = new HeroDAO().list();

        StringBuffer sb = new StringBuffer();
        sb.append("<table align='center' border='1' cellspacing='0'>\r\n");
        sb.append("<tr><td>idtd><td>nametd><td>hptd><td>damagetd><td>edittd><td>deletetd>tr>\r\n");

        String trFormat = "<tr><td>%dtd><td>%std><td>%ftd><td>%dtd><td><a href='editHero?id=%d'>edita>td><td><a href='deleteHero?id=%d'>deletea>td>tr>\r\n";

        for (Hero hero : heros) {
            String tr = String.format(trFormat, hero.getId(), hero.getName(), hero.getHp(), hero.getDamage(),hero.getId(),hero.getId());

            sb.append(tr);
        }

        sb.append("table>");

        response.getWriter().write(sb.toString());

    }
}

2.配置xml

在web.xml中把 /editHero路径映射到 HeroEditServlet类上

3.准备HeroEditServlet

HeroEditServlet 根据浏览器传过来的id获取一个hero对象
然后根据这个hero对象,准备一个类似add.html的页面,不同之处在于每个输入框都是有值的。
最后还会提供一个type=”hidden”的input,用于提交id到路径/updateHero

public class HeroEditServlet extends HttpServlet {

    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        int id = Integer.parseInt(request.getParameter("id"));

        Hero hero = new HeroDAO().get(id);

        StringBuffer format = new StringBuffer();
        response.setContentType("text/html; charset=UTF-8");

        format.append("");

        format.append("<form action='updateHero' method='post'>");
        format.append("名字 : <input type='text' name='name' value='%s' > <br>");
        format.append("血量 : <input type='text' name='hp'  value='%f' > <br>");
        format.append("伤害: <input type='text' name='damage'  value='%d' > <br>");
        format.append("<input type='hidden' name='id' value='%d'>");
        format.append("<input type='submit' value='更新'>");
        format.append("form>");

        String html = String.format(format.toString(), hero.getName(), hero.getHp(), hero.getDamage(), hero.getId());

        response.getWriter().write(html);

    }
}

编辑完了是不显示的,要显示通过更新。重新访问listHero

五、更新

1.编写 HeroUpdateServlet

HeroUpdateServlet
根据浏览器提交的id name hp damage创建一个Hero对象
然后调用HeroDAO的update,进行更新数据库里的内容

更新结束后,客户端跳转到 /listHero,访问数据库,显示内容

public class HeroUpdateServlet extends HttpServlet {

    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");

        Hero hero = new Hero();
        hero.setId(Integer.parseInt(request.getParameter("id")));
        hero.setName(request.getParameter("name"));
        hero.setHp(Float.parseFloat(request.getParameter("hp")));
        hero.setDamage(Integer.parseInt(request.getParameter("damage")));

        new HeroDAO().update(hero);

        response.sendRedirect("/listHero");

    }
}

六、弊端

用到这里,大家对使用Servlet进行CRUD开发就有比较全面感性认识了。 其中一个比较明显的弊端就是在Servlet编写html代码很痛苦,效率不高,可读性差,难以维护。

最好可以在html文件里面写html代码,同时又能在里面调用java的变量,那么这样就需要学习JSP了。

你可能感兴趣的:(Servlet)