1.MyBatis中#和$的区别:
1)#和$都可以充当占位符,
#的底层是通过PreparedStament实现的,$的底层是通过Stament实现的
2)只有传入数据库对象时才会使用到$
2.1按照某个表进行查询时输入表名
2.2按照表中的某一列进行排序时,输入类名
3)在传入非数据使用库对象时最好不要使用$
4)#是先编译sql语句在传值,传入的值加上双引号
$是直接拼接字符串,不会给传入的值加上双引号
5)#会防止sql注入,$不会
2.防止sql注入:
sql注入:
查询时通过修改where后面的条件,将条件该为真,查询全表
防止sql注入:
预执行sql语句,提前判断sql语句的语义和语法是否正确
当我们要查询的信息比较敏感,对安全要求比较高,通过PreparedStament来进行查询
3.Spring:
spring是轻量级别的控制反转和面向切面的容器框架
IOC:
以前我们都是自己创建对象使用对象,控制反转就是将对象的创建交给Spring来完成,
我们只需要使用对象即可,实现了松散耦合。
IOC的底层实现原理:
IOC容器创建对象和处理对象之间的依赖关系:工厂模式+反射机制
创建对象是Spring容器帮我们来进行创建(控制反转+依赖注入)
实现是通过java的反射机制来实现的。
创建对象的三种方式:
1)通过静态工厂获取对象
2)通过工厂方法模式获取对象
3)通过Bean的class来进行加载
DI:依赖注入
IOC的一种特殊体现形式,配合接口达到不同层之间的解耦
DI不能单独存在,必须建立在IOC的基础上。即要先创建对象才能注入属性值
DI依赖注入的方式:
1)构造器注入
2)静态工厂注入
3)实例化工厂注入
4)setter注入
4.1)由于属性注入具有可选性和灵活性高的特点,是最常用的注入方式
4.2)属性注入需要为Bean提供一个默认的构造函数,并且要为注入的属性值提供setter方法。
Spring先调用bean默认的构造函数,然后通过反射机制的方法通过setter注入属性值
通过Property标签的name属性的值去找对应的setter方法
AOP:面向切面的编程
对面向对象的完善和补充,即将面向对象中的各个不同的业务模块所用到的共同的功能提取出来,
通过动态代理模式为各个业务模块扩展功能。
一般应用在系统级别的功能配置上,在系统开发中主要是为了解决系统 层面上的问题(日志,事务,权限)
AOP的底层实现:采用动态代理模式
1)有接口的情况:创建接口的实现类的代理模式:JDK动态代理
2)没有接口的情况:子类可以通过super()调用父类的方法
创建子类的代理模式:oglib动态代理
连接点(joinPoint)需要额外增加功能的方法
切入点(pointcut) 所有连接点的集合
代理(proxy):将额外的功能切入切入点.
目标(target):连接点所在的对象
切面(aspect):封装横切关注点信息的类,每个关注带你体现为一个通知方法.
通知(advice):切面必须完成的各个具体工作
前置通知,后置通知, 后置异常通知, 后置成功通知,
环绕通知:可以更加灵活的在连接点之前,之后添加功能。
<!-- AOP配置 proxy-target-class="false":不使用自动代理-->
<aop:config>
<!-- 切入点的配置 expression:要额外增加功能的方法 返回值 包名 类名 方法名-->
<aop:pointcut id="mypointcut" expression="execution(* com.yangsheng.dao.*.*(..))"/>
<!--环绕增强,通知和切入点 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="mypointcut"/>
</aop:config>
Spring事务管理分为两种:
1)编程式事务管理:
通过编程的形式管理事务,灵活性高,很难维护
2)声明式事务管理:
将事务的管理和业务代码进行分离,只需要通过注解和配置xml文件管理事务
@Transactional注解:
可以作用于接口,接口方法,类以及类方法上
(String建议不要在接口或者接口方法上使用该注解,因为这只有在使用接口的代理时才会生效)
当作用到类上时,该类的所有public 方法将都具有该类型的事务属性
不要在Dao层使用事务注解,在平时工作中一般使用在service层。
<!-- 事务管理器 DataSourceTransactionManager dataSource:引用上面定义的数据源 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 支持事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- 事务通知以及传播特性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 传播行为 -->
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="create*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="select*" propagation="SUPPORTS" read-only="true" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
事务传播特性:
required, supports,mandatory,required_new, not_supports,never, nested
required:如果当前没有事务,就新建一个事务,如果有一个事务,就加入到这个事务中
supports: 支持当前事务,如果当前没有事务,以非事务方式执行
事务的隔离级别:
1)Read uncommited(读未提交):
允许一个事务可以看到这个事务未提交的数据
2)Read commited(读提交):
一个事务提交之后,才能被另外一个事务读取
3)Repeatable read(读重复):
一个事务不能读取该事务未提交的数据
4)Serializable(序列化):
事务被处理为顺序执行
脏读:一个事务读取了另外一个事务未提交的数据
不可重复读:一个事务两次读取同一行数据,得到不同的结果
幻读: 一个事务内读取了别的事务插入的数据,导致前后结果不一样
4.SpringMVC和Struts2的区别:
1)加载机制不同:
Struts2的核心是基于Filter的StrutsPrepareAndExecuteFilter
SpringMVC的核心是基于Servlet的DispatcherServlet
2.SpringMVC的性能比Struts2好
Struts2是基于类级别的拦截,每次来了请求之后都会创建一个Action,然后通过setter,getter方法将request中的数据注入
SpringMVC是基于方法级别的拦截,来了请求之后直接去Controller中找@RequestMapping的URL对应的方法即可
3.参数传递
Struts2是通过成员属性来接受参数,参数可以被多个方法所共享。
SpringMVC的方法基本上是独立的,独享request,response中的数据。
请求数据通过参数获取,处理结果通过ModerMap返回给框架,方法之间不共享变量
4.ajax交互
SpringMVC的ajax交互十分方便,只需要@ResponseBody返回响应文本即可
5.拦截机制的实现
SpringMVC通过AOP方式实现,
Struts2有自己的拦截机制,导致Struts2的配置文件比SpringMVC大。
5.Hibernate和Mybatis的区别:
相同点:
1)都是基于ORM思想解决Entity和数据库中的映射关系
2)Hibernate和MyBatis都支持JDBC(数据库连接池),JTA(事务),API(应用程序编程接口)事务处理
3)Hibernate和MyBatis都是通过SessionFactoryBuilder由xml配置文件生成sessionFactory,
由sessionFactory生成session,由session执行事务和sql语句
不同点:
1)MyBatis是通过mapper.xml维护映射结果,程序员需要手动编写sql语句,
比起Hibernate自动生成HQL语句更加灵活,SQL调优更加容易。
2)Hibernate 移植性更好,
MyBatis移植性不太好,不同的数据库需要编写不同的sql语句。
3)Hibernate在数据量大表多的时候关系操作变得复杂。
4)Hibernate比MyBatis有更好的二级缓存机制。
5)Hibernate自己提供分页功能,MyBatis需要配置分页插件
6.Hibernate与MyBatis二级缓存的区别:
1)Hibernate有良好的二级缓存机制,用户无需关心sql,在查询时如果出现脏数据系统会报错
MyBatis用二级缓存要特别小心,脏数据的出现会对系统的正常运行产生影响。
2)Hibernate的二级缓存在sessionFactory中进行详细的配置,然后在具体的表一映射关系中配置是那种缓存
MyBatis的二级缓存是在具体的表一映射关系中进行详细的配置,可以根据不同的表,指定不同的缓存机制
7.List Set Map区别?
1) List和Set是存储单列数据的集合,
Map是存储键值对的双列数据的集合
2)List是有序的,值可以重复
Set是无序的, 值不可以重复
Map是无序的,键不能重复,值可以重复
3) ArrayList:底层结构是数组,查询快,线程不安全,效率高
LinkedList: 底层结构是链表,增删快, 线程不安全,效率高
Vector: 底层结构是数组,线程安全,查询慢,增删慢
ArrayList中的数据是连续的,成块的,查询时直接遍历内存即可。
LinkdedList中链表内存是散列的,插入时只需要改变链表中两个节点之间的引用关系,
使它们指向新的节点,即可完成插入。删除时只需要删除对应节点的引用即可。
4)HashMap: 存储顺序和遍历顺序不一定一致,键和值都可以为null
HashTable: 和HashMap类似,键和值不可以为null,线程安全
LinkedHashMap:和HashMap类似,键和值不可以为null,线程安全
TreeMap: 按照键升序排列
5)HashSet:底层是由HashMap实现,不允许集合中有重复的值,使用该方法必须重写equals()和HashCode方法
LinkedHashSet:继承于HashSet,同时又基于LinkedHashMap来进行实现,底层用的是LinkedHashMap
8.Hibernate缓存:
一级缓存:
session级别的缓存,一级缓存不可卸载,只要用到了session,就用到了session的缓存机制
不能手动配置。当执行了get, load, find,query查询出来的数据默认会在session中保存一分数据。
缓存数据在数据库中将一些数据拷贝一份放到对应的地方。
清理一级缓存: clean,close
二级缓存:
sessionFactory级别的缓存,可以做到多个session共享此信息
查询缓存:
Hibernate的二级缓存是根据id来进行查询的,对条件查询无用。
Hibernate配置了根据条件查询的查询缓存。
适合放在一级缓存中的数据:
1)不允许出现并发(财务数据)
2)与其它应用共享的数据
适合放在二级缓存中的数据:
1)不是很重要的数据,允许出现偶尔并发
2)参考数据
3)不会被并发访问的数据
9.Spring中为什么要先写接口,在写实现类?
OOP思想就是面向接口的编程。
面向接口的编程: 无论类的内部怎样实现,它对外的接口不变,那么它的使用方式就不会变。
接口的作用:用于多态,可以动态的调用实现类,实现可以方便的更换,替换,只需要改变配置文件即可
10.抽象类和接口的区别:
抽象类:被abstract修饰的类为抽象类。
对于一个父类,如果它的某个方法在父类中实现出来没有任何意义,必须根据根据子类的实际需求来实现,
可以将这个类定义为抽象类。
抽象类和接口是解决单继承的重要手段。
区别:
1)抽象类可以提供成员方法的实现细节,而接口只能提供public abstract方法
2)抽象类的成员变量是多种类型的,而接口的成员变量是public abstract final 类型
3) 抽象类中可以有静态方法和静态代码块
接口中不能有静态方法和静态代码块
4)一个类只能继承一个抽象类,但是一个类可以实现多个接口。
5)抽象类可以有构造方法,而接口不能有。
6)抽象类中可以包含非抽象的普通方法,接口方法必须是抽象的
7)抽象类中的抽象方法的访问类型可以是public,protected
接口中的方法只能是public类型的(默认)
11. HTTP 协议
超文本传输协议,是用于从www服务器传输超文本到本地浏览器的传输协议
HTTP协议的特点:
客户端发送的请求都必须服务器回应响应,而且在请求之后主动释放资源
HTTP协议响应状态码:
400:请求语法有误
403:请求资源的访问被服务器拒绝
404:请求参数有误
405:请求路径有误
500:服务器在执行请求时发生错误
503:服务器暂时处于超负荷或者停机维护,现在无法处理请求
12.进程:一个正在运行的程序拥有该程序运行的所有资源,包括任务的调度和资源的分配
线程:在进程中负责具体代码的执行,一个进程至少有一个线程
单线程:在整个程序中只有一个线程,这个线程为主线程
多线程:整个程序不止一个线程,除了主线程,其它都为子线程
并发:多个任务独立执行,一起执行
同步: 同一时刻只能执行一个任务,该任务执行完成才能执行下一任务。
异步: 一个线程中多个任务同时执行,互不影响。
多进程:操作系统能同时执行多个程序
创建线程的方式:
1)继承Thread,重写run()方法
有开辟线程的能力,资源共享方面不是很方便
2)实现runable接口,实现该接口的run()方法
没有开辟线程的能力,要将创建的对象交给指定线程来执行
创建一个对象,做到资源共享,多个线程可以执行同一任务
线程池:
帮助我们管理线程,我们只需要将需要执行的任务交给线程池。
线程池会根据任务的个数,任务的时长,将不同的任务交给线程池中的线程执行
线程死锁:
多个线程因为竞争资源而造成相互等待,
若无外力作用,这些进程都将无法向前运行。
防止线程死锁:
1)加锁顺序
2)加锁时限
3)加锁检验
线程锁:
当多个线程访问资源时,为了数据安全,保证当一个线程访问资源时,其它线程不能访问,
等上一个线程访问完成之后才能发访问。
同步锁:
synchronized(对象){
//同步代码块: 同一个对象锁下的所有线程,某个时间段内只能有一个线程在执行该代码块
}
在同步代码快内:
wait():当前线程暂停运行,被同一个线程锁的其它线程唤醒才能继续运行
wait(时长毫秒):当前线程暂停运行,当超过时长还没有被唤醒,就不等其它线程唤醒了,接着执行
notify(): 唤醒同一个同步锁中某一个wait()锁
notifyAll(): 唤醒同一个同步锁中所有wait()线程
线程的生命周期:
创建(new)---就绪(start)---运行状态(等待CPU调用run方法,如果线程在运行时发生阻塞,
进入阻塞状态,之后又返回就绪状态,等待CPU的再次调用)---结束状态(run方法执行完成)
run和start方法的区别:
start:重新开启了一个线程,不必等待其它线程执行完成。
run:只是调应了一个普通方法,没有开启线程,程序还会按照顺序执行响应代码。
13.内部类:
作用场景:更好的完善和补充了java中类的单继承问题。
形式:
1)成员内部类:定义在外部类中
1.1)该类中不可以定义被static修饰的变量和方法等
1.2)该类的内部可以使用外部类中定义的变量,方法等
使用:外部类.内部类 对象名 = 外部类对象.new 内部类()
2)静态内部类:定义在外部类中,被static修饰
2.1)在该类中可以定义正常类的所有变量和方法
2.2) 在该类中不能直接使用外部类的成员方法和成员变量
使⽤:外部类.内部类 对象名 = new 外部类.内部类()
3)局部内部类:
定义在方法中的类,和成员内部类类似,只能在定义的方法中使用
不能被static修饰
4)匿名内部类:
有些场景下,接口或者类我们根据当前需求,需要重写其中的功能。
但是只是在场景下使用,这时我们可以通过匿名内部类来实现,不需要额外的定义子类。
new 接口名或者类名<>(){
//子类重写的方法
}
14.MyBatis接口的映射规则:
MyBatis是面向接口的编程,可以将配置文件当成接口的实现类
1)namespace必须写成接口的完整类名(包名+接口名)
2)sql语句的id必须是对应的方法名
3)parameterType:必须和方法的参数的类型保持一致
4)resultType: 必须和方法的返回值保持一致
增删改:parameterType: com.xalo.model.Doctor 没有resultType
所有更新(增删改)操作,不用指定返回值类型,默认返回受影响的行数
也可以为java类起别名,在配置文件中就可以使用别名。 目的:书写更加简单
查询: resultType, parameterType resultMap
resultMap:当实体类跟表中属性名不一致,在resultMap标签中做 实体类和表中字段的映射
<resultMap type="java.util.Map" id="stuMap">
<result column="name" property="name"/>
<result column="age" property="age"/>
</resultMap>
column:表中字段名称 property: 实体类中属性名
id:当前resultMap映射结果, type: 实体类中属性名
15.基本数据类型:
整数型: byte(1) short(2) int(4) long(8)
浮点型: float(4) double(8)
字符型: char(2)
布尔类型: boolean(1/4字节)
16.left join:
返回包括左表中的所有记录和右表中连接字段相等的记录
select * from A left join B on A.id = B.id
right join:
返回包括右表中的所有的记录和左表中连接字段相等的记录
select * from A right join B on A.id = B.id
inner join:
等值连接,只返回两个表中连接字段相等的值
17.SSM配置文件:
SpringMVC_beans.xml:
1.扫描注解包: <context:component-scan/>
2.注解驱动: <mvc:annotation-driven/>
3.静态资源的配置: <mvc:default-servlet-handler />
4.配置数据效验器
5.界面解析器
6.文件上传的配置
7.处理拦截器的配置
spring-mybatis.xml:
1.注解扫描包
2.数据源dataSource
数据库驱动 数据库地址 数据库用户名 数据库密码
3.spring和Mybatis的整合: sqlSessionFactory
3.1:引入数据源
3.2载入Mybatis的主配置文件
4.自动扫描,将Mapper接口生成代理注入到Spring.
4.1:扫描接口所在的包
5.事务管理器
5.1:引入数据源
6.事务通知以及传播特性
7.AOP配置
7.1切入点的配置:expression要额外增加功能的方法
7.2环绕增强,通知和切入点
myBatis-config.xml:
1.全局设置
1.1:调用log4j框架,打印日志
1.2:开启二级缓存
2.为java类型起别名,在配置文件中就可以使用别名 目的:书写简单方便
3.映射文件的导入:
注解的使用:在mybatis的配置文件中注册这个映射接口(注意是class)
18.获取input输入框中的值的方法:
1)利用var方法
var uId = $(#IDQuery).var();
2)通过attr属性,获取value的制定的值
var uId = $(#IDQuery).attr("value");
19.如何添加一个输入框
<label>用户id</label>
<input id = "IDQuery" type = "uId" disabled="disabled" style = " border:black solid; width: 150px" >
<button id = "selects">查询</button>
<!--添加点击事件-->
$("#selects").click(function(){
<!--ajax获取输入(input)的值-->
var uId = $(#IDQuery).var();
})
disabled:不可编辑,当设置这个输入框时,当前输入框不能输入内容
用到的标签<label> <input> <button>
20.JQuery入口函数(脚本)
JQuery: 在html所有便签(DOM)都加载之后,就会执行
$(document).ready(function(){
})
$(function(){
})
$().ready(function(){
})
21.JQuery选择器:
<!--1.元素选择器:用户点击按钮后,所有<p>元素都隐藏-->
$(document).ready(function(){
$("#selects").click(function(){
$("p").hide();
});
});
<!--#id选择器: 当用户点击按钮后, 有 id = "test" 属性的元素将被隐藏-->
$(document).ready(function(){
$("#selects").click(function{
$("#test").hide();
});
});
<!--3. .class选择器: 用户点击按钮后,所有带有 class = "test"属性的元素都隐藏-->
$(document).ready(function(){
$("#selects").click((){
$(".test").hide();
});
});
22.设置内容:
var(): 声明变量
text(): 设置和返回所选元素的文本内容
html(): 设置和返回所选元素的内容(包括HTML标记)
attr(): 设置/改变属性值,允许同时设置多个属性。
alert():使用变量,打印出来
val(): 设置或返回表单字段的值
23.前端页面:
1)将html文件转换为jsp文件
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
2)导入jsp标签库
<%@ taglib prefix="s" uri="/struts-tags"%>
3)引入css文件
<link rel = “stylesheet” type = “text/css” href = “”/>
4)引入js文件
<script type="text/javascript" src = "js/文件名"></script>
5)执行定义好的方法
<button id="selects" onclick = " ">点击按钮</button>
24.Spring SpringBuffer 和SpringBuilder的区别:
1)执行速度
SpringBuilder > SpringBuffer > Spring
Spring是字符串常量,SpringBuilder和SpringBuffer是字符串变量
Spring一旦创建椒不可以更改的,SpringBuilder和SpringBuffer是可以更改的。
2)StringBuilder没有线程锁,是线程不安全的
SpringBuilder和SpringBuffer是线程安全的。
String:用于少要字符串的操作。
StringBuffer:多线程下在字符缓冲区进行大量操作的情况
StringBuilder: 单线程下在字符缓冲区进行大量操作的情况
25.Maven
Maven生命周期
完整的项目构建过程: clean(清理)--->compile(编译)--->test(测试)
--->package(打包)---->集成测试--->验证--->部署
2.defaut 构建项目(最核心)
2.1compile 编译项目
2.2test 测试项目
2.3package 打包
2.4install 安装到本地仓库中
3.<modelVersion> 指定当前pom版本
<groupId> 组织名 包名 + 类名
<artifactId> 项目名
<packaging> 打包方式
<name> 项目名称
<url> 项目地址
maven install与maven build的区别
没有 mvn build这个命令。
只有mvn install 和 mvn package
mvn install 是将你打好的jar包安装到你的本地库中,一般没有设置过是在 用户目录下的 .m2\下面
mvn package 只是将你的代码打包到输出目录,一般的是 target下面
maven中更改tomcat默认端口号的方法
方式1:双击server下的tomcat服务器,然后在ports下面修改
方式2: 一次性的,下次进行启动,这样不需要手动重复输入
Run As ----Maven build -----Goals(tomcat:run -Dmaven.tomcat.port=8081)
tomcat:run:运行命令
26.如何配置搭建tomcat服务器
1)在官网下载tomcat源代码,可以直接下载免安装版,直接解压到本机的某个路径下
2)增加环境变量配置
在Path中新增加tomcat所在文件下的bin目录
3)增加CATALINA_HOME环境变量配置
配置的值是tomcat解压后的文件目录
4)打开cmd命令框(window+R)
输入:catalina startup进行启动服务器
启动过程中查看新的窗口打印日志成功后即可表示启动完成
5)测试启动是否正常:
打开浏览器输入地址: http://localhost:8080回车,可以测试启动是否正常
27.SQL数据库查询出一张表中重复的数据
----查询出name重复的有哪些
select name from score group by name having count(*) > 1;
----查询每个名字出现大于2次 DESC:降序 ASC:升序