目录

Life in Flow

知不知,尚矣;不知知,病矣。
不知不知,殆矣。

X

JDBC

JDBC

  • 全称 Java DataBase Connectivity, 是 Java 语言中用来规范客户端程序如何来访问数据库的应用程序接口
  • 提供了一种接口基准,可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序
  • 应用程序代码一般不能直接访问数据库,需要通过相应的数据库驱动程序才行,
  • 数据库驱动就是数据库厂商对 JDBC 接口的实现

JDBC

JDBC 连接 MySQL 相关概念

  • 数据库驱动:不同数据库开发商(比如 Oracle MySQL 等)为了某一种开发语言能够实现统一的数据库调用而开发的一个程序, 作用相当于一个翻译人员, 将某个语言(比如 Java)中对数据库的调用通过这个翻译成各个种类的数据库 自己的数据库语言
  • Connection 连接:特定数据库的连接(会话),在连接上下文中执行 SQL 语句并返回结果
  • Statement 语句: 创建执行 SQL 语句的 statement, 有好几种实现类,用于执行对应的 SQL
  • ResultSet 结果集:SQL 查询返回的结果信息

使用 Java 连接 MySQL 的步骤

  • 加载 JDBC 驱动程序
  • 建立数据库连接 Connection
  • 创建执行 SQL 的语句 Statement
  • 处理执行结果 ResultSet
  • 释放连接资源

驱动包导入和数据库准备

https://abc1024.oss-cn-shanghai.aliyuncs.com/Picture/Javaweb/mysql-connector-java-5.1.46.jar

数据库表

 1CREATE TABLE `user` (
 2  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 3  `phone` varchar(32) DEFAULT NULL,
 4  `pwd` varchar(128) DEFAULT NULL,
 5  `sex` int(2) DEFAULT NULL,
 6  `img` varchar(128) DEFAULT NULL,
 7  `create_time` datetime DEFAULT NULL,
 8  `role` int(11) DEFAULT NULL COMMENT '1是普通用户,2是管理员',
 9  `username` varchar(128) DEFAULT NULL,
10  `wechat` varchar(128) DEFAULT NULL,
11  PRIMARY KEY (`id`)
12) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
13
14
15INSERT INTO `user` (`id`, `phone`, `pwd`, `sex`, `img`, `create_time`, `role`, `username`,`wechat`)
16VALUES
17    (1,'123','666',1,'xdclass.net','2021-09-09 00:00:00',1,'jack','xdclass6'),
18    (2,'2323432','794666918',1,'wwwww','2020-05-20 04:54:01',1,'小滴Anna姐姐','xdclass-anna'),
19    (3,'2323432','xdclass-lw',1,'wwwww','2020-05-20 04:54:42',1,'二当家小D','xdclass1'),
20    (4,'2323432','3232323',1,'wwwww','2020-05-20 04:55:07',1,'老王','xdclass-lw');

编写一个 JDBC 程序

 1public class JDBCTest {
 2    public static void main(String[] args) throws ClassNotFoundException, SQLException {
 3        //加载驱动
 4        Class.forName("com.mysql.jdbc.Driver");
 5
 6        //建立数据库连接Connection
 7        String name = "root";
 8        String password = "123456";
 9            //协议:子协议://ip:端口/数据库名称?参数1=值1&参数2=值2
10        String url = "jdbc:mysql://192.168.31.101:50000/test?useUnicode=true&characterEncoding=utf-8&useSSL=false";
11        Connection connection = DriverManager.getConnection(url, name, password);
12
13        //创建执行SQL的语句Statement
14        Statement statement = connection.createStatement();
15
16        //处理执行结果ResultSet
17        ResultSet resultSet = statement.executeQuery("select * from user");
18        while (resultSet.next()) {
19            System.out.println("用户名称 name="+ resultSet.getString("username") +
20                    "  联系方式 wechat="+ resultSet.getString("wechat"));
21        }
22
23        //释放连接
24        resultSet.close();
25        statement.close();
26        connection.close();
27    }
28}

