#Maven配置
参考:IDEA配置maven_idea 配置maven-CSDN博客
Maven 是 Java 生态系统中广泛使用的项目管理和构建自动化工具,主要功能包括:
- 依赖管理:自动下载、管理项目所需的第三方库(JAR 包),并处理依赖之间的版本冲突,无需手动下载和复制 JAR 文件。
- 标准化项目结构 :规定了统一的项目目录结构(如 src/main/java 存放源代码、src/test/java 存放测试代码等),使不同 Java 项目的结构保持一致,降低协作成本。
- 构建自动化 :通过配置文件(pom.xml)定义项目的构建流程,支持编译、测试、打包(生成 JAR/WAR 等)、部署等一系列操作,可一键执行完整构建过程。
- 项目信息管理 :在 pom.xml 中可维护项目的基本信息(如名称、版本、开发者等),并能与代码仓库、持续集成工具等集成。
根据参考文档配置好,测试是否正确配置环境

配置时要注意,mirror是否包含在mirrors里面,是否少了 ,如果少了,就会报错了,导致第三方库无法下载下来

#JDBC
新建项目

选好版本和依赖

1、引用依赖(pom.xml)
选择第二个

选择一个版本,别选最新,不然可能不兼容,会报错

选择maven,然后将那段代码复制

将代码复制到里面,然后点击右侧的maven

打开之后点击和刷新很像的符号,然后要注意左侧是否将库下载进去了,如果没有就换一个MySQL存储库

新建一个软件包放服务器的东西,写一个接收id的值,然后写一个查询语句

2、注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
- MySQL 5.x 版本的驱动类名是 com.mysql.jdbc.Driver
- MySQL 8.x 版本才引入 com.mysql.cj.jdbc.Driver 这个新的驱动类名
写上注册语句,这里会报异常,直接用try ,catch 包裹就行,这里用的5.7版本的MySQL和5版本的驱动

3、建立数据库连接
String url ="jdbc:mysql://localhost:3306/phpstudy";
Connection connection=DriverManager.getConnection(url,"root","123456");

测试一下是否连接正常, 连接正常,输出乱码是因为没定义输出的格式


4、创建Statement执行SQL
Statement statement= connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);

输入id值进行测试

5、结果ResultSet进行提取
*while (rs .next()) {
resp *.getWriter().println(rs *.getString("id"**)); //输出名称为id的列的值
resp .getWriter().println(rs *.getString("username"*)); //输出名称为username的列的值
resp .getWriter().println(rs *.getString("password"*)); //输出名称为password的列的值
resp *.getWriter().println(*rs .getString(3)); *//输出第三列的值
}
这里查询id为2 的数据,可以正常显示


安全注入例子:
预编译:PreparedStatement
安全写法(预编译): "select * from admin where id=?"
输入的sql注入语句没有生效 ,预编译中将查询语句写死了,在后面写的sql注入语句不会执行

完整代码:
@WebServlet("/jdbc")
public class JdbcServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String id = req.getParameter("id");
// 安全的拼接 SQL 语句
// String sql = "select * from admin where id = ?";
String url ="jdbc:mysql://localhost:3306/phpstudy";
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url,"root","654321");
PreparedStatement ps = conn.prepareStatement(sql); // 创建 PreparedStatement 对象
ps.setString(1,id); // 设置第一个参数的值
ResultSet rs = ps.executeQuery(); // 执行查询
while (rs.next()) {
resp.getWriter().println(rs.getString("id")); // 输出名称为 id 的列的值
resp.getWriter().println(rs.getString("username")); // 输出名称为 username 的列的值
resp.getWriter().println(rs.getString("password")); // 输出名称为 password 的列的值
resp.getWriter().println(rs.getString(3)); // 输出第三列的值
}
} catch (ClassNotFoundException | SQLException e) {
throw new RuntimeException(e);
}
}
}
不安全写法(拼接): "select * from admin where id="+id
可以执行后面的sql注入语句,就可以开始注入了

