本文主要是介绍java基础知识点随笔,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
SQL结构化查询语言复习
1.添加
insert into user(id,birthday,sex,address) values (, , , ,);
2.修改
update (表名) set 列名=值1,列名=值2... where 条件
update user set username="tony",sex="male" where id=1;
注意:如果不加任何条件 会将表中所有的数据都修改
3.删除一条数据
delete from 表名 where 条件;
注意:如果要删除整张表建议使用truncate table 表名 它会先删除整张表然后创建一张空表
4.查询语句
单表查询
select 字段列表
from 表名称
where 条件语句
group by 分组条件
having 分组之后的条件
order by 按照什么排序
limit 分页查询
多表查询
1.内连接查询 用where语句消除无用数据
----查询员工信息,以及其所属部门-----
SELECT
t1.name, -- 员工表的姓名
t1.gender,-- 员工表的性别
t2.name -- 部门表的名称
FROM
emp t1,
dept t2
WHERE
t1.`dept_id` = t2.`id`;
2.外连接查询
左外连接查询 显示左表中的所有信息以及右表中和满足条件的数据
-- 查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示部门名称
SELECT
t1.*,t2.`name`
FROM
emp t1 LEFT JOIN dept t2
ON
t1.`dept_id` = t2.`id`;复杂结构化查询语句举例
一对多
查询所有用户以及每个用户包含的账户信息 用户和账户是一对多的关系 一个用户可以有多个账户
SELECT
t1.*,
t2.`ID` AS aid,
t2.`MONEY` AS money
FROM
USER t1 LEFT JOIN
account t2
ON
t1.`id` = t2.`UID`;
一对一
查询账户所有信息以及每个账户对应的用户的信息 账户和用户是一对一的关系 一个账户只能所属与一个用户
SELECT
t1.*,
t2.username
FROM
account t1 LEFT JOIN
USER t2
ON
t1.`UID` = t2.`id`;
多对多
用户和角色的关系 一个用户可以有多个角色 一个角色也可以所属与多个用户 所以需要第三张表作为中转 user_role表
查询用户表中的所有信息 以及每个用户对应的角色信息
SELECT
t1.*,
t3.id AS rid,
t3.role_name,
t3.role_desc
FROM
USER t1 LEFT JOIN user_role t2
ON
t1.id=t2.uid LEFT JOIN role t3
ON
t2.rid = t3.id;
事务
什么是事务
事务就是一个并发控制单位,包含多个步骤的操作被事务所管理,要么同时成功,要么同时失败。
事务中的四大特性?
- 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
- 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
- 隔离性:多个事务之间。相互独立。
- 一致性:事务操作前后,数据总量不变
不考虑隔离会产生的三个问题?
1,脏读
脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。
当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。例如:用户A向用户B转账100元,对应SQL命令如下
update account set money=money+100 where name=’B’; (此时A通知B) update account set money=money - 100 where name=’A’;
当只执行第一条SQL时,A通知B查看账户,B发现确实钱已到账(此时即发生了脏读),而之后无论第二条SQL是否执行,只要该事务不提交,则所有操作都将回滚,那么当B以后再次查看账户时就会发现钱其实并没有转。
2,不可重复读
不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。
例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。
不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。
在某些情况下,不可重复读并不是问题,比如我们多次查询某个数据当然以最后查询得到的结果为主。但在另一些情况下就有可能发生问题,例如对于同一个数据A和B依次查询就可能不同,A和B就可能打起来了……
3,虚读(幻读)
幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。
幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。
解决上述问题的方案?
设置不同的隔离级别就能解决上述问题。
隔离级别:
- read uncommitted:读未提交产生的问题:脏读、不可重复读、幻读
- read committed:读已提交 (Oracle) 产生的问题:不可重复读、幻读
- repeatable read:可重复读 (MySQL默认) 产生的问题:幻读
- serializable:串行化 可以解决所有的问题
注意:隔离级别从小到大安全性越来越高,但是效率越来越低
数据库查询隔离级别:select @@tx_isolation;
数据库设置隔离级别:set global transaction isolation level 级别字符串;
动态代理
动态的代理的特点
在不改变源码的基础上,对一个类中的方法进行增强。其特点是:字节码随用随创建,随用随加载。它与静态代理的区别也在于此。因为静态代理是字节码一上来就创建好,并完成加载。装饰者模式就是静态代理的一种体现。
动态代理的两种实现方式
package com.itheima.cglib;/*** 一个生产者*/
public class Producer {/*** 销售* @param money*/public void saleProduct(float money){System.out.println("销售产品,并拿到钱:"+money);}/*** 售后* @param money*/public void afterService(float money){System.out.println("提供售后服务,并拿到钱:"+money);}
}
基于接口的动态代理
package com.itheima.proxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;/*** 模拟一个消费者*/
public class Client {public static void main(String[] args) {final Producer producer = new Producer();/*** 动态代理:* 特点:字节码随用随创建,随用随加载* 作用:不修改源码的基础上对方法增强* 分类:* 基于接口的动态代理* 基于子类的动态代理* 基于接口的动态代理:* 涉及的类:Proxy* 提供者:JDK官方* 如何创建代理对象:* 使用Proxy类中的newProxyInstance方法* 创建代理对象的要求:* 被代理类最少实现一个接口,如果没有则不能使用* newProxyInstance方法的参数:* ClassLoader:类加载器* 它是用于加载代理对象字节码的。和被代理对象使用相同的类加载器。固定写法。* Class[]:字节码数组* 它是用于让代理对象和被代理对象有相同方法。固定写法。* InvocationHandler:用于提供增强的代码* 它是让我们写如何代理。我们一般都是些一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的。* 此接口的实现类都是谁用谁写。*/IProducer proxyProducer = (IProducer) Proxy.newProxyInstance(producer.getClass().getClassLoader(),producer.getClass().getInterfaces(),new InvocationHandler() {/*** 作用:执行被代理对象的任何接口方法都会经过该方法* 方法参数的含义* @param proxy 代理对象的引用* @param method 当前执行的方法* @param args 当前执行方法所需的参数* @return 和被代理对象方法有相同的返回值* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//提供增强的代码Object returnValue = null;//1.获取方法执行的参数Float money = (Float)args[0];//2.判断当前方法是不是销售if("saleProduct".equals(method.getName())) {returnValue = method.invoke(producer, money*0.8f);}return returnValue;}});proxyProducer.saleProduct(10000f);}
}
基于子类的动态代理
package com.itheima.cglib;import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;/*** 模拟一个消费者*/
public class Client {public static void main(String[] args) {final Producer producer = new Producer();/*** 动态代理:* 特点:字节码随用随创建,随用随加载* 作用:不修改源码的基础上对方法增强* 分类:* 基于接口的动态代理* 基于子类的动态代理* 基于子类的动态代理:* 涉及的类:Enhancer* 提供者:第三方cglib库* 如何创建代理对象:* 使用Enhancer类中的create方法* 创建代理对象的要求:* 被代理类不能是最终类* create方法的参数:* Class:字节码* 它是用于指定被代理对象的字节码。** Callback:用于提供增强的代码* 它是让我们写如何代理。我们一般都是些一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的。* 此接口的实现类都是谁用谁写。* 我们一般写的都是该接口的子接口实现类:MethodInterceptor*/Producer cglibProducer = (Producer)Enhancer.create(producer.getClass(), new MethodInterceptor() {/*** 执行北地阿里对象的任何方法都会经过该方法* @param proxy* @param method* @param args* 以上三个参数和基于接口的动态代理中invoke方法的参数是一样的* @param methodProxy :当前执行方法的代理对象* @return* @throws Throwable*/@Overridepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {//提供增强的代码Object returnValue = null;//1.获取方法执行的参数Float money = (Float)args[0];//2.判断当前方法是不是销售if("saleProduct".equals(method.getName())) {returnValue = method.invoke(producer, money*0.8f);}return returnValue;}});cglibProducer.saleProduct(12000f);}
}
Spring中基于XML的AOP配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 配置srping的Ioc,把service对象配置进来--><bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean><!--spring中基于XML的AOP配置步骤1、把通知Bean也交给spring来管理2、使用aop:config标签表明开始AOP的配置3、使用aop:aspect标签表明配置切面id属性:是给切面提供一个唯一标识ref属性:是指定通知类bean的Id。4、在aop:aspect标签的内部使用对应标签来配置通知的类型我们现在示例是让printLog方法在切入点方法执行之前之前:所以是前置通知aop:before:表示配置前置通知method属性:用于指定Logger类中哪个方法是前置通知pointcut属性:用于指定切入点表达式,该表达式的含义指的是对业务层中哪些方法增强切入点表达式的写法:关键字:execution(表达式)表达式:访问修饰符 返回值 包名.包名.包名...类名.方法名(参数列表)标准的表达式写法:public void com.itheima.service.impl.AccountServiceImpl.saveAccount()访问修饰符可以省略void com.itheima.service.impl.AccountServiceImpl.saveAccount()返回值可以使用通配符,表示任意返回值* com.itheima.service.impl.AccountServiceImpl.saveAccount()包名可以使用通配符,表示任意包。但是有几级包,就需要写几个*.* *.*.*.*.AccountServiceImpl.saveAccount())包名可以使用..表示当前包及其子包* *..AccountServiceImpl.saveAccount()类名和方法名都可以使用*来实现通配* *..*.*()参数列表:可以直接写数据类型:基本类型直接写名称 int引用类型写包名.类名的方式 java.lang.String可以使用通配符表示任意类型,但是必须有参数可以使用..表示有无参数均可,有参数可以是任意类型全通配写法:* *..*.*(..)实际开发中切入点表达式的通常写法:切到业务层实现类下的所有方法* com.itheima.service.impl.*.*(..)--><!-- 配置Logger类 --><bean id="logger" class="com.itheima.utils.Logger"></bean><!--配置AOP--><aop:config><!--配置切面 --><aop:aspect id="logAdvice" ref="logger"><!-- 配置通知的类型,并且建立通知方法和切入点方法的关联--><aop:before method="printLog" pointcut="execution(* com.itheima.service.impl.*.*(..))"></aop:before></aop:aspect></aop:config></beans>
HTTP协议复习 3月4号
概念:Hyper Text Transfer Protocol 超文本传输协议
- 传输协议:定义了,客户端和服务器端通信时,发送数据的格式
- 特点:
- 基于TCP/IP的高级协议
- 默认端口号:80
- 基于请求/响应模型的:一次请求对应一次响应
- 无状态的:每次请求之间相互独立,不能交互数据
- 历史版本:
- 1.0:每一次请求响应都会建立新的连接
- 1.1:复用连接
请求消息格式 request
POST /login.html HTTP/1.1 请求行
Host: localhost 请求头
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0)
Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,enUS;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://localhost/login.html
Connection: keep-alive
Upgrade-Insecure-Requests: 1请求空行
username=zhangsan 请求体
- 数据格式包含,请求行,请求头,请求空行和请求体。请求行中包含请求方式,url,请求协议和请求协议的版本。请求头中包含各种信息,是通过键值对的形式。请求体中封装着请求参数,但是只post请求方式才有请求体,get方式请求参数在请求行中。
- request 可以获取虚拟路径 String getContextPath() , 获取ServletContext从而获取绝对路径 getRealpath()
- request 可以实现请求转发 一种在服务器内部转发资源的方式getRequestDispatcher(String path).forward(ServletRequestrequest, ServletResponse response)
响应消息格式 reponse
响应字符串格式
HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Content-Length: 101
Date: Wed, 06 Jun 2018 07:08:42 GMT
- 响应行 协议 版本号 响应状态码
- 响应头
- 响应空行
- 响应体 包含服务器端返回的数据
重定向 redirect 和转发 forward 的区别
- 重定向response.sendRedirect("/day15/responseDemo2")地址栏发生变化,forward地址栏不发生变化
- 重定向可以访问别的服务器的资源,转发只能在本服务器内部转发
- 重定向是两次请求,不可以使用request域共享数据;转发是一次请求,可以使用request域共享数据
路径写法:
相对路径:通过相对路径不可以确定唯一资源
如:./index.html 。不以/开头,以.开头路径ServletContext对象:
规则:找到当前资源和目标资源之间的相对位置关系
./:当前目录
…/:后退一级目录
绝对路径:通过绝对路径可以确定唯一资源
如:http://localhost/day15/responseDemo2/day15/responseDemo2
以/开头的路径
规则:判断定义的路径是给谁用的?判断请求将来从哪儿发出
给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
建议虚拟目录动态获取:request.getContextPath()
超链接,表单提交, 重定向…
给服务器使用:不需要加虚拟目录
转发路径
这篇关于java基础知识点随笔的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!