SQL 注入攻击和 Statement 预编译语句

  • 什么是 SQL 注入攻击

    • 可以执行恶意 SQL 语句,将任意 SQL 代码插入数据库查询,使用 SQL 注入来添加,修改和删除数据库中的记录
  • PrepareStatement

    • 字面可译为预声明,内部包含一个预编译的 SQL 语句,参数采用占位符 ? 进行填充
    • 为啥可以防注入
      • 第一次操作数据库之前,SQL 语句已经被数据库分析和编译,对应的执行计划也会缓存下来,之后数据库就会以参数化的形式进行查询
      • 传入的值始终都是会作为一个值,而不是 SQL 指令
  • 好处:维护性好、提高 SQL 效率、增加安全性

  1public class JDBCTest {
  2
  3
  4    public static void main(String [] args) throws Exception{
  5
  6         //加载JDBC驱动程序
  7//         Class.forName("com.mysql.jdbc.Driver");
  8//
  9//         //建立数据库连接Connection
 10//        String username = "root";
 11//        String password = "xdclass.net";
 12//        //协议:子协议://ip:端口/数据库名称?参数1=值1&参数2=值2
 13//        String url = "jdbc:mysql://127.0.0.1:3306/xd_web?useUnicode=true&characterEncoding=utf-8&useSSL=false";
 14//
 15//        Connection connection = DriverManager.getConnection(url,username,password);
 16//
 17//         //创建执行SQL的语句Statement
 18//        Statement statement  = connection.createStatement();
 19//
 20//         //处理执行结果ResultSet
 21//        ResultSet resultSet = statement.executeQuery("select * from user");
 22//
 23//
 24//
 25//        while (resultSet.next()){
 26//
 27//            System.out.println("用户名称 name="+ resultSet.getString("username") + "  联系方式 wechat="+ resultSet.getString("wechat"));
 28//        }
 29//
 30//        //释放连接资源
 31//        statement.close();
 32//        connection.close();
 33
 34        testInjectSQL();
 35
 36
 37    }
 38
 39
 40
 41
 42  //攻击的例子
 43
 44//    private static  void  testInjectSQL()throws Exception{
 45//        //加载JDBC驱动程序
 46//        Class.forName("com.mysql.jdbc.Driver");
 47//
 48//        //建立数据库连接Connection
 49//        String username = "root";
 50//        String password = "xdclass.net";
 51//        //协议:子协议://ip:端口/数据库名称?参数1=值1&参数2=值2
 52//        String url = "jdbc:mysql://127.0.0.1:3306/xd_web?useUnicode=true&characterEncoding=utf-8&useSSL=false";
 53//
 54//        Connection connection = DriverManager.getConnection(url,username,password);
 55//
 56//        //创建执行SQL的语句Statement
 57//        Statement statement  = connection.createStatement();
 58//
 59//        String name = "jack";
 60//
 61//        String pwd = "666' or 1=1 or'";
 62//
 63//        String sql = "select * from user where username='"+name +"' and pwd='"+pwd +"'";
 64//
 65//        System.out.println(sql);
 66//
 67//        //处理执行结果ResultSet
 68//        ResultSet resultSet = statement.executeQuery(sql);
 69//
 70//
 71//        while (resultSet.next()){
 72//
 73//            System.out.println("用户名称 name="+ resultSet.getString("username") + "  联系方式 wechat="+ resultSet.getString("wechat"));
 74//        }
 75//
 76//        //释放连接资源
 77//        statement.close();
 78//        connection.close();
 79//    }
 80
 81
 82    /**
 83     * 防止攻击的例子
 84     * @throws Exception
 85     */
 86    private static  void  testInjectSQL()throws Exception{
 87        //加载JDBC驱动程序
 88        Class.forName("com.mysql.jdbc.Driver");
 89
 90        //建立数据库连接Connection
 91        String username = "root";
 92        String password = "xdclass.net";
 93        //协议:子协议://ip:端口/数据库名称?参数1=值1&参数2=值2
 94        String url = "jdbc:mysql://127.0.0.1:3306/xd_web?useUnicode=true&characterEncoding=utf-8&useSSL=false";
 95
 96        Connection connection = DriverManager.getConnection(url,username,password);
 97
 98        String name = "jack";
 99
100        String pwd = "666 or 1=1 ";
101
102        //创建执行SQL的语句Statement
103        PreparedStatement preparedStatement  = connection.prepareStatement("select * from user where username=? and pwd=?");
104
105        preparedStatement.setString(1,name);
106        preparedStatement.setString(2,pwd);
107
108
109        //处理执行结果ResultSet
110        ResultSet resultSet = preparedStatement.executeQuery();
111
112        while (resultSet.next()){
113
114            System.out.println("用户名称 name="+ resultSet.getString("username") + "  联系方式 wechat="+ resultSet.getString("wechat"));
115        }
116
117        //释放连接资源
118        preparedStatement.close();
119        connection.close();
120    }
121
122
123    }