完整代码
@WebServlet("/jdbc")*
public classJdbcServlet extendsHttpServlet {
@Override
protected void doGet*(HttpServletRequest req ,*HttpServletResponse resp ) throwsServletException , IOException {
String id =req *.getParameter("id"*);
//不安全的拼接SQL语句,容易导致SQL**注入攻击
String sql = "select * from admin where id = "+id ;
String url *="jdbc:mysql://localhost:3306/phpstudy"*;
try {
Class .forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager .getConnection(url *,"root","654321"*);
Statement statement =conn .createStatement(); //创建Statement对象
ResultSet rs *=statement .executeQuery(sql ); *//执行查询
while *(rs .next()) {
resp *.getWriter().println(rs *.getString("id")); //输出名称为id的列的值
resp *.getWriter().println(rs *.getString("username"*)); //输出名称为username的列的值
resp .getWriter().println(rs *.getString("password"*)); //输出名称为password的列的值
resp *.getWriter().println(*rs .getString(3)); *//*输出第三列的值
}
} catch *(*ClassNotFoundException | SQLException e ) {
throw new RuntimeException *(e );
}
}
}
#Hibernate
项目创建和jdbc 一样,就是项目名称改一下
这里勾选一下 hibernate ,等会就不用引用了 (但是测试时用这个依赖库时会报错,可能是后面的id什么对不上或者版本不兼容等)

1、引用依赖(pom.xml)
hibernate-core,mysql-connector-java
创建项目时勾选的引用库

自己写引用

