【Java从零到架构师第二季】【09】数据库连接池_Spring JDBC_JUnit


持续学习&持续更新中…

学习态度:守破离


数据库连接池

为什么需要连接池

Dbsupdatequery方法中,如果执行数据库操作的话每次都会创建数据库连接和关闭释放数据库连接,这样会很浪费资源、耗时和降低数据库访问性能。

在这里插入图片描述

在这里插入图片描述

什么是数据库连接池

在这里插入图片描述

Druid连接池

在这里插入图片描述

链接:

https://github.com/alibaba/druid/

https://mvnrepository.com/artifact/com.alibaba/druid

使用Druid连接池

1 引入jar包

在这里插入图片描述

2 导入配置文件

在这里插入图片描述

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/my_db
username=root
password=root
initialSize=5
maxActive=10
maxWait=5000
3 代码实现(重构Dbs->Dbs2)
public final class Dbs2 {
    
    
    private Dbs2() {
    
    }

    private static DataSource DATASOURCE;

    static {
    
    
        Properties properties = new Properties();
        try (final InputStream is = Dbs2.class.getClassLoader().getResourceAsStream("druid.properties")) {
    
    
            properties.load(is);
            DATASOURCE = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    public interface RowMapper<T> {
    
    
        T generateBean(ResultSet resultSet) throws Exception;
    }

    public static <T> List<T> query(RowMapper<T> rowMapper, String sql, Object... args) {
    
    
        try (
                final PreparedStatement preparedStatement = DATASOURCE.getConnection().prepareStatement(sql)
        ) {
    
    
            for (int i = 0; i < args.length; i++) {
    
    
                preparedStatement.setObject(i + 1, args[i]);
            }

            List<T> list = new ArrayList<>();
            try (final ResultSet resultSet = preparedStatement.executeQuery()) {
    
    
                while (resultSet.next()) {
    
    
                    list.add(rowMapper.generateBean(resultSet));
                }
            } catch (Exception e) {
    
    
                e.printStackTrace();
            }
            return list;
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return null;
    }

    public static int update(String sql, Object... args) {
    
    
        try (

                final PreparedStatement preparedStatement = DATASOURCE.getConnection().prepareStatement(sql)
        ) {
    
    
            for (int i = 0; i < args.length; i++) {
    
    
                preparedStatement.setObject(i + 1, args[i]);
            }
            return preparedStatement.executeUpdate();
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return 0;
    }

}

Spring JDBC

什么是Spring JDBC

在这里插入图片描述

JdbcTemplate

在这里插入图片描述

使用JdbcTemplate重写代码

Dbs类
public final class Dbs {
    
    

    private Dbs() {
    
    
    }

    private static JdbcTemplate JDBCTEMPLATE;

    static {
    
    
        try (final InputStream is = Dbs.class.getClassLoader().getResourceAsStream("druid.properties")) {
    
    
            Properties properties = new Properties();
            properties.load(is);
            JDBCTEMPLATE = new JdbcTemplate(DruidDataSourceFactory.createDataSource(properties));
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    public static JdbcTemplate jdbcTemplate() {
    
    
        return JDBCTEMPLATE;
    }

}
CustomerDao
public class CustomerDao {
    
    
    public boolean save(Customer customer) {
    
    
        final String sql = "INSERT INTO customer(name, age, height) VALUES(?, ?, ?)";
        return Dbs.jdbcTemplate().update(sql, customer.getName(), customer.getAge(), customer.getHeight()) == 1;
    }
    
    public List<Customer> list() {
    
    
        final String sql = "SELECT id, name, age, height FROM customer";
        return Dbs.jdbcTemplate().query(sql, new BeanPropertyRowMapper<>(Customer.class));
    }
}
CustomerServlet
@WebServlet("/customer/*")
public class CustomerServlet extends HttpServlet {
    
    

    private CustomerDao customerDao;

    @Override
    public void init() {
    
    
        customerDao = new CustomerDao();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        doGet(request, response);
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    
    

        request.setCharacterEncoding("utf-8");

        final String[] split = request.getRequestURI().split("/");
        final String methodName = split[split.length - 1];
        try {
    
    
            Method method = CustomerServlet.class.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            method.invoke(this, request, response);
        } catch (Exception e) {
    
    
            try {
    
    
                Method method = CustomerServlet.class.getMethod("error", String.class, HttpServletRequest.class, HttpServletResponse.class);
                method.invoke(this, "请求页面不存在", request, response);
            } catch (Exception exception) {
    
    
                exception.printStackTrace();
            }
            e.printStackTrace();
        }
    }

    public void list(HttpServletRequest request, HttpServletResponse response) {
    
    
        final List<Customer> list = customerDao.list();
        request.setAttribute("customerSize", list.size());
        request.setAttribute("customers", list);
        try {
    
    
            request.getRequestDispatcher("../pages/list.jsp").forward(request, response);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    public void save(HttpServletRequest request, HttpServletResponse response) {
    
    
        try {
    
    
            String customerName = request.getParameter("customer_name");
            String customerAge = request.getParameter("customer_age");
            String customerHeight = request.getParameter("customer_height");

            if (
                    customerName != null && customerAge != null && customerHeight != null &&
                            !"".equals(customerName) && !"".equals(customerAge) && !"".equals(customerHeight)
            ) {
    
    
                if (customerDao.save(new Customer(
                        customerName, Integer.valueOf(customerAge), Double.valueOf(customerHeight)
                ))) {
    
    
                    response.sendRedirect("/eight_springjdbc/customer/list");
                } else {
    
    
                    error("数据保存失败", request, response);
                }
            } else {
    
    
                error("用户输入非法值", request, response);
            }
        } catch (Exception e) {
    
    
            error("用户输入非法值", request, response);
            e.printStackTrace();
        }
    }

    public void error(String error, HttpServletRequest request, HttpServletResponse response) {
    
    
        try {
    
    
            request.setAttribute("error", error);
            request.getRequestDispatcher("../pages/error.jsp").forward(request, response);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

}

使用beanutils框架

引入jar包

需要使用如下jar包:

在这里插入图片描述

代码实现

    // 使用beanutils框架生成Bean对象
    private Customer newCustomer(HttpServletRequest request) {
    
    
        Customer customer = new Customer();
        try {
    
    
            BeanUtils.populate(customer, request.getParameterMap());
        } catch (Exception e) {
    
    
            return null;
        }
        return customer;
    }

JUnit

什么是JUnit

在这里插入图片描述

常用注解

在这里插入图片描述

Assert常用方法

在这里插入图片描述

代码实现

首先引入jar包

在这里插入图片描述

假设我们现在需要测试CustomerDao

那么进行如下操作(在自动生成的test包下新建CustomerDaoTest):

在这里插入图片描述

public class CustomerDaoTest {
    
    
    private static CustomerDao dao;

    @Before
    public void before() {
    
    
        System.out.println("before");
    }

    @After
    public void after() {
    
    
        System.out.println("after");
    }

    @BeforeClass
    public static void beforeClass() {
    
    
        dao = new CustomerDao();
        System.out.println("beforeClass");
    }

    @AfterClass
    public static void afterClass() {
    
    
        System.out.println("afterClass");
    }


    @Test
    public void testSave() {
    
    
        Customer customer = new Customer();
        customer.setName("张武");
        customer.setRealAge(20);
        customer.setHeight(1.89);

        Assert.assertTrue(dao.save(customer));
    }

    @Test
    public void testList() {
    
    
        List<Customer> customers = dao.list();
        Assert.assertTrue(customers.size() > 0);
    }

    @Test
    public void testRemove() {
    
    
        // ......
    }

    @Test
    public void testUpdate() {
    
    
        // ......
    }

    // ......

}

实现crms小项目的增删改查

CustomerServlet

@WebServlet("/customer/*")
public class CustomerServlet extends HttpServlet {
    
    

    private CustomerDao customerDao;

    @Override
    public void init() {
    
    
        customerDao = new CustomerDao();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        doGet(request, response);
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    
    

        request.setCharacterEncoding("utf-8");

        final String[] split = request.getRequestURI().split("/");
        final String methodName = split[split.length - 1];
        try {
    
    
            Method method = CustomerServlet.class.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            method.invoke(this, request, response);
        } catch (Exception e) {
    
    
            try {
    
    
                Method method = CustomerServlet.class.getMethod("error", String.class, HttpServletRequest.class, HttpServletResponse.class);
                method.invoke(this, "请求页面不存在", request, response);
            } catch (Exception exception) {
    
    
                exception.printStackTrace();
            }
            e.printStackTrace();
        }
    }

    public void list(HttpServletRequest request, HttpServletResponse response) {
    
    
        final List<Customer> list = customerDao.list();
        request.setAttribute("customerSize", list.size());
        request.setAttribute("customers", list);
        try {
    
    
            request.getRequestDispatcher("../pages/list.jsp").forward(request, response);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    public void save(HttpServletRequest request, HttpServletResponse response) {
    
    
        try {
    
    
            Customer customer = newCustomer(request);
            if (null != customer) {
    
    
                if (customerDao.save(customer)) {
    
    
                    response.sendRedirect("/eight_springjdbc/customer/list");
                } else {
    
    
                    error("客户添加失败", request, response);
                }
            } else {
    
    
                error("用户非法输入", request, response);
            }
        } catch (Exception e) {
    
    
            error("客户添加失败", request, response);
            e.printStackTrace();
        }
    }

    public void edit(HttpServletRequest request, HttpServletResponse response) {
    
    
        try {
    
    
            String customerId = request.getParameter("id");
            if (customerId != null && !"".equals(customerId)) {
    
    
                final Integer id = Integer.valueOf(customerId);
                final Customer customer = customerDao.edit(id);

                try {
    
    
                    request.setAttribute("customer", customer);
                    request.getRequestDispatcher("../pages/edit.jsp").forward(request, response);
                } catch (Exception e) {
    
    
                    e.printStackTrace();
                    error("数据编辑失败", request, response);
                }
            }
        } catch (Exception e) {
    
    
            error("数据编辑失败", request, response);
            e.printStackTrace();
        }
    }

    public void update(HttpServletRequest request, HttpServletResponse response) {
    
    
        try {
    
    
            Customer customer = newCustomer(request);
            String customerId = request.getParameter("customer_id");
            if (null != customer) {
    
    
                customer.setId(Integer.valueOf(customerId));
                if (customerDao.update(customer)) {
    
    
                    response.sendRedirect("/eight_springjdbc/customer/list");
                } else {
    
    
                    error("数据更新失败", request, response);
                }
            } else {
    
    
                error("用户输入非法值", request, response);
            }
        } catch (Exception e) {
    
    
            error("数据更新失败", request, response);
            e.printStackTrace();
        }
    }

    public void remove(HttpServletRequest request, HttpServletResponse response) {
    
    
        try {
    
    
            String customerId = request.getParameter("id");
            if (customerId != null && !"".equals(customerId)) {
    
    
                final Integer id = Integer.valueOf(customerId);
                if (customerDao.remove(id)) {
    
    
                    response.sendRedirect("/eight_springjdbc/customer/list");
                } else {
    
    
                    error("数据删除失败", request, response);
                }
                System.out.println(id);
            }
        } catch (Exception e) {
    
    
            error("数据删除失败", request, response);
            e.printStackTrace();
        }
    }

    private void error(String error, HttpServletRequest request, HttpServletResponse response) {
    
    
        try {
    
    
            request.setAttribute("error", error);
            request.getRequestDispatcher("../pages/error.jsp").forward(request, response);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    // 使用beanutils框架生成Bean对象
    private Customer newCustomer(HttpServletRequest request) {
    
    
        Customer customer = new Customer();
        try {
    
    
            BeanUtils.populate(customer, request.getParameterMap());
        } catch (Exception e) {
    
    
            return null;
        }
        return customer;
    }

//    private Customer newCustomer(HttpServletRequest request) {
    
    
//        String customerName = request.getParameter("customer_name");
//        String customerAge = request.getParameter("customer_age");
//        String customerHeight = request.getParameter("customer_height");
//        if (
//                customerName != null && customerAge != null && customerHeight != null &&
//                        !"".equals(customerName) && !"".equals(customerAge) && !"".equals(customerHeight)
//        ) {
    
    
//            return new Customer(
//                    customerName, Integer.valueOf(customerAge), Double.valueOf(customerHeight)
//            );
//        }
//        return null;
//    }

}

CustomerDao

public class CustomerDao {
    
    

    public boolean update(Customer customer) {
    
    
        final String sql = "UPDATE customer SET name=?, age=?, height=? WHERE ID = ?";
        return 1 == Dbs.jdbcTemplate().update(sql, customer.getName(), customer.getAge(), customer.getHeight(), customer.getId());
    }

    public boolean save(Customer customer) {
    
    
        final String sql = "INSERT INTO customer(name, age, height) VALUES(?, ?, ?)";
        return Dbs.jdbcTemplate().update(sql, customer.getName(), customer.getAge(), customer.getHeight()) == 1;
    }

    public boolean remove(Integer id) {
    
    
        final String sql = "DELETE FROM customer WHERE id = ?";
        return Dbs.jdbcTemplate().update(sql, id) == 1;
    }

    public Customer edit(Integer id) {
    
    
        final String sql = "SELECT id, name, age, height FROM customer WHERE id = ?";
//        return Dbs.jdbcTemplate().query(sql, new BeanPropertyRowMapper<>(Customer.class), id).get(0);
        return Dbs.jdbcTemplate().queryForObject(sql, new BeanPropertyRowMapper<>(Customer.class), id);
    }

    public List<Customer> list() {
    
    
        final String sql = "SELECT id, name, age, height FROM customer";
        return Dbs.jdbcTemplate().query(sql, new BeanPropertyRowMapper<>(Customer.class));
    }

//    public List<Customer> list() {
    
    
//        final String sql = "SELECT id, name, age, height FROM customer";
//        return DbsUsingSpringJDBC.jdbcTemplate().query(sql, (resultSet, row) -> {
    
    
//            System.out.println("表中的第" + row + "行记录");
//
//            final Integer id = resultSet.getInt("id");
//            final String name = resultSet.getString("name");
//            final Integer age = resultSet.getInt("age");
//            final Double height = resultSet.getDouble("height");
//            return new Customer(id, name, age, height);
//        });
//    }

}

Dbs

public final class Dbs {
    
    

    private Dbs() {
    
    }

    private static JdbcTemplate JDBCTEMPLATE;

    static {
    
    
        try (final InputStream is = Dbs.class.getClassLoader().getResourceAsStream("druid.properties")) {
    
    
            Properties properties = new Properties();
            properties.load(is);
            JDBCTEMPLATE = new JdbcTemplate(DruidDataSourceFactory.createDataSource(properties));
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    public static JdbcTemplate jdbcTemplate() {
    
    
        return JDBCTEMPLATE;
    }

}

list.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>list</title>
    <style>
        table, tr, th, td {
      
      
            border: 1px solid black;
            width: 500px;
            text-align: center;
        }
    </style>
</head>
<body>
<h1 style="color: green">总共有${customerSize}个客户</h1>
<table>
    <tr>
        <th>姓名</th>
        <th>年龄</th>
        <th>身高</th>
    </tr>

    <c:forEach items="${customers}" var="customer">
        <tr>
            <td>${customer.name}</td>
            <td>${customer.age}</td>
            <td>${customer.height}</td>
            <td><a href="/eight_springjdbc/customer/edit?id=${customer.id}">编辑</a></td>
            <td><a href="/eight_springjdbc/customer/remove?id=${customer.id}">删除</a></td>
        </tr>
    </c:forEach>


</table>

<br>
<a href="/eight_springjdbc/pages/save.html">添加客户</a>

</body>
</html>

save.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>save</title>
</head>
<body>

<form action="/eight_springjdbc/customer/save" method="post">
    <div>姓名:<input type="text" name="customer_name"></div>
    <div>年龄:<input type="number" name="customer_age"></div>
    <div>身高:<input type="text" name="customer_height"></div>
    <div>
        <button type="submit">保存</button>
    </div>
</form>

</body>
</html>

edit.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>update</title>
</head>
<body>
<form action="/eight_springjdbc/customer/update" method="post">
    <%--    <div style="height: 0; display: none;"><input type="text" name="customer_id" value="${customer.id}"></div>--%>
    <div><input type="hidden" name="customer_id" value="${customer.id}"></div>
    <div>姓名:<input type="text" name="customer_name" value="${customer.name}"></div>
    <div>年龄:<input type="number" name="customer_age" value="${customer.age}"></div>
    <div>身高:<input type="text" name="customer_height" value="${customer.height}"></div>
    <div>
        <button type="submit">保存</button>
    </div>
</form>
</body>
</html>

error.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>error</title>
    <style>
        html, body, h1 {
      
      
            color: red;
            text-align: center;
        }
    </style>
</head>
<body>
<h1>${error}</h1>

<br>
<br>
<a href="/eight_springjdbc/customer/list">返回用户页面</a>
</body>
</html>

一些细节和注意

  • Java中使用小驼峰命名法realAge,数据库中使用下划线命名法real_age,是业界认可的编码标准,SpringJDBC框架已经在内部帮我们做好了相关映射。

参考

李明杰: Java从0到架构师②JavaEE技术基石.


本文完,感谢您的关注支持!


猜你喜欢

转载自blog.csdn.net/weixin_44018671/article/details/120815642