JDBC
JDBC
- 全称 Java DataBase Connectivity, 是 Java 语言中用来规范客户端程序如何来访问数据库的应用程序接口
- 提供了一种接口基准,可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序
- 应用程序代码一般不能直接访问数据库,需要通过相应的数据库驱动程序才行,
- 数据库驱动就是数据库厂商对 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
- dbcp: 全称 DataBase connection pool,数据库连接池是 apache 上的一个 Java 连接池项目
- 地址:http://commons.apache.org/proper/commons-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