1. 数据库的事务
什么是事务 在实际业务操作过程中,可能同时需要执行多张表的sql语句或者一张表的多个sql(update,delete,insert into)使用事务将多个sql语句进行管理,如果整个sql执行没问题,提交事务(表示整个完成);如果有问题,回滚事务(撤销这个sql语句的所有操作,回滚到原来起始点,操作sql之前的操作)
1.1 事务特点 ACID
- 原子性(Atomicity) : 操作多个sql,要么同时执行成功或者要么同时执行失败
- 一致性(Consistency) : 频繁进行写入操作时,保证数据内容一致(针对具体的业务操作)
- 隔离性(Isolation) : 事务和事务之间是独立的,互不影响的
- 持久性(Durability) : 事务在提交commit之后, 对数据的添加,修改,删除是永久性的
1.2 数据库的隔离级别
read uncommitted 读未提交,会造成"脏读" read committed 读已提交,能有效防止"脏读",但会出现"不可重复读" repeatable read 可重复读,mysql默认级别,有效防止"脏读"和"不可重复读",但是可能会出现"幻读"的问题 serializable 串行化
start transaction
执行sql语句
commit
rollback
SELECT @@tx_isolation ;
set global transaction isolation level 级别的名称;
select tranaction_isolation
2. JDBC
Java Database Connectivity : Java数据库连接 使用Java语言编写的应用程序直接操作数据库,对数据库表进行添加,删除,修改,查询 sun提供的接口, 数据库厂商提供数据库驱动jar包(sun提供的接口的实现类)
2.1 JDBC原生操作
public class JDBCDemo {
@SuppressWarnings("all")
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection root = DriverManager.getConnection("jdbc:mysql://localhost:3306/库名", "用户名", "密码");
Statement statement = root.createStatement();
String sql = "insert into student (name, gender) values('张三','男')";
int count = statement.executeUpdate(sql);
System.out.println("共影响了" + count + "行");
statement.close();
root.close();
}
}
2.2 自定义工具类
public class JDBCUtils {
private static String url = null;
private static String user = null;
private static String password = null;
private JDBCUtils() {
}
static {
try {
InputStream resourceAsStream = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties prop = new Properties();
prop.load(resourceAsStream);
url = prop.getProperty("url");
user = prop.getProperty("user");
password = prop.getProperty("password");
Class.forName(prop.getProperty("driverClass"));
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection() {
try {
return DriverManager.getConnection(url, user, password);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
public static void close(ResultSet resultSet, Statement statement, Connection connection){
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
public static void close(Statement statement, Connection connection) {
close(null, statement, connection);
}
}
2.3 Statement来模拟用户登录操作,有什么弊端
Statement 本身执行的静态sql语句—>存在SQL拼接,造成sql注入! 当前表中只有两位用户 使用statement来模拟用户登录,sql语句中存在拼接,输入错误的用户名及密码,依然显示登录成功,所以使用statement来执行sql语句,是不安全的
2.4 PrepareStatement
以后不会用Statement,以后都是PreparedStatement预编译对象
@Override
public Employee selectEmpById(int id) throws SQLException {
Employee employee = null;
Connection connection = JDBCUtils.getConnection();
String sql = "select * from employee where id = ? ;" ;
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,id);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
employee = new Employee();
employee.setId(resultSet.getInt("id"));
employee.setName(resultSet.getString("name"));
employee.setAge(resultSet.getInt("age"));
employee.setGender(resultSet.getString("gender"));
employee.setAddress(resultSet.getString("address"));
employee.setBirthday(resultSet.getDate("birthday"));
}
JDBCUtils.close(resultSet, preparedStatement, connection);
return employee;
}
2.5 Statement 和PreparedStatement的区别
共同点:
能够将sql语句发送给数据库进行操作,都称为执行对象
后者继承前者
不同点:
1)是否能够造成SQL注入
Statement操作的是静态sql语句,存在sql语句的字符串拼接,会存在安全漏洞,造成SQL注入
PreparedStatement预编译对象,发送的sql数据,是一种参数化sql,不存在sql拼接,相对于Statement更安全,不会造成SQL注入
2)执行sql语句效率的区别
Statement执行sql语句的效率比较低
PreparedStatement执行sql语句的效率相对来说比较高
Statement是执行静态sql语句,存在sql语句拼接,容易出现sql注入的问题
PreparedStatement可以对sql语句进行预编译,我们只需要填入相关参数,
有效防止了sql注入的问题
2.6 JDBC控制事务
public class JdbcDemo {
public static void main(String[] args) {
Connection conn = null ;
PreparedStatement ps = null ;
PreparedStatement ps2 = null ;
try {
conn = JdbcUtils.getConnection();
conn.setAutoCommit(false) ;
String sql1 = "update account set balance = balance -? where id= ? " ;
String sql2 = "update account set balance = balance +? where id = ?" ;
ps = conn.prepareStatement(sql1);
ps.setInt(1,500);
ps.setInt(2,3);
ps2 = conn.prepareStatement(sql2);
ps2.setInt(1,500) ;
ps2.setInt(2,4);
int count = ps.executeUpdate();
int count2 = ps2.executeUpdate();
System.out.println(count+"---"+count2);
conn.commit();
System.out.println("转账成功");
} catch (ArithmeticException throwables) {
try {
conn.rollback();
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
}
throwables.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
JdbcUtils.close(ps,conn);
JdbcUtils.close(ps2,conn);
}
}
}
2.7 数据库连接池概念以及使用步骤
跟线程池一样,都属于"池化技术"
早期的dbcp
c3p0
现在使用阿里提供的连接池 Druid 德鲁伊(为监控而生)
提供连接池的jar包 druid.jar
后期使用sun提供的接口---java.sql.DataSource(数据源接口) 代替DriverManager
public Connection getConnection() ; 连接池的jar包来实现接口
连接池的好处
会创建一个固定的可重复用的连接对象,当某个线程使用完毕这个连接对象,
将连接对象归还连接池中!
使用步骤
1)导入druid的jar包
2)准备好连接池的配置文件
配置好数据库的连接信息以及一些连接参数(最大连接数量, 超时时间, 空闲数量)
3)创建连接池对象--->数据源DataSource接口不能实例化,
com.alibaba.druid.pool.DruidDataSource它具体类,可以创建
4)DruidDataSourceFactory 连接池数据源工厂类
加入Druid的好处
1)资源重用; 针对连接池提供的参数----初始化连接数量,最大激活数量,最大等待时间
等等, 就是"共享资源"----->"资源池"
2)连接对象被释,将连接对象归还给连接池,大大提高系统性能!(防止资源浪费)
3)防止连接对象被泄露掉,强制将使用完的连接对象必须归还给连接池!
4)Druid连接池 为监控而生(一直在监听资源池中的连接数量)
2.8 加入连接池后对JDBCUtils的优化
public class JdbcUtilsWithDruid {
private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
private static DataSource dataSource;
private JdbcUtilsWithDruid() {
}
static {
try {
Properties properties = new Properties();
InputStream resourceAsStream = JdbcUtilsWithDruid.class.getClassLoader().
getResourceAsStream("druid.properties");
properties.load(resourceAsStream);
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static DataSource getDataSource() {
return dataSource;
}
public static Connection getConnection() {
Connection conn = threadLocal.get();
try {
if (conn == null) {
Connection connection = dataSource.getConnection();
threadLocal.set(connection);
return connection;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return conn;
}
public static void close(ResultSet rs, Statement stmt, Connection conn){
if (rs != null) {
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
threadLocal.remove();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
public static void close(Statement stmt,Connection conn){
close(null,stmt,conn);
}
public static void main(String[] args) {
DataSource dataSource = JdbcUtilsWithDruid.getDataSource();
System.out.println(dataSource);
Connection connection = JdbcUtilsWithDruid.getConnection();
System.out.println(connection);
}
}
2.9 DButils
common-Dbutils的使用步骤
1)导入dbutils.jar包
2)创建执行对象
public QueryRunner(DataSource ds)----->自动提交方式 (前期都用这个)
public QueryRunner() ----->空参构造---手动提交(牵扯事务的使用)
3)准备sql语句 update/delete/insert /select...
4)执行
QueryRunner针对update/delete/insert----通用方法
int update(String sql,Object[]...params):参数1:sql语句 参数2:就是可变参数,给占位符赋值 (属于自动提交更新)
int update(Connection conn,String sql,Object[]...params) 更新方法
//通用的查询方法
public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params)
//参数1:sql语句
//参数2:结果集的处理---接口--->需要子实现类
BeanListHandler<T> :将数据库查询的多条记录--->封装List<T>集合中
BeanHandler<T>:将数据库中查询的某条记录---->封装某个实体类中
ScalarHandler<T>:将数据库查询的记录--->封装Object类中---返回的数据单行单列的数据(聚合函数)---->查询总记录数
//参数3:可变参数,在select语句如果有条件查询,传入条件值;如果没有参数,不需要传!
引入DButils后的JDBCUtils
public class JdbcUtilsByDruid {
private static ThreadLocal<Connection> threadLocal = new ThreadLocal();
private static DataSource dataSource;
private JdbcUtilsByDruid() {
}
static {
try {
Properties properties = new Properties();
properties.load(new FileInputStream("src/druid.properties"));
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static DataSource getDataSource() {
return dataSource;
}
public static Connection getConnection() {
try {
Connection connection = threadLocal.get();
if (connection == null) {
connection = dataSource.getConnection();
threadLocal.set(connection);
}
return connection;
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
}
3. HTML
Hypert Text Markup Language:超文本记语言
网页标签
常见的文本标签
1)标题标签h1-h6 :从大到小的标题
2)段落标签 p
3)滚动标签marquee
属性:
behivour:滚动的方式
slide:默认从右滚到左边结束
alternate:默认从右滚动到左边然后来回滚动
默认值? scroll:?穿梭滚动
srollamount:滚动速度,正数值 值越大,速度越快
direction:滚动方向,默认left,从右到左
rigth从左到右
bgcolor:背景颜色
4) div标签和span标签
div:占一行空间
span:行内标签---在一行上,不会换行
div----层级布局去使用 div+Css-----完成页面布局
5)引用标签:blockquote ----
针对某个段落的文字进行解释说明,自带段落缩进的效果
6)原样输出 pre标签,按照文本的原先格式---原封不动的展示!
7)上下标标签 sup和sub
上标 sup使用居多----结合html转义字符
版权所有 © ----?
注册商品 ®
8)无序列表 ul li
ul
type属性 列表项前的标记 默认值 disc(实心原点)
circle:空心原点
square:正方形
9)有序列表
ol li
ol里面 type属性的默认值从1开始
10)超链接标签 a标签
属性:href:连接到本地地址或者服务器地址(url地址:同意资源定位符)
协议://域名/地址
协议
http协议--https--联网
thunder://迅雷协议
file://本地文件协议
后面用的服务器 tomcat --window系统本地部署
linux系统---远程部署
http://localhost:8080/findproduct
127.0.0.1
域名 -- 绑定 -- ip地址
target属性:
打开新页面地址的方式
默认值:_self 当前页面直接打开
_blank:新建一个窗口打开
11)超链接
<a ></a>
属性:
href: 连接到本地地址或者服务器地址(url地址:统一资源定位符)
协议://域名/地址
http://
thunder://迅雷协议
file://本地文件协议
target: 打开新页面地址的方式
默认值: _self 当前页面直接打开
_blank 新建窗口打开
超链接应用
<a href="跳转url地址" target="打开方式">文本内容</a>
锚链接的使用
同一个页面使用
a)创建一个锚点 (创建一个标记)
<a name="锚点名称"></a>
b)创建跳转连接
<a href="#锚点名称">跳转</a>
在不同页面上使用
a)在另一个页面某个位置创建一个锚点 (创建一个标记)
<a name="锚点名称"></a>
b)在当前页面中,进行跳转链接
<a href="另一个页面地址#锚点名称">跳转</a>
12)表格标签 table
<table></table>
html语言中只有行的概念 tr, 没有列的概念 td : 理解为列
tr 一行中有多少个td
属性:
要表格边框线 border 边框线 单位px
表格对齐方式 align left right center
bgcolor 背景色
width和height 宽度和高度
cellspacing 设置单元格和边框线的距离
子标签
tr : 行
td : 是一个普通单元格
th : 是一个特殊单元格(表格的表头 自动居中,加粗)
caption : 表格的标题标签
普通单元格合并
colspan : 合并列,当前单元格占的格子数
rowspan : 合并行,当前单元格占的格子数
13)表单标签 form
<form></form>
表单场景 : 注册或者登录
注册--将用户的信息提交后端服务器上,校验用户信息是否存在,如果存在,不能注册;
登录---将用户信息提狡服务器上,查看是否有这个用户,有才能的登录;
表单提交的时候,里面所有的表单项标签必须有一个name属性
---后端服务器才能知道用户的输入内容
属性:
action : url地址 将表单中的表单项的数据提交到后台服务器地址上
method : 表单的提交工具
get/post
常见表单标签的表单项
跟input 标签相关的表单项
input type = "text" 文本输入框
input type = "password" 密码输入框
input type = "radio" 单选按钮-
input type = "checkbox" 复选框
input type = "date" 日期组件
input type = "file" 文件上传组件
普通按钮
input type = "button" 必须和value="属性值"
特殊按钮
input type = "submit" 表单提交按钮
input type = "reset" 重置按钮, 清空表单项
select : 下拉菜单
option : 下拉选项
14)框架标签 frame
整个结构是2个或者2个以上的html组成,不能使用frame(只能包含一个html页面)
需要使用 frameset框架集,不能body共存,要么在加载在他前面,或者删除body
15)图像标签 img
scr属性 : 连接到图片地址(可以是本地图片或者网络图片)
width: 图片宽度 指定像素px或者百分比(占整个宽度分辨率的百分之几)
heigh: 图片高度 指定像素px或者百分比(占整个宽度分辨率的百分之几)
title : 当鼠标悬浮在图片上的时候,有提示信息
alt : 替代文本 当这个图片失效(地址找不到),他会给一个信息描述
|