增删功能

 1private static void testAdd() throws Exception {
 2        //加载JDBC驱动程序
 3        Class.forName("com.mysql.jdbc.Driver");
 4
 5        //建立数据库连接Connection
 6        String username = "root";
 7        String password = "xdclass.net";
 8        //协议:子协议://ip:端口/数据库名称?参数1=值1&参数2=值2
 9        String url = "jdbc:mysql://127.0.0.1:3306/xd_web?useUnicode=true&characterEncoding=utf-8&useSSL=false";
10
11        Connection connection = DriverManager.getConnection(url, username, password);
12
13        PreparedStatement preparedStatement = connection.prepareStatement("insert into  user(username, pwd,sex,role,create_time) values(?,?,?,?,?) ");
14
15        preparedStatement.setString(1,"二当家小D");
16        preparedStatement.setString(2,"123456");
17        preparedStatement.setInt(3,1);
18        preparedStatement.setInt(4,2);
19        preparedStatement.setTimestamp(5,new Timestamp(System.currentTimeMillis()));
20
21        //执行
22        preparedStatement.execute();
23
24        preparedStatement.close();
25        connection.close();
26
27
28
29
30    }
31
32
33    private static void testDelete() throws Exception {
34        //加载JDBC驱动程序
35        Class.forName("com.mysql.jdbc.Driver");
36
37        //建立数据库连接Connection
38        String username = "root";
39        String password = "xdclass.net";
40        //协议:子协议://ip:端口/数据库名称?参数1=值1&参数2=值2
41        String url = "jdbc:mysql://127.0.0.1:3306/xd_web?useUnicode=true&characterEncoding=utf-8&useSSL=false";
42
43        Connection connection = DriverManager.getConnection(url, username, password);
44
45        PreparedStatement preparedStatement = connection.prepareStatement("delete  from user where  id=?");
46
47        preparedStatement.setInt(1,2);
48
49        //执行
50        preparedStatement.execute();
51
52        preparedStatement.close();
53        connection.close();
54
55
56    }

