JDBC
代码步骤
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=1234
-
创建工程,导入驱动jar包:mysql-connector-java-5.1.48.jar
-
编写代码如下
/** * JDBC快速入门 */ public class JDBCDemo { public static void main(String[] args) throws Exception { //1. 注册驱动 //Class.forName("com.mysql.jdbc.Driver"); //2. 获取连接 String url = "jdbc:mysql://127.0.0.1:3306/db1"; String username = "root"; String password = "1234"; Connection conn = DriverManager.getConnection(url, username, password); //3. 定义sql String sql = "update account set money = 2000 where id = 1"; //4. 获取执行sql的对象 Statement Statement stmt = conn.createStatement(); //5. 执行sql int count = stmt.executeUpdate(sql);//受影响的行数 //6. 处理结果 System.out.println(count); //7. 释放资源 stmt.close(); conn.close(); } }
mysql 事务管理
先回顾一下MySQL事务管理的操作:
- 开启事务 : BEGIN; 或者 START TRANSACTION;
- 提交事务 : COMMIT;
- 回滚事务 : ROLLBACK;
MySQL默认是自动提交事务
- Connection几口中定义了3个对应的方法:
conn.setAutoCommit(false);开启事务
conn.commit();提交事务
//程序在出现异常时会执行到这个地方,此时就需要回滚事务
conn.rollback();
ResultSet
- ResultSet(结果集对象)作用:封装了SQL查询语句的结果。ResultSet executeQuery(sql):执行DQL 语句,返回 ResultSet 对象
next()
-
将光标从当前位置向前移动一行 一开始光标指定于第一行前,如图所示红色箭头指向于表头行。当我们调用了
next()
方法后,光标就下移到第一行数据,并且方法返回true,此时就可以通过getInt("id")
获取当前行id字段的值,也可以通过getString("name")
获取当前行name字段的值。如果想获取下一行的数据,继续调用next()
方法,以此类推。 -
代码实现
/** * 执行DQL * @throws Exception */ @Test public void testResultSet() throws Exception { //1. 注册驱动 //Class.forName("com.mysql.jdbc.Driver"); //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写 String url = "jdbc:mysql:///db1?useSSL=false"; String username = "root"; String password = "1234"; Connection conn = DriverManager.getConnection(url, username, password); //3. 定义sql String sql = "select * from account"; //4. 获取statement对象 Statement stmt = conn.createStatement(); //5. 执行sql ResultSet rs = stmt.executeQuery(sql); //6. 处理结果, 遍历rs中的所有数据 /* // 6.1 光标向下移动一行,并且判断当前行是否有数据 while (rs.next()){ //6.2 获取数据 getXxx() int id = rs.getInt(1); String name = rs.getString(2); double money = rs.getDouble(3); System.out.println(id); System.out.println(name); System.out.println(money); System.out.println("--------------"); }*/ // 6.1 光标向下移动一行,并且判断当前行是否有数据 while (rs.next()){ //6.2 获取数据 getXxx() int id = rs.getInt("id"); String name = rs.getString("name"); double money = rs.getDouble("money"); System.out.println(id); System.out.println(name); System.out.println(money); System.out.println("--------------"); } //7. 释放资源 rs.close(); stmt.close(); conn.close(); }
PreparedStatement
- 作用:预编译SQL语句并执行:预防SQL注入问题
sql注入问题
-
sql注入问题案例:select * from tb_user where username = ‘sjdljfld’ and password = ''or ‘1’ = ‘1’ 条件
username = 'sjdljfld' and password = ''
不管是否满足,而or
后面的'1' = '1'
是始终满足的,最终条件是成立的,就可以正常的进行登陆了。 -
用法,多了占位符:#### 使用PreparedStatement改进
@Test public void testPreparedStatement() throws Exception { //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写 String url = "jdbc:mysql:///db1?useSSL=false"; String username = "root"; String password = "1234"; Connection conn = DriverManager.getConnection(url, username, password); // 接收用户输入 用户名和密码 String name = "zhangsan"; String pwd = "' or '1' = '1"; // 定义sql String sql = "select * from tb_user where username = ? and password = ?"; // 获取pstmt对象 PreparedStatement pstmt = conn.prepareStatement(sql); // 设置?的值 pstmt.setString(1,name); pstmt.setString(2,pwd); // 执行sql ResultSet rs = pstmt.executeQuery(); // 判断登录是否成功 if(rs.next()){ System.out.println("登录成功~"); }else{ System.out.println("登录失败~"); } //7. 释放资源 rs.close(); pstmt.close(); conn.close(); }
执行上面语句就可以发现不会出现SQL注入漏洞问题了。那么PreparedStatement又是如何解决的呢?它是将特殊字符进行了转义,转义的SQL如下:select * from tb_user where username = ‘sjdljfld’ and password = ‘'or ‘1’ = '1’,使用转义将中间的部分视为了字符串了
数据库连接池
Driud使用
-
导入jar包 druid-1.1.12.jar
-
编写配置文件如下:
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true username=root password=1234 # 初始化连接数量 initialSize=5 # 最大连接数 maxActive=10 # 最大等待时间 maxWait=3000
使用druid的代码如下:
/** * Druid数据库连接池演示 */ public class DruidDemo { public static void main(String[] args) throws Exception { //1.导入jar包 //2.定义配置文件 //3. 加载配置文件 Properties prop = new Properties(); prop.load(new FileInputStream("jdbc-demo/src/druid.properties")); //4. 获取连接池对象 DataSource dataSource = DruidDataSourceFactory.createDataSource(prop); //5. 获取数据库连接 Connection Connection connection = dataSource.getConnection(); System.out.println(connection); //获取到了连接后就可以继续做其他操作了 //System.out.println(System.getProperty("user.dir")); } }
tomcat
- 下载:Tomcat的官网: https://tomcat.apache.org/ 从官网上可以下载对应的版本进行使用。打开
apache-tomcat-8.5.68
目录就能看到如下目录结构,每个目录中包含的内容需要认识下 - 修改端口:Tomcat默认的端口是8080,要想修改Tomcat启动的端口号,需要修改 conf/server.xml
JSP
- 头文件:<%@ page language=“java” contentType=“text/html; charset=UTF-8” pageEncoding=“UTF-8” %>
jsp 中的三种脚本介绍
- 声明脚本格式如下:
<%!
java 代码
%>
在声明脚本块中,我们可以干 4 件事情
1.我们可以定义全局变量。
2.定义 static 静态代码块
3.定义方法
4.定义内部类
几乎可以写在类的内部写的代码,都可以通过声明脚本来实现 - 表达式脚本格式如下:(表达式脚本可以输出任意类型。)
<%=表达式 %>
表达式脚本 用于向页面输出内容 - 代码脚本如下:
<% java 代码 %>
代码脚本里可以书写任意的 java 语句。
代码脚本的内容都会被翻译到 service 方法中。 - 单行注释和多行注释能在翻译后的 java 源代码中看见。
<%-- jsp 注释 --%>
jsp 注释在翻译的时候会直接被忽略掉
九大内置对象
- 那么 jsp 中九大内置对象分别是:
request 对象 请求对象,可以获取请求信息
response 对象 响应对象。可以设置响应信息
pageContext 对象 当前页面上下文对象。可以在当前上下文保存属性信息
session 对象 会话对象。可以获取会话信息。
exception 对象 异常对象只有在 jsp 页面的 page 指令中设置 isErrorPage=“true” 的时候才会存在
application 对象 ServletContext 对象实例,可以获取整个工程的一些信息。
config 对象 ServletConfig 对象实例,可以获取 Servlet 的配置信息
out 对象 输出流。
page 对象 表示当前 Servlet 对象实例(无用,用它不如使用 this 对象)。
包含,转发
-
静态包含–很常用<%@ include file=“” %>
静态包含是把包含的页面内容原封装不动的输出到包含的位置 -
页面转发–常用<jsp:forward page=“”></jsp:forward><jsp:forward 转发功能相当于
request.getRequestDispatcher(“/xxxx.jsp”).forward(request, response); 的功能。
EL表达式
- 作用:EL 表达式的什么作用:EL 表达式主要是代替 jsp 页面中的表达式脚本在 jsp 页面中进行数据的输出。
<%
request.setAttribute(“key”,“值”);
%>
表达式脚本输出 key 的值是:
<%=request.getAttribute(“key1”)==null?“”:request.getAttribute(“key1”)%>
EL 表达式输出 key 的值是:${key1} EL 表达式的格式是:${表达式}
EL 表达式在输出 null 值的时候,输出的是空串。jsp 表达式脚本输出 null 值的时候,输出的是 null 字符串
EL 表达式的 11 个隐含对象
EL 个达式中 11 个隐含对象,是 EL 表达式中自己定义的,可以直接使用。
变量 类型 作用
pageContext PageContextImpl 它可以获取 jsp 中的九大内置对象
pageScope Map<String,Object> 它可以获取 pageContext 域中的数据
requestScope Map<String,Object> 它可以获取 Request 域中的数据
sessionScope Map<String,Object> 它可以获取 Session 域中的数据
applicationScope Map<String,Object> 它可以获取 ServletContext 域中的数据
param Map<String,String> 它可以获取请求参数的值
paramValues Map<String,String[]> 它也可以获取请求参数的值,获取多个值的时候使用。
header Map<String,String> 它可以获取请求头的信息
headerValues Map<String,String[]> 它可以获取请求头的信息,它可以获取多个值的情况
cookie Map<String,Cookie> 它可以获取当前请求的 Cookie 信息
pageContext 对象的使用
1.协议: ${ req.scheme }
2.服务器 ip:${ pageContext.request.serverName }
3.服务器端口:${ pageContext.request.serverPort }
4.获取工程路径:${ pageContext.request.contextPath }
5.获取请求方法:${ pageContext.request.method }
6.获取客户端 ip 地址:${ pageContext.request.remoteHost }
7.获取会话的 id 编号:${ pageContext.session.id }
JSTL 标签库
- 1、先导入 jstl 标签库的 jar 包。taglibs-standard-impl-1.2.1.jar taglibs-standard-spec-1.2.1.jar
- 2、第二步,使用 taglib 指令引入标签库。<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>
core 核心库使用
- <%–
ii.<c:if />
if 标签用来做 if 判断。
test 属性表示判断的条件(使用 EL 表达式输出)
–%>
<c:if test=“${ 12 == 12 }”>
<h1>12 等于 12</h1>
</c:if> - <%–
iii.<c:choose> <c:when> <c:otherwise>标签
作用:多路判断。跟 switch … case … default 非常接近
choose 标签开始选择判断
when 标签表示每一种判断情况
test 属性表示当前这种判断情况的值
otherwise 标签表示剩下的情况
<c:choose> <c:when> <c:otherwise>标签使用时需要注意的点:
1、标签里不能使用 html 注释,要使用 jsp 注释
2、when 标签的父标签一定要是 choose 标签
–%>
问题
目录问题
- // 读取 jdbc.properties 属性配置文件
InputStream inputStream =
JdbcUtils.class.getClassLoader().getResourceAsStream(“jdbc.properties”);获取不到文件,没加/是当前类所在目录,加了就是项目目录。但是我试了都不行,原来target/classes字节码文件中没有jdbc.properties文件
a标签跳转问题
- 我搜了说是在click方法添加return false就行但是还是不行。这样就行
<a class="delete" href="http://localhost:8080/FinalExam/delete?id=${item.id}" οnclick="return toDelete()">删除</a> <script type="text/javascript"> function toDelete() { return confirm("确定要删除吗?"); }