本文主要讲述了maven项目创建后进行的一些基础配置及对数据库操作的前置准备工作(pom.xml、DBUtil类、Image类)。
maven项目创建可以看这里:Servlet-day01 这里面有详细介绍
pom.xml
pom.xml中放置了许多外部包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--
<groupId>org.example</groupId>
<artifactId>untitled15</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
-->
<groupId>com.bit</groupId>
<artifactId>java_image_servlet</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>untitled15 Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--json的依赖 gosn-->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
<!--mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<!--上传文件的第三方仓库FileUpload-->
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<!--servlet包-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<!--表示在开发阶段需要此依赖,部署到Tomcat后就不需要了-->
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<!--指定最终包的名称-->
<finalName>java_image_servlet</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
这些包中的具体内容以及如何加入的后续都会一一解释,首先我们这里解释一下这几个
1.juit
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
用于在Java项目中添加JUnit测试框架。JUnit是一个用于编写和运行单元测试的框架,可以帮助开发者确保他们的代码能够按照预期工作。
2.gson
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
用于在Java项目中添加Google的Gson库。Gson是一个用于处理JSON数据的Java库,可以将Java对象转换为JSON字符串,也可以将JSON字符串转换为Java对象
3.mysql依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
用于在Java项目中添加MySQL的JDBC驱动。这个驱动允许Java程序与MySQL数据库进行交互。
4.servlet
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<!--表示在开发阶段需要此依赖,部署到Tomcat后就不需要了-->
<scope>provided</scope>
</dependency>
用于在Java Web应用程序中添加Servlet API。Servlet API提供了一组接口和类,用于开发基于Java的Web应用程序。
DBUtil类
在Java目录下创建dao包(数据访问层,蔚然数据库展开操作),在dao包中创建DBUtil类
JDBC相关操作不清楚可以看这篇文章:0基础速成Java环境下JDBC编程(细节超全,保姆级教程)
package dao;
import com.mysql.cj.jdbc.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.SynchronousQueue;
public class DBUtil {
//获取数据库连接
private static final String URL = "jdbc:mysql://127.0.0.1:3306/image_table?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";
private static final String USERNAME = "root";
private static final String PASSWORD = "123456";
private static volatile DataSource dataSource = null;
//定义了一个私有的、静态的、易变的DataSource类型的变量,并且将其初始化为null
public static DataSource getDataSource(){
if(dataSource == null){
Synchronized(DBUtil.class);{
if(dataSource == null){
dataSource = new MysqlDataSource();
// MysqlDataSource 对象强制转换为 MysqlDataSource 类型,
// 并使用 setURL()、setUser() 和 setPassword() 方法设置数据库连接的相关信息,包括 URL、用户名和密码。
MysqlDataSource tmpDataSour = (MysqlDataSource) dataSource;
tmpDataSour.setURL(URL);
tmpDataSour.setUser(USERNAME);
tmpDataSour.setPassword(PASSWORD);
}
}
}
return dataSource;
}
//建立连接
public static Connection getConnection() throws SQLException {
return getDataSource().getConnection();
}
//关闭连接
public static void close(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet) throws RuntimeException {
if(resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if(preparedStatement != null){
try {
preparedStatement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (connection != null){
try {
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
private static void Synchronized(Class<DBUtil> dbUtilClass) {
}
}
1.数据库基本信息
private static final String URL = "jdbc:mysql://127.0.0.1:3306/image_table?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";
private static final String USERNAME = "root";
private static final String PASSWORD = "123456";
(1)
jdbc:mysql://127.0.0.1:3306/image_table?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";
127.0.0.1:3306/
数据库服务器的地址
image_table
数据库名,写自己需要对数据库中操作的那个数据库的名字
characterEncoding=utf8
:客户端和服务器之间的通信字符编码为UTF-8
useSSL=false
:表示不使用SSL进行安全连接
serverTimezone=UTC
:设置服务器的时区为UTC
allowPublicKeyRetrieval=true
:允许从服务器获取公钥。执行需要公钥认证的操作(如SSL/TLS连接)是必要的(2)
private static final String USERNAME = "root";
:表示该数据库的名字为root
(3)private static final String PASSWORD = "123456";
:表示该数据库的密码为123456
2.获取数据库连接
这是一个单例模式且线程安全的获取数据库连接的代码
单例模式详解:我给面试官讲解了单例模式后,他对我竖起了大拇指!
线程安全详解:多线程中synchronized和volatile-解决线程安全问题
private static DataSource dataSource = null;
public static DataSource getDataSource(){
if(dataSource == null){
dataSource = new MysqlDataSource();
//类型加强,将dataSource 对象强制转换为 MysqlDataSource 类型
MysqlDataSource tmpDataSour = (MysqlDataSource) dataSource;
//使用 setURL()、setUser() 和 setPassword() 方法设置数据库连接的相关信息,包括 URL、用户名和密码
tmpDataSour.setURL(URL);
tmpDataSour.setUser(USERNAME);
tmpDataSour.setPassword(PASSWORD);
}
public static Connection getConnection() throws SQLException {
//从一个数据源(DataSource)对象中获取数据库连接,以便执行SQL语句和操作数据库。
// 数据源可以是配置文件中定义的数据源,也可以是通过编程方式创建的数据源
return getDataSource().getConnection();
}
(1)
dataSource
这个对象在一个程序中只用存在一份,且在使用前线判断是否创建了,若没有则创建,若已经创建则将URL,USERNAME,PASSWORD等信息设置进去
(2)if(dataSource == null){ dataSource = new MysqlDataSource(); } return dataSource;
判断dataSource是否为空,为空说明还未创建,此时应该创建dataSource对象并调用相关方法设置数据库 URL、数据库名和密码,若不为空则直接返回dataSource
这个判断很明显可以看出来这段代码为单例模式中的懒汉模式(3)上述代码很明显不是一个线程安全的代码,解决方法:
首先:用
volatile
让dataSource
变量每次读取都会去主存中获取最新值,每次写入都会立即写主存(volatile不能保证原子性,即它不能替代synchronized关键字实现同步操作) 其次:
Synchronized(DBUtil.class):同步块,确保在多线程环境下,只有一个线程可以执行这个代码块。锁对象为DBUtil.class 最后:在
Synchronized(DBUtil.class)`同步块外加入一个if判断,判断dataSource变量是否为空(4)
return getDataSource().getConnection();
调用了getDataSource()方法获取数据源对象,然后调用该对象的getConnection()方法获取数据库连接,并将连接返回。
Image类
在java目录下的dao包中创建Image类
package dao;
public class Image {
private int imageId;//图片ID
private String imageName;//图片名字
private int size;//图片大小
private String uploadTime;//图片上传时间
private String contentType;//图片类型
private String path;//图片存储路径
private String md5;//图片md5校验和
}
然后进行自动生成get方法、set方法和toString方法
方便在后期直接调用这些方法
(1)自动生成get和set方法:alt+ins 选择Getter and Setter 全选,按下OK
(2)自动生成toString方法:alt+ins 选择toString… 全选,按下OK
最后结果:
package dao;
public class Image {
private int imageId;//图片ID
private String imageName;//图片名字
private int size;//图片大小
private String uploadTime;//图片上传时间
private String contentType;//图片类型
private String path;//图片存储路径
private String md5;//图片md5校验和
public int getImageId() {
return imageId;
}
public void setImageId(int imageId) {
this.imageId = imageId;
}
public String getMd5() {
return md5;
}
public void setMd5(String md5) {
this.md5 = md5;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getUploadTime() {
return uploadTime;
}
public void setUploadTime(String uploadTime) {
this.uploadTime = uploadTime;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public String getImageName() {
return imageName;
}
public void setImageName(String imageName) {
this.imageName = imageName;
}
@Override
public String toString() {
return "Image{" +
"imageId=" + imageId +
", imageName='" + imageName + '\'' +
", size=" + size +
", uploadTime='" + uploadTime + '\'' +
", contentType='" + contentType + '\'' +
", path='" + path + '\'' +
", md5='" + md5 + '\'' +
'}';
}
}