JDBC 控制 MySQL 事务

  • 事务:

    • 一个最小的不可再分的工作单元,通常一个事务对应一个完整的业务
    • 例如银行账户转账业务,该业务就是一个最小的工作单元
  • 四大特性

    • 原子性(A):事务是最小单位,不可再分
    • 一致性(C):事务要求所有的 DML 语句操作的时候,必须保证同时成功或者同时失败
    • 隔离性(I):事务 A 和事务 B 之间具有隔离性
    • 持久性(D):是事务的保证,事务终结的标志(内存的数据持久到硬盘文件中)
  • 事务的一些术语

    • 开启事务:Start Transaction
    • 事务结束:End Transaction
    • 提交事务:Commit Transaction
    • 回滚事务:Rollback Transaction
  • JDBC 事务控制实操

 1private static void testTransaction() throws Exception {
 2        //加载JDBC驱动程序
 3        Class.forName("com.mysql.jdbc.Driver");
 4
 5        //建立数据库连接Connection
 6        String username = "root";
 7        String password = "xdclass.net";
 8        //协议:子协议://ip:端口/数据库名称?参数1=值1&参数2=值2
 9        String url = "jdbc:mysql://127.0.0.1:3306/xd_web?useUnicode=true&characterEncoding=utf-8&useSSL=false";
10
11        Connection connection = DriverManager.getConnection(url, username, password);
12
13            try (
14                PreparedStatement ps1 = connection.prepareStatement("insert into  user(username, pwd) values(?,?) ");
15                PreparedStatement ps2 = connection.prepareStatement("insert into  user(username, pwd) values(?,?) ")) {
16
17            //JDBC中默认事务是自动提交的,false就不会自动提交
18            connection.setAutoCommit(false);
19
20            ps1.setString(1, "1111tranc ps 1二当家小D");
21            ps1.setString(2, "123456");
22
23            ps2.setString(1, "2222tranc ps 2二当家小D");
24            ps2.setString(2, "123456");
25
26            ps1.execute();
27
28            //模拟异常
29            int i = 1/0;
30
31            ps2.execute();
32
33
34        } catch (Exception e) {
35            e.printStackTrace();
36
37            //事务回滚
38            connection.rollback();
39
40        } finally {
41                //事务提交
42            connection.commit();
43
44
45            connection.close();
46        }
47
48    }

封装 DBUtils 工具类

  • 优化 JDBC 操作,提高效率
  • javaweb 项目中,使用 JDBC 需要添加 MySQL 启动到 Tomcat 里面

db.properties

1url=jdbc:mysql://127.0.0.1:3306/xd_web?useUnicode=true&characterEncoding=utf-8&useSSL=false
2username=root
3password=xdclass.net
4driver=com.mysql.jdbc.Driver

CustomDBUtil

 1public class CustomDBUtil {
 2
 3    private static String url;
 4
 5    private static String username;
 6
 7    private static String password;
 8
 9    private static String driver;
10  
11    static {
12        try {
13            Properties properties = new Properties();
14
15            properties.load(CustomDBUtil.class.getClassLoader().getResourceAsStream("db.properties"));
16
17            url = properties.getProperty("url");
18            username = properties.getProperty("username");
19            password = properties.getProperty("password");
20            driver = properties.getProperty("driver");
21
22            //加载JDBC驱动程序
23            Class.forName(driver);
24
25        }catch (Exception e){
26            e.printStackTrace();
27        }
28    }
29  
30    /**
31     * 获取连接
32     * @return
33     * @throws Exception
34     */
35    public static Connection getConnection() throws Exception{
36
37        Connection connection = DriverManager.getConnection(url,username,password);
38        return connection;
39    }
40
41    /**
42     * 关闭数据库资源
43     * @param resultSet
44     * @param ps
45     * @param connection
46     */
47    public static void close(ResultSet resultSet, PreparedStatement ps, Connection connection){
48        try{
49            if(resultSet!=null){
50                resultSet.close();
51            }
52
53            if(ps!=null){
54                ps.close();
55            }
56            if(connection!=null){
57                connection.close();
58            }
59
60        }catch (SQLException e){
61            throw  new RuntimeException();
62        }
63    }
64}

TestJDBCServlet

 1@WebServlet({"/jdbc"})
 2public class TestJDBCServlet extends HttpServlet {
 3    public TestJDBCServlet() {
 4    }
 5
 6    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 7        String idStr = req.getParameter("id");
 8        int id = Integer.parseInt(idStr);
 9
10        try {
11            Connection connection = CustomDBUtil.getConnection();
12            PreparedStatement ps = connection.prepareStatement("select  * from user where  id=?");
13            ps.setInt(1, id);
14            ResultSet resultSet = ps.executeQuery();
15
16            while(resultSet.next()) {
17                System.out.println("用户名称 name=" + resultSet.getString("username") + "  联系方式 wechat=" + resultSet.getString("wechat"));
18            }
19
20            CustomDBUtil.close(resultSet, ps, connection);
21        } catch (Exception var8) {
22            var8.printStackTrace();
23        }
24
25    }
26}