2、Hibernate配置文件
src/main/resources/hibernate.cfg.xml
<?xmlversion='1.0'encoding='utf-8'?>*
<!DOCTYPE hibernate-configuration**PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd" >
< hibernate-configuration*>*
< session-factory*>*
<!--*数据库连接配置 -->
< propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</* property*>*
< propertyname="hibernate.connection.url">jdbc:mysql://localhost:3306/phpstudy?useUnicode=true &*characterEncoding=UTF-8 &serverTimezone=Asia/Shanghai</ property>
< propertyname="hibernate.connection.username">root</* property*>*
< propertyname="hibernate.connection.password">654321</ property*>*
<!--*数据库方言 -->
< propertyname="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</* property*>*
<!--显示 SQL语句 -->
< propertyname="hibernate.show_sql">true</ property*>*
<!--*自动更新数据库表结构 -->
< propertyname="hibernate.hbm2ddl.auto">update</* property*>*
<!--*映射实体类 -->
< mappingclass="com.example.hibermateddemo.entity.User"/>*
</ session-factory*>*
</ hibernate-configuration*>**
3、映射实体类开发
用来存储获取数据:
src/main/java/com/example/entity/User.java
packagecom* .example .*hibermateddemo .entity ;
import javax *.persistence .*;
@Entity
@Table(name = *"admin")
public classUser {
@Id
@GeneratedValue(strategy *=GenerationType .IDENTITY)
private *intid* ;
private String username ;
public User*()* {}
public int getId*()* {
returnid ;
}
public void setId*(intid* ) {
this*.id =id ;
}
public String getUsername() {
returnusername ;
}
public void setUsername(String username ) {
this.username =username ;
}
@Override
public String toString() {
return "User{id=" +id + ", username=" *+username + *"}";
}
}
4、Hibernate工具类
用来Hibernate使用:
src/main/java/com/example/util/HibernateUtil.java
packagecom* *.*example *.*hibermateddemo .util ;
import org .*hibernate .SessionFactory ;
import org *.hibernate *.cfg .*Configuration ;
public classHibernateUtil {
private static *finalSessionFactory sessionFactory ;
static {
try {
Configuration configuration = new Configuration ().configure();
sessionFactory =configuration .buildSessionFactory();
} catch (Throwable ex ) {
throw new ExceptionInInitializerError *(ex );
}
}
public *staticSessionFactory getSessionFactory() {
returnsessionFactory ;
}
}
5、Servlet开发接受:
src/main/java/com/example/servlet/UserServlet.java
packagecom* *.*example *.*hibermateddemo *.*servlet ;
import com *.*example *.*hibermateddemo *.*entity *.*User ;
import com *.*example *.*hibermateddemo *.*util *.*HibernateUtil ;
import jakarta *.*servlet *.*ServletException ;
import jakarta *.*servlet *.*annotation *.*WebServlet ;
import jakarta .servlet *.http *.HttpServlet ;
import jakarta .servlet *.http *.HttpServletRequest ;
import jakarta .servlet .http *.HttpServletResponse ;
import org *.hibernate *.Session ;
import org .hibernate .Query ;
import java .*io .IOException ;
import java *.io *.PrintWriter ;
import java *.util *.List ;
@WebServlet("/user")
public classUserServlet extendsHttpServlet {
@Override
protected void doGet(HttpServletRequest request ,*HttpServletResponse response ) throwsServletException , IOException {
response *.setContentType("text/html;charset=UTF-8");
PrintWriter out *=response .getWriter();
*//获取参数(这里假设根据用户名查询)
String username *=request *.getParameter("username");
//打开 Hibernate Session
Session session *=HibernateUtil .getSessionFactory().openSession();
try {
//修改后的 HQL语句,直接拼接字符串
// String hql = "FROM User WHERE username = '" + username + "'";
String hql = *"FROM User WHERE username=:username";
*//创建查询对象
Query <User >query *=session *.createQuery(hql *,User .class);
query *.setParameter("username",username ); *//设置参数值
*//执行查询
List <User *>users *=query .getResultList();
*//输出查询结果
out *.println("<html><body>");
if *(users .isEmpty()) {
out *.println("<p>未找到匹配的用户。</p>");
} else {
for (User user *:users ) {
out *.println("<p>" *+user + *"</p>");
}
}
out *.println("</body></html>");
} catch *(Exception e ) {
e .printStackTrace();
out *.println("<html><body><p>查询出错,请稍后重试。</p></body></html>");
} finally {
*//关闭 Session
session .close();
}
}
}
完整流程:
***1.*启动阶段:Hibernate 初始化
- 加载配置文件
应用启动时,HibernateUtil 类被加载,其静态代码块执行:- 通过new Configuration().configure() 读取类路径下的hibernate.cfg.xml配置文件。
- 配置文件中包含:数据库连接信息(URL、用户名、密码、驱动)、Hibernate 方言、实体映射等。
- 创建 SessionFactory
- configuration.buildSessionFactory() 根据配置信息创建SessionFactory(Hibernate 的核心工厂类,负责管理数据库连接池和会话)。
- SessionFactory 是重量级对象,全局唯一,后续所有数据库操作都通过它创建Session。
***2.*运行阶段:处理用户请求(以 /user 请求为例)
步骤 1**:接收 HTTP** 请求
- 前端通过*/user?username=xxx* 发送 GET 请求,被*@WebServlet("/user")* 注解的UserServlet拦截。
- doGet 方法被调用,获取请求参数username(用户输入的查询条件)。
步骤 2**:获取 Hibernate Session**
- 通过HibernateUtil.getSessionFactory().openSession() 从SessionFactory 获取Session对象。
- Session 是 Hibernate 与数据库交互的会话对象,类似 JDBC 的Connection,用于执行 CRUD 操作。
步骤 3**:执行 HQL** 查询
- 构建查询语句
- 拼接 HQL 语句:"FROM User WHERE username = '" + username + "'" (根据用户名查询User实体)。
- 创建查询对象
- 通过session.createQuery(hql, User.class) 创建Query 对象,指定返回结果为User类型。
- 执行查询
- 调用query.getResultList() 执行查询,Hibernate 将 HQL 转换为对应数据库的 SQL(如SELECT * FROM user WHERE username = 'xxx'),并发送到数据库。
- 数据库返回结果后,Hibernate 将结果集映射为User对象列表。
步骤 4**:响应查询结果**
- 通过
- HTML 响应:
- 若查询结果为空,显示 "未找到匹配的用户"。
- 若有结果,遍历User列表并输出用户信息。
步骤 5**:释放资源**
- 在finally 块中调用session.close() 关闭Session,释放数据库连接资源。
安全注入例子: (修改UserServlet.java 中的语句实现效果)
安全写法:String hql = "FROM User WHERE username=:username";

