day01
什么是代理
就好比于中介 让客户端通过代理对象访问目标对象
这样做的好处是在目标对象实现的基础上 增强额外功能的操作
什么是静态代理
静态代理中,我们对目标对象的每个方法的增强都是手动完成的, 从 JVM 层面来说, 静态代理在编译时就将接口、实现类、代理类这些都变成了一个个实际的 class 文件。
静态代理实现步骤:
1,定义一个接口及其实现类;
2,创建一个代理类同样实现这个接口
3,将目标对象注注入进代理类,然后在代理类的对应方法调用目标类中的对应方法。
什么是动态代理
动态代理: (java中动态代理有两种实现方式 JDK动态代理, CGLIB动态代理 )
JDK动态代理实现步骤:(在java类中只有实现了接口,才能使用JDK动态代理)
定义一个接口及其实现类;
自定义 InvocationHandler 并重写invoke方法,在 invoke 方法中我们会调用原生方法(被代理类的方法)并自定义一些处理逻辑;
通过 Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) 方法创建代理对象;
通过一个接口创建多个代理类
动态代理步骤:
1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法
2.创建被代理的类以及接口
3.通过Proxy的静态方法
newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理
4.通过代理调用方法
day 02
表关系
一对多
在多的里面建立外键与其连接
建立外键 constraint 外键名称 foreign key 外键列名 reference 主表名 主表列名
多对多
要建立三张表 至少包含两外键 对应关键两方的主键
一对一
在任意一方建立外键 关联对方主键 并设置唯一
笛卡尔积 集合所有表组合的情况
清除笛卡尔积方式 添加条件 添加外键列名= 主表 列名 id
内连接 用左边表去匹配右边表记录 从表.外键=主表.主键
隐式内连接
select 字段名 from 左表名 ,右表名 where 条件
显示内连接
select 字段名 from 左表 inner join 右表 on条件
内连接 查询步骤
1 确定查询哪些表
2 确定表连接的条件
3 确定查询的条件
4确定查询的字段
左外连接
select 字段名 from左表 left join 右表 on 条件
用左表记录去匹配右表记录 如果符合条件显示 否则显示null 可以理解为在内连接基础上左表信息全部显示
右外连接
select 字段名 from 左表 right join 右表 on 条件
用右表的记录匹配左表的记录 如果符合条件显示 否则显示null 可以理解为在内连接基础上右表信息全部显示
子查询
一个查询的结果作为另一个查询的条件
有查询嵌套的称为子查询
子查询需要带括号
子查询结果是单行单列
select 查询字段 from 表名 where 字段=(子查询)
子查询结果是单列 多行
select 查询字段 from 表名 where 字段 in (子查询)
子查询结果是多行多列
select 查询字段 (子查询) from 表名 where 条件
事物
事物 在开发中 处理业务 里面的sql语句 必须同时成功 事物执行是一个整体 所有sql必须成功 只要有一条异常 所有sql语句都要回滚 整个业务失败
开启事物 start transaction
提交事物 commit
回滚事物 rollback
事物的四大特性
ACID
原子性(Atomicity) 每个事物都是一个整体 不可再分 要么同时执行成功 要么同时执行失败
一致性(Consistency) 事物在执行前后 数据库的状态保持一致 就好比转账 前后总金额必须保持一致
隔离性(Isolation) 事物与事物之间不应该互相影响 执行时保持隔离状态
持久性(Durability) 事物一旦执行成功 对数据库的修改是持久的 就算关机也是保存下来的
mysql数据库的四种隔离级别
1 读未提交 隔离级别 read uncommitted 脏读 不可重复读 读取到未提交的事物
2 读已提交 隔离级别 read committed 不可重复读 读已提交的事物
3 可重复读 隔离级别 repeatable read 可重复读
4 串行化 隔离级别 serializable
前三个都会出现幻读
一个事务中两次读取的数量不一致 要求在一个事务中 多次读取的数量是一致的 这是insert和delete引发的问题
day03
什么是JDBC
java连接数据库的规范
JDBC核心思想
java定义了访问数据库的接口 可为多种关系型数据库提供统一的访问方式
JDBC开发步骤
1 导包 注册驱动
Class.forName(" com.mysql.jdbc.Driver ")
2 获取数据库连接对象
DriverManager.getConnection("jdbc:mysql://localhost :3306/数据库名","username","password")
3 准备sql语句
String sql="";
4 获取执行对象
Statement
5执行sql
如果是DQL语句用executequery
如果是DML语句用executeupdate
6 处理结果
如果是查询 返回修改的Resultset结果集
如果是增删改 返回的是修改的行数
7释放资源
也可以封装成工具类 方便调用
先编写配置文件
在src目录下 创建 resource 文件
eg
driverclassname=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/my2203?useSSL=false
username=root
password=1234
在工具类中 创建 properties集合读取配置文件 到prop集合
eg:
InputStream inputStream = conjdbc.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties prop= new Properties();
prop.load(inputStream);
根据键获取值
driverclassname =prop.getProperty("driverclassname");
url= prop.getProperty("url");
username= prop.getProperty("username");
password=prop.getProperty("password");
第一步先注册驱动
Class.forName(driverclassname);
上面这些都在静态代码块内执行
第二步创建一个返回值为连接对象的方法
eg
public static Connection getconnection( ) throws SQLException {
Connection connection = DriverManager.getConnection(url, username, password);
return connection;
}
第三步创建一个释放资源的方法
eg:
public static void close(Statement stat,Connection conn){
close(null,stat,conn);
}
public static void close(ResultSet rs, Statement sta,Connection conn){
if(rs!=null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(sta!=null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
day04
JDBC使用preparedStatement 预编译对象操作数据
1,导包
2 注册驱动
3 获取数据库连接对象
4 准备好sql语句 (预编译对象的sql语句可以使用占位符?表示)
5获取预编译对象 将sql语句发送给数据库
6 通过预编译对象参数赋值 (可以用set数据类型(占位符?的索引 赋值的内容 ))
7 释放资源
preparedStatement的优点
可以防止sql注入的问题 是动态的sql 效率更高
statement和preparedStatement的区别
前一个 执行sql语句每一次都要发一次 和后者相比 效率低
数据库性能的优化就是减少交互的次数
后者 预编译对象 执行参数化的sql 直接发送给数据库 数据库会进行校验(参数类型 以及参数字段是哪一列 然后保存在预编译对象中 可不断重新赋值) 效率高
利用Druid获取数据源的操作
1,导包
2,在连接池配置配置文件
eg:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/my2203?useSSL=false
username=root
password=1234
initialSize=5 //初始化连接池数量
maxActive=10// 设置最大连接数
maxWait=3000// 最大等待时间为三秒
3,读取配置文件
eg:
InputStream inputStream = druidDemo.class.getClassLoader().getResourceAsStream("druid.properties");// 获取配置文件
Properties pro= new Properties();
pro.load(inputStream);//将配置文件读取到集合中
DataSource dataSource = DruidDataSourceFactory.createDataSource(pro);// 通过德鲁伊数据库工厂传入集合分件 创建数据源对象
、
也可以加入Threadlocal 执行
threadlocal 里有 set()添加连接
get()获取链接
remove()删除连接
day05
Commons-dbutils 工具类库
DbUtils :提供如关闭连接、装载JDBC驱动程序等常规工作的工具类,里面的所有方法都是静态的(关闭资源、加载驱动)。将jdbc的操作进行简单封装,操作数据库的代码更加简便高效。
使用步骤:
1 导入核心的jar包 commons-dbtils.jar
mysql驱动jar包
连接池--druid的jar包
junit单元测试:核心包junit.jar以及依赖包
2 有关commons-dbtils.jar 核心接口以及核心类有哪些
执行对象:操作数据库
org.apache.commons.dbutils.QueryRunner 里面封装就是PreparedStatement 两个通用的方法
query(xxx,ResultSetHandler rsh):针对dql语句来完成查询操作
update(xxx,xx):针对dml域操作: insert into,update,delete from .... 核心接口:ResultSetHandler:针对结果集的处理
有很多实现类:
BeanListHandler:将查询的多条记录封装到list集合中
BeanHandler:将查询的结果其中某条记录封装到一个java实体类中
ScalarHandler:查询单行数据/查询总记录数 可以使用聚合函数:
select count(id字段) from 表名 ;
查询总记录数的返回值使用int 和long都可以
JDBC事物
connetion.setautocommit()开启事物的方法 值如果为true 则为自动提交 false 手动提交
connection.rollback()事物回滚 当出现异常时 回滚到最初
connection.commit()提交事物