池化思想

  • 为什么要用连接池

    • 数据库建立 Connection 比较耗时,频繁的创建和释放连接引起的大量性能开销
    • 如果数据库连接得到重用,避免这些开销,也提高了系统稳定
    • 数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于池中备用,对于业务请求处理而言,直接利用现有可用连接,缩减了系统整体响应时间
    • 统一的连接管理,避免数据库连接泄漏、超时占用等问题
  • 同类对比其他池化思想

    • Java 线程池
    • Tomcat 连接池
    • 对象池(SpringIOC 容器)

主流 DB 工具类、数据库连接池

  • 数据库工具类 : Apache commens-dbutils

    • Apache 组织提供的一个开源 JDBC 工具类库,它是对 JDBC 的简单封装,能极大简化 JDBC 编码的工作量,同时也不会影响程序的性能
    • 地址:https://commons.apache.org/proper/commons-dbutils/
    • 导入
      • 添加到 IDEA
      • 可以添加到 web-inf 的 lib 包(添加到 Tomcat 效果是一样的)
  • 数据库连接池:c3p0、druid、dbcp

所有依赖包

commons-pool2-2.8.0 、commons-logging-1.2、commons-dbcp2-2.7.0、commons-dbutils-1.7、mysql-connector-java-5.1.46

https://abc1024.oss-cn-shanghai.aliyuncs.com/Picture/Javaweb/packages.rar

DBCP 连接池、dbutils 工具类

创建配置文件 database.properties

1driverClassName = com.mysql.jdbc.Driver
2url = jdbc:mysql://127.0.0.1:3306/xd_web?useUnicode=true&characterEncoding=utf-8&useSSL=false
3username = root
4password = xdclass.net
5
6initialSize=10              //连接池建立时创建的连接的数量
7maxActive=30            //连接池同一时间内最多能够分配的活动连接的数量

数据库连接池工具类(用于返回 DataSource,更方便使用 dbutils 工具类)

 1/**
 2 * 数据库连接池工具类
 3 */
 4public class DataSourceUtil {
 5
 6    //连接池
 7    private static DataSource dataSource;
 8
 9    static {
10
11        try{
12
13            InputStream in = DataSourceUtil.class.getClassLoader().getResourceAsStream("database.properties");
14            Properties p = new Properties();
15            p.load(in);
16	    //BasicDataSourceFactory用于创建连接池
17            dataSource = BasicDataSourceFactory.createDataSource(p);
18
19        }catch (Exception e){
20            e.printStackTrace();
21            throw new ExceptionInInitializerError("初始化DBPC失败");
22        }
23    }
24
25    /**
26     * 获取连接池
27     * @return
28     */
29    public static DataSource getDataSource(){
30        return dataSource;
31    }
32
33}

dbutils 工具介绍