输入正确的值是可以正常查询

用sqlmap 跑一下看是否存在 SQL 注入漏洞 用这个写法是不存在sql注入漏洞的
命令 : python sqlmap.py -u "http://localhost:8080/Hibermated_demo_war_exploded/user?username=xiaodi"

不安全写法:String hql = "FROM User WHERE username='"+username+"'";
这里用正确的username查询一下数据库的数据看一下

用sqlmap 跑一下看是否存在 SQL 注入漏洞 用这个写法是存在sql注入漏洞的

#MyBatis
1、引用依赖(pom.xml)
mybatis,mysql-connector-java
在pom.xml 中的 里面加入下面代码
< dependency>*
< groupId*>org.mybatis</* groupId*>*
< artifactId*>mybatis</* artifactId*>*
< version*>3.5.13</* version*>*
</ dependency*>*
< dependency*>*
< groupId*>mysql</* groupId*>*
< artifactId*>mysql-connector-java</* artifactId*>*
< version*>5.1.17</* version*>*
</ dependency*>**
要确保引入的库加载到了外部库中,否则是没有成功的

2、MyBatis配置文件
src/main/resources/mybatis-config.xml 文件路径
<?xmlversion="1.0"encoding="UTF-8"* ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd" >
< configuration*>*
< environments*default="development">*
< environment*id="development">*
< transactionManager*type="JDBC"/>*
< dataSource*type="POOLED">*
< property*name="driver"value="com.mysql.cj.jdbc.Driver"/>*
< property*name="url"value="jdbc:mysql://localhost:3306/phpstudy?serverTimezone=UTC"/>*
< property*name="username"value="root"/>*
< property*name="password"value="123456"/>*
</ dataSource*>*
</ environment*>*
</ environments*>*
< mappers*>*
< mapper*resource="AdminMapper.xml"/>*
</ mappers*>*
</ configuration*>
3、AdminMapper.xml创建
src/main/resources/AdminMapper.xml 文件路径
<?xmlversion="1.0"encoding="UTF-8"* ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
< mapper*namespace="com.example.jdbcdemo43.mapper.AdminMapper">*
< select*id="selectAdminById"resultType="com.example.jdbcdemo43.model.Admin">*
SELECT * FROM admin WHERE id = #{id}
</ select*>*
</ mapper*>
4、创建数据实体类
com/example/mybatisdemo43/model/Admin.java
packagecom* .example *.mybatisdemo .*model ;
public classAdmin {
private *int*id ;
private String username ;
private String password ;
// Getters and Setters
public int getId*()* {
returnid ;
}
public void setId*(intid* ) {
this*.id =id ;
}
public String getUsername() {
returnusername ;
}
public void setUsername(String username ) {
this.username =username ;
}
public String getPassword() {
returnpassword ;
}
public void setPassword(String password ) {
this.*password =password ;
}
@Override
public String toString() {
return "Admin{" +
"id=" *+id +
", username='" +username + '\'' +
", password='" *+password + '\'' +
*'}';
}
}
5、创建mapper实体类
com/example/mybatisdemo43/mapper/AdminMapper.java
packagecom* *.*example *.mybatisdemo .mapper ;
import com *.example *.mybatisdemo *.model *.Admin ;
import org .apache *.ibatis .annotations .*Param ;
public interfaceAdminMapper {
Admin selectAdminById(@Param("name") String name );
}
6、创建servlet接受类
com/example/mybatisdemo43/servlet/SelectServlet.java
packagecom* *.*example *.*mybatisdemo *.*servlet ;
import com *.*example *.*mybatisdemo *.*mapper *.*AdminMapper ;
import com *.*example *.*mybatisdemo *.*model *.*Admin ;
import jakarta *.*servlet *.*ServletException ;
import jakarta *.*servlet *.*annotation *.*WebServlet ;
import jakarta *.*servlet *.*http *.*HttpServlet ;
import jakarta *.*servlet *.*http *.*HttpServletRequest ;
import jakarta *.*servlet *.*http *.*HttpServletResponse ;
import org *.*apache *.*ibatis *.*io *.*Resources ;
import org *.*apache *.ibatis .session *.SqlSession ;
import org .apache .ibatis *.session .SqlSessionFactory ;
import org *.apache *.ibatis .session .SqlSessionFactoryBuilder ;
import java .*io .IOException ;
import java *.io *.InputStream ;
@WebServlet(name = *"sql",value = *"/sql")
public classSelectServlet extendsHttpServlet {
@Override
protected void doGet(HttpServletRequest req ,*HttpServletResponse resp ) throwsServletException , IOException {
String name *=req *.getParameter("name");
if *(name == null *||name .isEmpty()) {
resp *.getWriter().write("none");
return;
}
//加载 MyBatis配置文件
String resource = *"mybatis-config.xml";
InputStream inputStream = Resources .getResourceAsStream(resource );
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream );
*//获取 SqlSession
try *(SqlSession session =sqlSessionFactory .openSession()) {
//获取 Mapper接口
AdminMapper mapper *=session *.getMapper(AdminMapper .class);
//执行查询
Admin admin =mapper .selectAdminById(name );
*//输出结果
if (admin != null) {
resp *.getWriter().println("ID: " *+admin .getId());
resp *.getWriter().println("用户名: " *+admin .getUsername());
resp *.getWriter().println("密码: " *+admin .getPassword());
} else {
resp *.getWriter().write("111111no");
}
} catch *(Exception e ) {
e .printStackTrace();
resp *.getWriter().write("shibai");
}
}
}
目录结构:

