一:权限如何回答
1:数据库表设计:用户表,角色表,权限表,用户角色表,角色权限表,
2:用户表使用shiro进行权限拦截,
Web.xml
Service.xml配置 拦截路径,
Realm类
控制按钮:在权限表里面进行权限标记,jsp页面判断
Lucene和solr
全文检索:lucene是全文检索工具包
Solr是一个全文检索服务器
Solr整合tomcat,放入tomcat下解压
二:Redis(缓存----非关系型数据库,数据存在内存上,其它关系型数据库数据是存在磁盘上)
三:springboot
四:mybatis如何分页
五:servlet,springMVC,struts2区别
① springMVC的入口是一个servlet,即前端控制器
② struts2的入口是一个filter过滤器,即前端过滤器
② springMVC基于方法开发,传递参数通过形参,
struts2基于类开发,通过类的属性传递参数,
③ springMVC通过modelAndView或者将数据转化成json返回数据,
④ springMVC返回页面???
六:jdbcTempate,jdbc,mybatis,hirbnate区别。
从层次上看,JDBC是较底层的持久层操作方式,而hibernate和MyBatis都是在JDBC的基础上进 行了封装使其更加方便程序员对持久层的操作。
从功能上看,JDBC就是简单的建立数据库连接,然后创建statement,将sql语句传给statement 去执行,如果是有返回结果的查询语句,会将查询结果放到ResultSet对象中,通过对ResultSet对 象的遍历操作来获取数据;Hibernate是将数据库中的数据表映射为持久层的Java对象,实现数据 表的完整性控制;MyBatis是将sql语句中的输入参数和输出参数映射为java对象,放弃了对数据表 的完整性控制,但是获得了更灵活和响应性能更快的优势。
从使用上看,如果进行底层编程,而且对性能要求极高的话,应该采用JDBC的方式;如果要对数据 库进行完整性控制的话建议使用Hibernate;如果要灵活使用sql语句的话建议采用MyBatis框架。
七:spring IOC和AOP
Ioc: 1:概念:控制反转。
2:思想,工厂模式,降低耦合度,举例说明。Factory类
Aop: 1.概念:面向切面编程,
2.好处:在不改变源代码基础上可以增加功能
3.案例(何处用到):1.spring aop管理事物,2.spring aop添加日志 (不用aop,写一个方法,在需要添加 日志时调用该方法)
4.降低了代码的耦合性
八:如何优化sql
1:科学冗余
2:避免三张表以上联查
3:科学索引:索引类型,三种,主键索引,字符串索引,大文本索引。
4:避免过多的计算函数,在Java里面计算
5:避免使用不能用索引的关键字。比如like,in,not in,用exist
九:创建线程和线程池,死锁。
十:set,map等的比较
十一:什么是存储过程,说一下如何创建带参数的存储过程
概念:命名的pl/sql块就是存储过程或者函数,他们存在数据库中,可以为他们指定参数,可以在数据库客户端或者应用程序中调用,
作用:1:模块化便于管理,2:可以提高代码的可重用性,3:他保存在数据库中,而不是本机,所以可以在任意客户端上登录数据库调用,
创建需要create procedure权限
语法:create or replace procedure 过程名称
is|as
begin
... ...
end;
删除存储过程:drop procedure 存储过程名
参数类型:in,out,in out
十二:如何创建视图
创建或修改视图
Creat or replace view 视图名称 as select 语句
删除视图
drop view 视图名称
查询视图(跟普通表一样查询即可)
select * from 视图名称
十三:创建索引
1:单列索引
Creat index 索引名称 on 表名(列名)
2:复合索引
create index emp_idx1 on emp ( ename, job );
先按ename查找,再按job查找
十三:servlet生命周期
1.创建servlet,并调用init方法
2.通过service方法来处理请求。
3.通过destroy来销毁servlet。
当我们创建一个servlet时,第一次访问会创建一个servlet对象,并且调用init方法,init方法只被调 用一次。
开启一个线程调用service方法,再次开启一个线程,再次调用service方法。
服务停止或者servlet对象销毁时,会调用destroy方法
十四:ajax的属性
(1)url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址
(2)type: 要求为String类型的参数,请求方式(post或get)默认为get。
(3)data: 要求为Object或String类型的参数,发送到服务器的数据。如果已经不是字符串,将自动转换为字符串格式。
(4)datatype:要求为String类型的参数,预期服务器返回的数据类型。
(5)success:要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。function(data, textStatus)
(6)error:要求为Function类型的参数,请求失败时被调用的函数。该函数有3个参数。function(XMLHttpRequest, textStatus, errorThrown)
十五:多线程用过没有?你怎么理解锁的?
实现方式:1.继承Thread类 2.实现Runnable接口:每个java对象都有一个锁synchronized对象.而且只有一把钥匙,Java中的每个对象都有一个内置锁,可以使用this关键字作为锁对象,也可以使用所在类的字节码文件对应的Class对象作为锁对象,只有当对象具有同步方法代码时,内置锁才会起作用
线程需要同步时候,需要用到锁synchronized,当多个线程完成功能需要同时获取多个共享资源的时候可能会导致死锁。
十六:知道集合吧,你说说ArrayList与linkedlist还有hashset他们的底层结构都是什么?
ArrayList:动态数组实现, 查找快, 增删慢
LinkedList:链表实现, 增删快, 查找慢
hashset:hashmap实现,数组加链表,查询增删相对较快。
十七:那你能说一下数据库中去重的办法有什么,有多少说多少
select distinct deptno , job from emp;
一、数据库中的去重操作(删除数据库中重复记录的SQL语句)主要有三种方法
(1)、rowid方法
(2)、group by 方法
(3)、distinct方法
1、用rowid方法
根据Oracle带的rowid属性,可以进行判断是否存在重复语句;
(1)、查出表1和表2中name相同的数据
Select * from table1 a
Where rowid !=(select max(rowid)
from table2 b
Where a.name1 = b.name1
And a.name2 = b.name2......)
(2)、删除表1和表2 中name相同的所有数据
Delete from table1 a
Where rowid !=(select max(rowid)
From table2 b
Where a.name1 = b.name1
And a.name2 = b.name2.......)
2、用group by方法
主要用于分组统计,一般都是使用在聚合函数中使用;
(1)、查数据
Select count(num), max(name) from student 列出表中的重复的记录数和学生名字的属性,
Group by num
Having count(num)>1
并按照num分组后找出表中num列出现次数大于一次的。
(2)、删除数据
Delete from student
Group by num
Having count(num)>1
//删除表中num列所有重复的数据
3、用distinct方法
一般用于比较小的表进行去重,会过滤掉多余的重复记录,返回不重复的记录或字段;
(1)、select distinct name
From student
十八:js与jquery的区别等等
jquery就是用JS写的,jquery是js的方法库。
十九:有没有用过连接池,什么是数据库连接池
dbcp,c3p0,德鲁伊
数据库连接池(Connection pooling)是程序启动时建立足够的数据库连接用来连接数据库,将这些数据库链接放入数据库连接池,由spring进行统一的管理。
二十:那你说一下springMVC框架的流程吧
前端控制器接收客户端的请求,前端控制器请求处理器映射器查找处理器,处理器适配器是根据特定的规则去执行handller
处理器处理完成返回modelandview给前端控制器,前端控制器将modelandview传递给视图解析器
二十一:你这个视图解析器是怎样把参数传给用户的(modleAndview的内部构成)
modleAndview.addObject("user",user)
modleAndview.setViewName("user/user.jsp")
二十二:Servlet你应该用过? Servlet里面,redrect和forward啥区别?
Httpservletresponse.sendRedrect:重定向,服务器行为,一次请求,地址栏不变。
RequestDispatcher.forward:请求转发,客户端行为,两次请求,地址栏改变。
二十三. jsp有几大对象?你觉得session和application谁的生命周期长?
session,request,response,page,pageContext,config,exception,application,out
服务器启动:application就一直存在,页面打开或者关闭,session创建或者消失。
二十四:单例模式
懒汉模式===在掉用的时候才new对象(线程不安全-----加上synchronized锁同步一下可解决)
Publicclass singleton{
private Singleton singleton=null;
private singleton(){
};
Public static Singleton getInstance(){
If(singleton=null);
singleton=new Singleton();
Return singleton;
}
}
饿汉模式===管用不用,一上来就先new一个对象
Public class singleton{
Private singleton(){};
Private static final Singleton singleton=new singleton();
Public static Singleton getInstance(){
Return singleton;
}
}
饿汉式和懒汉式区别
从名字上来说,饿汉和懒汉,
饿汉就是类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了,
而懒汉比较懒,只有当调用getInstance的时候,才回去初始化这个单例。
另外从以下两点再区分以下这两种方式:
1、线程安全:
饿汉式天生就是线程安全的,可以直接用于多线程而不会出现问题,
懒汉式本身是非线程安全的,为了实现线程安全有几种写法,分别是上面的1、2、3,这三种实现在资源加载和性能方面有些区别。
2、资源加载和性能:
饿汉式在类创建的同时就实例化一个静态对象出来,不管之后会不会使用这个单例,都会占据一定的内存,但是相应的,在第一次调用时速度也会更快,因为其资源已经初始化完成,
而懒汉式顾名思义,会延迟加载,在第一次使用该单例的时候才会实例化对象出来,第一次调用时要做初始化,如果要做的工作比较多,性能上会有些延迟,之后就和饿汉式一样了。
至于1、2、3这三种实现又有些区别,
第1种,在方法调用上加了同步,虽然线程安全了,但是每次都要同步,会影响性能,毕竟99%的情况下是不需要同步的,
第2种,在getInstance中做了两次null检查,确保了只有第一次调用单例的时候才会做同步,这样也是线程安全的,同时避免了每次都同步的性能损耗
第3种,???classloader?????????instance???????,?????????,????????,??????????????
什么是线程安全?
如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
或者说:一个类或者程序所提供的接口对于线程来说是原子操作,或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题,那就是线程安全的。
二十五:冒泡排序
Public static void main(String[] args){
Int t;
Int array[]=new int[]{4,5,1,6,7,2,9};
For(int i=1;i<array.length;i++){
For(int k=0;k<i;k++){
If(array[k]<array[i]){
T=Array[k];
Array[k]=array[i];
Array[i]=t;
}
}
}
For(int j=0;j<array.length,j++){
System.out.println(array[j]);
}
}
二十六:选择排序法
publicclass SelectSort {
publicstaticvoid main(String[] args) {
int array[] = { 4, 6, 2, 1, 9, 5 };
int max = 0;
int temp = 0;
for (int i = 0; i < array.length; i++) {
max = i;
for (int j = i + 1; j < array.length; j++) {
if (array[max] < array[j]) {
max = j;
}
}
if (max != i) {
temp = array[i];
array[i] = array[max];
array[max] = temp;
}
}
for (int k = 0; k < array.length; k++) {
System.out.print(array[k]);
}
}
}
选择排序法效率更高
二十七:常见软件开发模式
瀑布模式:流程化的东西
迭代模式:先有需求说明书,开发出来给客户看后再开发(多次开发)
敏捷模式:主张交流对话,不主张写开发文档(互联网公司常用)
二十八:jdbc数据库链接步骤
①:加载驱动类
②:获得数据库连接对象
③:创建PreparedStatement对象
④:调用PreparedStatement对象的相关方法执行相对应的 SQL 语句
⑤:关闭数据库链接
// 加载驱动类
Class.forName("com.mysql.jdbc.Driver");
// 试图建立到给定数据库的连接
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mysql", "root", "root");
// 创建字符串对象写出sql语句
String s = "select * from student";
// 利用Connection对象得到PreparedStatement;
ps = conn.prepareStatement(s);
// 执行sql语句返回结果集 ResultSet
rs = ps.executeQuery();
二十九:常见的乱码问题及其处理方法
乱码问题产生原因:汉字在各编码表中的码值不一样
Get请求解决乱码:
Post请求解决乱码:
三十:request生命周期
request生命周期;
1.当请求来时创建request对象.
2.当响应结束时,request就销毁。
三十一:简述java的垃圾回收机制
垃圾回收机制是JAVA虚拟机JVM的默认机制,也是JAVA的一大特色!比如程序运行 中,回收机制会自动回收没用的类,对象之类的,节省内存空间,提高运行效率!
GC垃圾回收,调用GC 两种方法, ①System.gc(),②Runtime.getRuntime.gc()
三十二:逻辑运算符位运算符
&:逻辑运算符位运算符
&&:逻辑运算符
数组下标越界:ArrayIndexOutOfBoundsException
空指针异常:NullPointerException
数字格式异常:NumberFormatException
三十三:Lucene和Solr
三十四:Nginx---负载均衡(分配任务给闲着的服务器)
三十五:error和exception区别
error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指
望程序能处理这样的情况。
exception 表示一种设计或实现问题。也就是说,它表示如果程
序运行正常,从不会发生的情况。
三十六:final, finally, finalize 的区别。
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
内部类要访问局部变量,局部变量必须定义成 final 类型,例如,一段代码……
finally 是异常处理语句结构的一部分,表示总是执行。
finalize 是 Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可
以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM 不保证此方法总被
调用
三十七:不能用作索引的关键字
Name,like,null,is not null
三十八:报表导出
导出excel用poi技术
组长封装好的方法:传三个参数:1:list数据2:表头3:文件名
Liux命令:
1:cd:入一个文件
2:ls:查看文件下文件
3:Kill-q杀死线程
4:jsp
5:ps:查看进程
6::守护线程
X—manager:liux链接工具
调接口:
Httpclent
Hession
附件上传:
1:导入jar:commones fileupload
commones io
2:springMVC.xml配置 springMVC接收图片MultipartFile
RestFul支持:
就是对url的命名标准,要求url中只有能名词,没有动词(不严格要求),但是要求url中不能用问号? 传参
传参数:
页面:${pageContext.request.contextPath }/items/itemEdit/${item.id}(传的值)
方法: @RquestMapping("/itemEdit/{id}")(接收的变量名)
方法: @PathVariable("id") Integer id
访问修饰符
Java异常体系结构
Throwable
Error Exception
RuntimeException checked exception
一般异常:必须要用catch块处理,IOException,SQLException,ClassNotFoundException都属于一般异常
运行时异常:可以不做处理,jvm会处理:NullPointerException,ArithmeticException都属于运行时异常
流的分类
按流的类型:字符流,字节流
按流的方向:输入流,输出流
Java序列化
序列化是将对象状态转换为可保持或传输的格式的过程。说明白点就是你可以用对象输出流输出到文件
在Java中,只要一个类实现了java.io.Serializable接口,那么它就可以被序列化
Xml
Xml:可扩展标记语言,dom4j解析,可以配置,可以存储数据
线程同步
给一个方法增加synchronized修饰符之后就可以使它成为同步方法
wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
Join():让子线程等待主线程运行完才能执行
Jdbc四种驱动类型
JDBC-ODBC桥
本地API驱动
网络协议驱动
本地协议驱动
synchronized和lock的区别
Jsp动作
JSP共有以下6种基本动作 jsp:include:在页面被请求的时候引入一个文件。 jsp:useBean:寻找或者实例化一个JavaBean。 jsp:setProperty:设置JavaBean的属性。 jsp:getProperty:输出某个JavaBean的属性。 jsp:forward:把请求转到一个新的页面。 jsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记。
Jsp内置对象
1、request对象:客户端的请求信息被封装在request对象中,通过它才能了解到客户的需求,然后做出响应。
2、response对象:response对象包含了响应客户请求的有关信息。
3、session对象:session对象指的是客户端与服务器的一次会话,从客户连到服务器的一个WebApplication开始,直到客户端与服务器断开连接为止。
4、out对象:是向客户端输出内容常用的对象
5、page对象:page对象就是指向当前JSP页面本身,有点象类中的this指针。
6、application对象:application对象实现了用户间数据的共享,可存放全局变量。它开始于服务器的启动,直到服务器的关闭,在此期间,此对象将一直存在;这样在用户的前后连接或不同用户之间的连接中,可以对此对象的同一属性进行操作;在任何地方对此对象属性的操作,都将影响到其他用户对此的访问。服务器的启动和关闭决定了application对象的生命。
7、exception对象:exception对象是一个例外对象,当一个页面在运行过程中发生了例外,就产生这个对象。如果一个JSP页面要应用此对象,就必须把isErrorPage设为true,否则无法编译。
8、pageContext对象:pageContext对象提供了对JSP页面内所有的对象及名字空间的访问,也就是说他可以访问到本页所在的SESSION,也可以取本页面所在的application的某一属性值,他相当于页面中所有功能的集大成者,它的本 类名也叫pageContext。
9、config对象:config对象是在一个Servlet初始化时,JSP引擎向它传递信息用的,此信息包括Servlet初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个ServletContext对象)。
字符串问题
equals与==的区别
String?StringBuffer?StringBuilder??
StringBuffer、StringBuilder和String一样,也用来代表字符串。
String---字符串常量
String是不可变对象,在每次对String类型进行改变的时候其实都等同于生成了一个新的String对象,然后指向新的String对象,所以经常改变内容的字符串最好不要用String类型,因为每次都会对系统性能产生影响。
StringBuffer---字符串变量
StringBuffer则是可变的字符串,在每次对StringBuffer对象进行改变时,会对StringBuffer对象本身进行操作,而不是生成新的对象,再改变对象引用。所以,在字符串对象经常改变的情况下推荐使用StringBuffer类。任何对它所指代的字符串的改变都不会产生新的对象。
StringBuilder---字符串常量
StringBuilder它和StringBuffer类等价,区别在于StringBuffer类是线程安全的,适合多线程使用。StringBuilder类是单线程的,类不是线程安全的,不适合在多线程中使用,但其在单线程中比StringBuffer的效率更高。
总结:
1. 在不考虑多线程时,采用String对象时,执行时间比其他两个都要长,效率比较低下。
2. 如果我们的程序是在单线程下运行,或者是不必考虑到线程同步问题,我们应该优先使用StringBuilder类;
3. 如果在多线程下运行,也要保证线程安全,就要用StringBuffer。
既然可变和不可变都有了,为何还有一个StringBuilder呢?相信初期的你,在进行append时,一般都会选择StringBuffer吧!
先说一下集合的故事,HashTable是线程安全的,很多方法都是synchronized方法,而HashMap不是线程安全的,但其在单线程程序中的性能比HashTable要高。StringBuffer和StringBuilder类的区别也是如此,他们的原理和操作基本相同,区别在于StringBufferd支持并发操作,线性安全的,适合多线程中使用。StringBuilder不支持并发操作,线性不安全的,不适合多线程中使用。新引入的StringBuilder类不是线程安全的,但其在单线程中的性能比StringBuffer高。
从后面List的测试结果可以看出,除了对多线程的支持不一样外,这两个类的使用方式和结果几乎没有任何差别,
StringBuffer????
(由于StringBuffer和StringBuilder在使用上几乎一样,所以只写一个,以下部分内容网络各处收集,不再标注出处)
StringBuffer s = new StringBuffer();
这样初始化出的StringBuffer对象是一个空的对象,
StringBuffer sb1=new StringBuffer(512);
分配了长度512字节的字符缓冲区。
StringBuffer sb2=new StringBuffer(“how are you?”)
创建带有内容的StringBuffer对象,在字符缓冲区中存放字符串“how are you?”
a、append方法
public StringBuffer append(boolean b)
该方法的作用是追加内容到当前StringBuffer对象的末尾,类似于字符串的连接,调用该方法以后,StringBuffer对象的内容也发生改变,例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.append(true);
则对象sb的值将变成”abctrue”
使用该方法进行字符串的连接,将比String更加节约内容,经常应用于数据库SQL语句的连接。
b、deleteCharAt方法
public StringBuffer deleteCharAt(int index)
该方法的作用是删除指定位置的字符,然后将剩余的内容形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“KMing”);
sb. deleteCharAt(1);
该代码的作用删除字符串对象sb中索引值为1的字符,也就是删除第二个字符,剩余的内容组成一个新的字符串。所以对象sb的值变为”King”。
还存在一个功能类似的delete方法:
public StringBuffer delete(int start,int end)
该方法的作用是删除指定区间以内的所有字符,包含start,不包含end索引值的区间。例如:
StringBuffer sb = new StringBuffer(“TestString”);
sb. delete (1,4);
该代码的作用是删除索引值1(包括)到索引值4(不包括)之间的所有字符,剩余的字符形成新的字符串。则对象sb的值是”TString”。
c、insert方法
public StringBuffer insert(int offset, boolean b),
该方法的作用是在StringBuffer对象中插入内容,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“TestString”);
sb.insert(4,false);
该示例代码的作用是在对象sb的索引值4的位置插入false值,形成新的字符串,则执行以后对象sb的值是”TestfalseString”。
d、reverse方法
public StringBuffer reverse()
该方法的作用是将StringBuffer对象中的内容反转,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.reverse();
经过反转以后,对象sb中的内容将变为”cba”。
e、setCharAt方法
public void setCharAt(int index, char ch)该方法的作用是修改对象中索引值为index位置的字符为新的字符ch。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.setCharAt(1,’D’);
则对象sb的值将变成”aDc”。
f、trimToSize方法
public void trimToSize()
该方法的作用是将StringBuffer对象的中存储空间缩小到和字符串长度一样的长度,减少空间的浪费,和String的trim()是一样的作用,不在举例。
g、length方法
该方法的作用是获取字符串长度,不用再说了吧。
h、setlength方法
该方法的作用是设置字符串缓冲区大小。
StringBuffer sb=new StringBuffer();
sb.setlength(100);
如果用小于当前字符串长度的值调用setlength()方法,则新长度后面的字符将丢失。
i、sb.capacity方法
该方法的作用是获取字符串的容量。
StringBuffer sb=new StringBuffer(“string”);
int i=sb.capacity();
j、ensureCapacity方法
该方法的作用是重新设置字符串容量的大小。
StringBuffer sb=new StringBuffer();
sb.ensureCapacity(32); //预先设置sb的容量为32
k、getChars方法
该方法的作用是将字符串的子字符串复制给数组。
getChars(int start,int end,char chars[],int charStart);
StringBuffer sb = new StringBuffer("I love You");
int begin = 0;
int end = 5;
//注意ch字符数组的长度一定要大于等于begin到end之间字符的长度
//小于的话会报ArrayIndexOutOfBoundsException
//如果大于的话,大于的字符会以空格补齐
char[] ch = new char[end-begin];
sb.getChars(begin, end, ch, 0);
System.out.println(ch);
结果:I lov
集合
Hashmap与hashtable区别
List集合有哪些,有什么特点,list如何排序
Set集合有哪些,有什么特点,
Map集合有哪些,有什么特点,两个有重复的map集合如何去重
线程
启动线程有几种方式,
什么是多线程,怎么理解锁,
线程的生命周期
数据库
一. 内连接,外连接(左连接,右连接,完全连接)区别:(多表联查时用到)
左连接:左表是主表
右连接:右表是主表
内连接:普通的,两表平等
例如:
TABLE A ;TABLE B
内连接:A INNER JOIN B ,在A中也有,在B中也有的数据才能查询出来
左连接:A LEFT JOIN B,连接查询的数据,在A中必须有,在B中可以有可以没有
右连接与左连接相反
内连接。(典型的连接运算,使用像 = 或<>之类的比较运算符)。包括相等连接和自然连接。
内连接使用比较运算符根据每个表共有的列的值匹配两个表中的行。例如,检索 students 和 courses 表中学生标识号相同的所有行。
外连接。外连接可以是左外连接、右外连接或完整外部连接。
在FROM子句中指定外连接时,可以由下列几组关键字中的一组指定:
LEFT JOIN 或 LEFT OUTER JOIN。
左连接的结果集包括LEFT OUTER子句中指定的左表的所有行,而不仅仅是连接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值(null)。
RIGHT JOIN 或 RIGHT OUTER JOIN。
右连接是左向外连接的反向连接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值(null)。
FULL JOIN 或 FULL OUTER JOIN。
完整外部连接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。
交叉连接。交叉连接返回左表中的所有行,左表中的每一行与右表中的所有行组合。交叉连接也称作笛卡尔积。
例如,下面的内连接检索与某个出版商居住在相同州和城市的作者:
USE pubs
SELECT a.au_fname, a.au_lname, p.pub_name
FROM authors AS a INNER JOIN publishers AS p
ON a.city = p.city
AND a.state = p.state
ORDER BY a.au_lname ASC, a.au_fname ASC
FROM 子句中的表或视图可通过内连接或完整外部连接按任意顺序指定;但是,用左或右向外连接指定表或视图时,表或视图的顺序很重要。有关使用左或右向外连接排列表的更多信息,请参见使用外连接。
例子:
a表 id name b表 id job parent_id
1张3 1 231
2 李四 2342
3王武3 34 4
注:a.id同parent_id 存在关系
内连接
select a.*,b.* from a inner join b on a.id=b.parent_id
结果是
1 张3 1 23 1
2 李四 2 34 2
左连接
select a.*,b.* from a left join b on a.id=b.parent_id
结果是
1 张3 1 23 1
2 李四 2 34 2
3 王武 null
右连接
select a.*,b.* from a right join b on a.id=b.parent_id
结果是
1 张3 1 23 1
2 李四 2 34 2
null 3 34 4
完全连接
select a.*,b.* from a full join b on a.id=b.parent_id
结果是
1 张3 1 23 1
2 李四2 34 2
null 3 34 4
3 王武null
内连接 (inner join)
内连接的特性是只显示符合连接条件的记录。
通过比较源表间共享的列的值从多个源表检索行的操作。内联接排除来自不具有与其它源表中的行匹配的行的源表的行。
用join
外连接(outer join)
而外连接就不一样,以左外连接为例(右外连接类似),它除了显示符合连接条件的记录以外,还会显示所有左表中的记录(右外连接就是所有右表中的记录)。
左连接即左外连接,显示左边表的所有行,用left join
右连接即右外连接,显示右边表的所有行,用right join
全连接,返回左边表与右边表的所有记录,没有对应的用NULL表示, 用full join
二. Inner jion A on B where A.id=B.id与from A ,B where A.id=B.id的区别:
1.inner join 中on后面的限制条件将全部起作用,这与where的执行结果是一样的。另外,where语句与inner join确实能得到相同的结果,只是效率不同(这个我没有测试过,不过我相信这个结论)。
2.inner join 1对1 等同于where A.a=B.b
完全等价.不过使用INNER JOIN比较好,兼容性好
select * from a,b where a.id=b.id ---等值连接 select * from a inner join b on a.id = b.id -----内连接 内连接与等值连接效果是相同的,执行效率也是一样的。
3.join是数据连接.分为3种. inner join left join right join
4.join是表连接,where是条件判断.
从你给的2条sql语句看,效率几乎没区别.
但如果是比较复杂的sql查询或者是多次连续调用的话就有区别了.
where是擅长条件判断
join是擅长表与表之间的联合查询
在多表查询的时候join更优
5.内连接inner join 与一般笛卡尔积的区别:inner join是笛卡尔积的特殊形式。如果有表a和表b,表a有m条记录,表b有n条记录,则一般笛卡尔积后得到的记录条数是m*n条,记录之间的组合是随意的。而内连接则是建立在表a和表b的结构中有相同的列名的基础上进行的。
select * from tb1 a inner join tb2 b on a.id=b.id 与select * from tb1 a ,tb2 b where a.id=b.id 有什么不同?
第一条和第二条SQL语句的执行方式应该是不一样的。第一条的话应该是参照表a中的记录,一条一条到表b中去找符合记录的,符合则连在一起,否则转到a中下一条。
而第2条语句的执行方式是将表a和表b的记录组合起来,然后考察满足条件的,并返回。
三. 数据库如何去重:
sql 单表/多表查询去除重复记录
1.单表distinct (加上distinct,不过大型项目不建议使用,该关键字非常影响性能!)
例:select distinct column1,column2 ... from table_name where ....; 注意:1.distinct只能放在去重字段的最前面 2.distinct 后的字段名全部算在去重条件中也就是如果 column1 且column2 必须都相同才能算作重复的记录
2.多表group by
group by 必须放在 order by 和 limit之前,不然会报错
3. ROW_NUMBER(),
四. Union和 union all 的作用和区别
假设我们有一个表 Student,包括以下字段与数据:
drop table student;
create table student
(
id int primary key,
name nvarchar2(50) not null,
score number not null
);
insert into student values(1,'Aaron',78);
insert into student values(2,'Bill',76);
insert into student values(3,'Cindy',89);
insert into student values(4,'Damon',90);
insert into student values(5,'Ella',73);
insert into student values(6,'Frado',61);
insert into student values(7,'Gill',99);
insert into student values(8,'Hellen',56);
insert into student values(9,'Ivan',93);
insert into student values(10,'Jay',90);
commit;
Union 和 Union All 的区别。
select *
from student
where id < 4
union
select *
from student
where id > 2 and id < 6
结果将是
1 Aaron 78
2 Bill 76
3 Cindy 89
4 Damon 90
5 Ella 73
如果换成 Union All 连接两个结果集,则返回结果是:
1 Aaron 78
2 Bill 76
3 Cindy 89
3 Cindy 89
4 Damon 90
5 Ella 73
可以看到,Union 和 Union All 的区别之一在于对重复结果的处理。
UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。实际大部分应用中是不会产生重复的记录,最常见的是过程表与历史表 UNION。如:
select * from gc_dfys
union
select * from ls_jg_dfys
这个 SQL 在运行时先取出两个表的结果,再用排序空间进行排序删除重复的记录,最后返回结果集,如果表数据量大的话可能会导致用磁盘进行排序。
UNION ALL 只是简单的将两个结果合并后就返回。这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。
从效率上说,UNION ALL 要比 UNION 快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据的话,那么就使用 UNION ALL,
五. 视图,索引,触发器等
六. 增删改查CRUD
CRUD
编辑
CRUD是指在做计算处理时的增加(Create)、读取查询(Retrieve)[r?'tri:v]、修改(Update)和删除(Delete)几个单词的首字母简写。crud主要被用在描述软件系统中数据库或者持久层的基本操作功能。
中文名
增删改查
外文名
CRUD
性 质
计算机术语
含 义
增加,查询,修改,删除
作 用
被用在描述软件系统
七.数据库的数据表类型
框架
Spring里面有哪些配置
Springmvc里面有哪些配置,Springmvc执行顺序
你们的项目怎么分层
Spring ioc 和aop
项目
项目上线后出问题如何处理
项目的流程:接到项目先干什么,再干什么。。。。。。。。。。。。。问老师
打包问题
项目部署问题