DbUtils 中的核心类/接口

  • QueryRunner

    • 查询执行器,提供对 SQL 语句操作的 API
    • update(String sql,Object...params) 可执行 增-INSERT、删-DELETE、改-UPDATE
    • query(String sql,ResultSetHandler rsh,Object...params) 可执行 查询-SELECT
  • ResultSetHandler

    • 结果集处理类,执行处理一个结果集对象,将数据转变并处理为任何一种形式
      • BeanHandler 结果集中的第一行数据封装到一个对应的 JavaBean 实例
      • BeanListHandler 结果集中的每一行数据都封装到一个对应的 JavaBean 实例中,存放到 List 里
      • MapHandler 结果集中的第一行数据封装到一个 Map 里,key 是列名,value 就是对应的值
      • MapListHandler 结果集中的每一行数据都封装到一个 Map 里,然后再存放到 List
      • ScalarHandler 结果集中第一行数据指定列的值,常用来进行单值查询
  1public class UserDao {
  2
  3    private QueryRunner queryRunner = new QueryRunner(DataSourceUtil.getDataSource());
  4
  5    //开启驼峰映射
  6    private BeanProcessor bean = new GenerousBeanProcessor();
  7    private RowProcessor processor = new BasicRowProcessor(bean);
  8
  9    /**
 10     * 新增
 11     * queryRunner.update(sql,params);
 12     * @param user
 13     * @return
 14     * @throws Exception
 15     */
 16    public int save(User user) throws Exception {
 17
 18        String sql = "insert into user (phone,pwd,sex,img,create_time,role,username,wechat) values(?,?,?,?,?,?,?,?)";
 19
 20        Object [] params = {
 21                user.getPhone(),
 22                user.getPwd(),
 23                user.getSex(),
 24                user.getImg(),
 25                user.getCreateTime(),
 26                user.getRole(),
 27                user.getUsername(),
 28                user.getWechat()
 29        };
 30//        String sql = "delete from user where id= ?";
 31//        Object [] params = { 1};
 32
 33        int i = 0;
 34        try{
 35
 36           i = queryRunner.update(sql,params);
 37
 38        }catch (Exception e){
 39            e.printStackTrace();
 40            throw new Exception();
 41        }
 42        return i;
 43    }
 44
 45    /**
 46     * BeanHandler 结果集中的第一行数据封装到一个对应的JavaBean实例
 47     * @param id
 48     * @return
 49     */
 50    public User findById(int id){
 51        String sql = "select * from user where id=?";
 52        User user = null;
 53        try {
 54            user  =  queryRunner.query(sql,new BeanHandler<>(User.class,processor),id);
 55
 56        } catch (SQLException e) {
 57            e.printStackTrace();
 58        }
 59        return user;
 60    }
 61
 62    /**
 63     * BeanListHandler 结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里
 64     * @return
 65     */
 66    public List<User> list(){
 67        String sql = "select * from user";
 68       List<User> list = null;
 69        try {
 70            list  =  queryRunner.query(sql,new BeanListHandler<>(User.class,processor));
 71
 72        } catch (SQLException e) {
 73            e.printStackTrace();
 74        }
 75        return list;
 76    }
 77
 78    /**
 79     * 根据id找用户
 80     * MapHandler  结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值
 81     * @param id
 82     * @return
 83     */
 84    public Map<String,Object> findByIdWithMap(int id){
 85        String sql = "select * from user where id=?";
 86        Map<String,Object> map = null;
 87        try {
 88            map  =  queryRunner.query(sql,new MapHandler(),id);
 89
 90        } catch (SQLException e) {
 91            e.printStackTrace();
 92        }
 93        return map;
 94    }
 95
 96    /**
 97     * 小滴课堂jdbc实战 https://xdclass.net
 98     *
 99     * 查找全部用户
100     * MapListHandler 果集中的每一行数据都封装到一个Map里,然后再存放到List
101     * @return
102     */
103
104    public List<Map<String,Object>> listWithMap(){
105        String sql = "select * from user";
106        List<Map<String,Object>> list = null;
107        try {
108            list  =  queryRunner.query(sql,new MapListHandler());
109
110        } catch (SQLException e) {
111            e.printStackTrace();
112        }
113        return list;
114    }
115
116    /**
117     * ScalarHandler 结果集中第一行数据指定列的值,常用来进行单值查询
118     * @return
119     */
120    public int countUser(){
121
122        String sql = "select count(*) from user";
123
124        Long count = null;
125
126        try{
127
128            count = (Long)queryRunner.query(sql,new ScalarHandler<>());
129
130        }catch (Exception e){
131            e.printStackTrace();
132        }
133        return count.intValue();
134    }
135}
136