流程:
- mybatis-config.xml
(最先被加载)程序启动时,MyBatis 首先读取该核心配置文件,解析数据源、事务管理和 Mapper 路径等信息,为后续创建SqlSessionFactory做准备。 - SelectServlet.java (核心执行代码)
(接收请求后执行)当 Servlet 收到请求(doGet 方法被调用)时:- 先加载mybatis-config.xml 创建SqlSessionFactory
- 再通过SqlSessionFactory 获取SqlSession
这是运行时触发查询的起点。
- AdminMapper.java
(获取代理对象时使用)通过*SqlSession.getMapper(AdminMapper.class)*获取接口的动态代理对象,此时 MyBatis 会关联接口与对应的映射文件。 - AdminMapper.xml
(执行 SQL 时使用)调用AdminMapper.selectAdminById() 方法时,MyBatis 通过namespace +id找到该文件中定义的 SQL 语句,替换参数后执行查询。 - Admin.java
(结果返回时使用)SQL 执行完成后,MyBatis 根据resultType 配置,将数据库返回的结果集自动映射为Admin对象,最终在 Servlet 中被处理并响应。
数据流向链路
请求触发 → SelectServlet加载mybatis-config.xml → 创建SqlSessionFactory → 获取SqlSession → 获取AdminMapper代理对象 → 调用方法匹配AdminMapper.xml中的SQL → 执行SQL查询 → 结果映射为Admin对象 → 响应结果
安全注入例子:
1、安全写法: select * from admin where id = #{id}

拿sqlmap跑一下看看是否有能注入 ,这里是没有的

2、不安全写法:select * from admin where id = ${id}
在AdminMapper.xml 写的查询语句是$

拿sqlmap跑一下看看是否有能注入 ,这里是有的
命令: (要进到sqlmap目录里面打开cmd输入下面命令)
python sqlmap.py -u "http://localhost:8080/mybatis_demo_war_exploded/sql?id=1"

#Spring JPA
由于涉及到开发框架,后续讲到,安全基本和Hibernate相似