Maven 依赖

  1<?xml version="1.0" encoding="UTF-8"?>
  2
  3<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5  <modelVersion>4.0.0</modelVersion>
  6
  7  <groupId>net.xdclass</groupId>
  8  <artifactId>xd_forum</artifactId>
  9  <version>1.0-SNAPSHOT</version>
 10  <packaging>war</packaging>
 11
 12  <name>xd_forum Maven Webapp</name>
 13  <!-- FIXME change it to the project's website -->
 14  <url>http://www.example.com</url>
 15
 16  <properties>
 17    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 18    <maven.compiler.source>1.7</maven.compiler.source>
 19    <maven.compiler.target>1.7</maven.compiler.target>
 20  </properties>
 21
 22  <dependencies>
 23
 24    <dependency>
 25      <groupId>junit</groupId>
 26      <artifactId>junit</artifactId>
 27      <version>4.11</version>
 28      <scope>test</scope>
 29    </dependency>
 30
 31
 32    <dependency>
 33      <groupId>javax.servlet</groupId>
 34      <artifactId>javax.servlet-api</artifactId>
 35      <version>3.1.0</version>
 36      <scope>provided</scope>
 37    </dependency>
 38
 39
 40    <dependency>
 41      <groupId>mysql</groupId>
 42      <artifactId>mysql-connector-java</artifactId>
 43      <version>5.1.41</version>
 44    </dependency>
 45
 46    <!-- JSP -->
 47    <dependency>
 48      <groupId>javax.servlet.jsp</groupId>
 49      <artifactId>jsp-api</artifactId>
 50      <version>2.2</version>
 51      <scope>provided</scope>
 52    </dependency>
 53
 54
 55    <!-- https://mvnrepository.com/artifact/commons-dbutils/commons-dbutils -->
 56    <dependency>
 57      <groupId>commons-dbutils</groupId>
 58      <artifactId>commons-dbutils</artifactId>
 59      <version>1.7</version>
 60    </dependency>
 61
 62    <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
 63    <dependency>
 64      <groupId>org.apache.commons</groupId>
 65      <artifactId>commons-dbcp2</artifactId>
 66      <version>2.7.0</version>
 67    </dependency>
 68
 69    <!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
 70    <dependency>
 71      <groupId>commons-beanutils</groupId>
 72      <artifactId>commons-beanutils</artifactId>
 73      <version>1.9.4</version>
 74    </dependency>
 75
 76
 77
 78
 79
 80    <!-- https://mvnrepository.com/artifact/taglibs/standard -->
 81    <dependency>
 82      <groupId>taglibs</groupId>
 83      <artifactId>standard</artifactId>
 84      <version>1.1.2</version>
 85    </dependency>
 86
 87
 88    <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
 89    <dependency>
 90      <groupId>javax.servlet</groupId>
 91      <artifactId>jstl</artifactId>
 92      <version>1.2</version>
 93    </dependency>
 94
 95
 96  </dependencies>
 97
 98  <build>
 99
100    <!--专门用于打包配置文件到类路径-->
101    <resources>
102      <resource>
103        <directory>src/main/java</directory>
104        <includes>
105          <include>**/*.properties</include>
106          <include>**/*.xml</include>
107        </includes>
108        <filtering>true</filtering>
109      </resource>
110    </resources>
111
112
113
114    <finalName>xd_forum</finalName>
115    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
116      <plugins>
117        <plugin>
118          <artifactId>maven-clean-plugin</artifactId>
119          <version>3.1.0</version>
120        </plugin>
121        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
122        <plugin>
123          <artifactId>maven-resources-plugin</artifactId>
124          <version>3.0.2</version>
125        </plugin>
126        <plugin>
127          <artifactId>maven-compiler-plugin</artifactId>
128          <version>3.8.0</version>
129        </plugin>
130        <plugin>
131          <artifactId>maven-surefire-plugin</artifactId>
132          <version>2.22.1</version>
133        </plugin>
134        <plugin>
135          <artifactId>maven-war-plugin</artifactId>
136          <version>3.2.2</version>
137        </plugin>
138        <plugin>
139          <artifactId>maven-install-plugin</artifactId>
140          <version>2.5.2</version>
141        </plugin>
142        <plugin>
143          <artifactId>maven-deploy-plugin</artifactId>
144          <version>2.8.2</version>
145        </plugin>
146      </plugins>
147    </pluginManagement>
148  </build>
149</project>
150

作者:Soulboy