MAVEN
maven三大组件如何协同
1.依赖
maven高级依赖原则之二:声明顺序依赖
2.mybatis高级映射column属性如何传递多个值?
子查询调用
3.因为当前应用的MyBatis3&Spring5这两个版本较高版本框架对环境有要求
会造成以下影响
因为当前环境下的maven其实用的JDK版本不是1.8所以要设置jdk版本为1.8
- 局部配置
pom.xml
<modelVersion>4.0.0</modelVersion>
<groupId>com.yyjc.mybatis.spring</groupId>
<artifactId>mybatis_spring_xml</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
- 全局配置
%maven-home%\conf\settings.xml
<profile>
<id>jdk18</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
4.mybatis与spring整合,applicationContext.xml中设置
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--1、关联数据资源属性文件-->
<context:property-placeholder location="classpath:config.properties"/>
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${conn.driverclass}"/>
<property name="url" value="${conn.url}"/>
<property name="username" value="${conn.username}"/>
<property name="password" value="${conn.userpass}"/>
</bean>
<!--3、配置sqlsessionfactory bean-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="druidDataSource"/>
<property name="mapperLocations" value="classpath*:*Mapper.xml"/>
<property name="typeAliasesPackage" value="com.yyjc.spring.pojo"/>
</bean>
5.spring配置-mybatis基于mapper接口动态代理生成实现类并注入
- 使用mybaitis的mapper接口执行sql语句时,我们拿到其实是接口实现类的代理,这个代理类是由mybatis使用动态代理生成的接口实现类。
- mybatis通过配置 MapperFactoryBean来生成Mapper接口的代理。如:
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.example.mapper.UserMapper" />
<!--
MapperFactoryBean继承了SqlSessionDaoSupport,在此将sqlSessionFactory注入
-->
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
上面这种配置的缺点是为每一个mapper接口都要加入配置,因此有了使用MapperScannerConfigurer,它会将包下的每个mapper接口都自动创建MapperFactoryBean,无需自己单独添加,MapperScannerConfigurer的配置如下:
<bean
class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.example.mapper" />
<!-- 无需在此指定SqlSessionFactory或SqlSessionTemplate , 因为 MapperScannerConfigurer将会创建MapperFactoryBean之后自动装配。可以使用 sqlSessionFactoryBeanName或sqlSessionTemplateBeanName 属性来设置正确的bean 名称 -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
下面是一个更简单的配置
<mybatis:scan base-package="com.example.mapper"/>
在此框架中获取动态代理的实现类的bean的id:即为实现接口的驼峰法名称,但也有问题
eg:接口(IEmplo),id(iEmplo),
以上会报错:
现阶段:不以大写I开头的遵循驼峰法即可
6.开启事务的几种方式:
sqlSessionFactory.sessionOpen(true);
sqlSession.commit();
基于注解开启事务
在要开启事务的方法上用以下该方法级别的注解
@Transactional(rollbackFor = Throwable.class)
7.基于mybatis注解实现关联映射
1.pojo类要实现序列化接口(Serializable)
①【在主配置文件中的映射配置文件没了怎么配置?】
基于mapper接口动态代理【把接口当映射配置文件看】
<mappers>
<mapper class="com.yyjc.mybatis.daoInter.EmployeeDaoInter"/>
</mappers>
class指向的是接口的字节码文件
②【字段名和pojo属性的关联】
@Results(
value={
@Result(id=true,column="",property=""),
@Result(column="",property=""),
@Result(column="",property="")
}
)
③@Results中字段名和pojo已经关联了如何重用呢?
在本类中重用
在本类中的其它方法重用(在@Results中设置id[唯一标识符],在想要重用此注解的方法外用@ResultMap其值等于id即可[value=“id”])注:其他类引用时只能是其方法名
/*根据员工编号查询员工信息*/
@Select(value="select * from employees where employee_id=#{emId}")
@Results(id = "selectOne",value ={
@Result(
id=true,column = "employee_id",property = "employeeId"),
@Result(
column = "first_name",property = "firstName"),............})
Employee selectOne(int emId);
@Select(value="select * from employees where employee_id=#{emId}")
@ResultMap(
value = "selectOne"
)
Employee test(int emId);
在其他类中重用
一对多分布式关联映射查询
EmployeeDaoInter:
@Select(value="select * from employees where department_id=#{departId}")
@ResultMap(
/*
重用@Results
*/
value = "commonsResult"
)
List<Employee> selectEmployeeList(int departId);
DepartmentDaoInter:
@Result(column = "department_id",
property = "employeesList",
many = @Many(select = "com.yyjc.mybatis.daoInter.EmployeeDaoInter.selectEmployeeList"))
④注解中设置加载 的方式
全局加载(懒):
第一步:在主配置文件开启延时加载
<setting name="lazyLoadingEnabled" value="true"/>
<!--把积极加载改为按需加载-->
<setting name="aggressiveLazyLoading" value="false"/>
局部:
懒加载:延时加载
@Result(column = "department_id",
property = "employeesList",
many = @Many(select = "com.yyjc.mybatis.daoInter.EmployeeDaoInter.selectEmployeeList",fetchType = FetchType.LAZY))
}
立即加载:默认的加载方式
@Result(column = "department_id",
property = "employeesList",
many = @Many(select = "com.yyjc.mybatis.daoInter.EmployeeDaoInter.selectEmployeeList",fetchType = FetchType.EAGER))
}
延迟加载
1.全局延迟加载:在主配置文件的设置
2.局部延迟加载,在映射文件中设置
效果
8.mybatis基于映射配置文件二级缓存如何配置
①存配置
要正确的使用二级缓存,需完成如下配置的。
- 在MyBatis的主配置文件中开启二级缓存。
name="cacheEnabled"
value=“true”/>` - 在MyBatis的映射XML中配置cache或者 cache-ref 。
cache标签用于声明这个namespace使用二级缓存,并且可以自定义配置。
<cache/>
- type:cache使用的类型,默认是PerpetualCache,这在一级缓存中提到过。
- eviction: 定义回收的策略,常见的有FIFO(先入先出),LRU。
- flushInterval: 配置一定时间自动刷新缓存,单位是毫秒。
- size: 最多缓存对象的个数。
- readOnly: 是否只读,若配置可读写,则需要对应的实体类能够序列化。
- blocking: 若缓存中找不到对应的key,是否会一直blocking,直到有对应的数据进入缓存。
cache-ref代表引用别的命名空间的Cache配置,两个命名空间的操作使用的是同一个Cache。
<cache-ref namespace="mapper.StudentMapper"/>
当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。
②缓存中相关属性介绍
select元素中的属性
useCache="true|or"默认为true
一级缓存无效,二级缓存有效
select flushC、e="默认为false"清理缓存,一二级缓存都会受到影响。
insrt/delete/update flushCache="默认为true"清理缓存,一二级缓存都会受到影响。
sqlSession.clearCache();只清除一级缓存
第三方缓存配置文件的defaultCache元素的属性意思
ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<!-- 磁盘保存路径 -->
<diskStore path="E:\" />
defaultCache:默认的缓存配置信息,如果不加特殊说明,则所有对象按照此配置项处理
maxElementsInMemory:设置了缓存的上限,最多存储多少个记录对象
eternal:代表对象是否永不过期
timeToIdleSeconds:最大的发呆时间
timeToLiveSeconds:最大的存活时间
overflowToDisk:是否允许对象被写入到磁盘
<defaultCache
maxElementsInMemory="10000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>
9.基于mybatis注解和主配置文件开启和使用二级缓存
1.在主配置文件中开启缓存【默认是开启的可以不写】
<setting name="cacheEnabled" value="true"/>
2.在要使用二级缓存的类前加入类注解开启 二级缓存
```开启二级缓存
@CacheNamespace(blocking = true)
序列化和反序列化
Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象的过程:(就像是加密和解密的过程一样)
10.pojo实现序列化
是==对象永久化的一种机制==。
确切的说应该是对象的序列化,一般程序在运行时,产生对象,这些对象随着程序的停止运行而消失,但如果我们想把某些对象(因为是对象,所以有各自不同的特性)保存下来,==在程序终止运行后,这些对象仍然存在,可以在程序再次运行时读取这些对象的值,或者在其他程序中利用这些保存下来的对象。==这种情况下就要用到对象的序列化。
11.JDBC操作数据库的步骤
加载并注册驱动
Class.forName("com.mysql.jdbc.Driver");
基于驱动管理类创建连接对象
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/dbName",userName,passWord);
定义待执行的SQL语句
String sql="insert/delete/update"or"select";
基于连接对象创建【预编译】命令语句对象
①Statement statement=conn.createStatement();
②PreparedStatement statement=conn.prepareStatement(sql)
12.数据库事务
并发:理解(一群人打一个球)
并行:理解(每个人都有一个球)
①把DOS命令窗口切换成MySQL窗口
mysql -uroot -p0610
mysql -u[数据库用户账户] -p[数据库用户密码]
退出mysql窗口返回DOS窗口
quit/exit
②MySQL命令行操作常用命令【重点】
1、通过命令行窗口连接MySQL服务
mysql -uroot -proot;
2、查看当前所有数据库
show databases;
3、使用指定数据库
use databasename; (use myemployees)
4、查看当前使用的数据库
select database();
5、查看MySQL数据库的引擎
show engines;
6、查看当前数据库的所有表
show tables;
7、查看指定表的结构
desc employees;
8、查看当前自动提交事务的状态
show variables like 'autocommit'; (ON表启用 ,OFF表禁用)
9、设置当前自动事务的状态
set autocommit = 0 | 1 ;
10、查看当前MySQL数据库默认的事务隔离级别
select @@tx_isolation;
11、设置当前会话事务隔离级别
set session|global transaction isolation level 隔离级别;
③事务的并发问题
3.1 脏读
事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
3.2 不可重复读
事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,
对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
3.3 幻读
系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,
但是系统管理员B就在这个时候插入了一条具体分数的记录,
当系统管理员A改结束后发现还有一条记录没有改过来,
就好像发生了幻觉一样,这就叫幻读。
④事务的隔离级别
. 事务隔离级别存在的意义:在一定的层面上避免事务并发引发的问题
4.1 读未提交(read-uncommitted)
4.2 已提交读(不可重复读)(read-committed)
4.3 可重复读(repeatable-read)
4.4 串行化(serializable)(序列化)
面试题:事务并发与事务隔离级别的联系?
答:因为有事务并发影响才会导致出现事务隔离级别来解决它;事务隔离级别能在一定层面上避免事务并发引发的问题
--------------------------------------------------------
| 事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
------------------------------------------------------
| 读未提交(read-uncommitted)| 是 | 是 | 是 |
------------------------------------------------------
| 不可重复读(read-committed)| 否 | 是 | 是 |
------------------------------------------------------
| 可重复读(repeatable-read) | 否 | 否 | 是 |
------------------------------------------------------
| 串行化(serializable) | 否 | 否 | 否 |
------------------------------------------------------
13.http中post和get的区别
都是http(超文本传输协议)中浏览器与服务器交互的方法。
HTTP协议中定义了浏览器和服务器进行交互的不同方法,基本方法有4种,分别是GET,POST,PUT,DELETE。这四种方法可以理解为,对服务器资源的查,改,增,删。
GET:从服务器上获取数据,也就是所谓的查,仅仅是获取服务器资源,不进行修改。
POST:向服务器提交数据,这就涉及到了数据的更新,也就是更改服务器的数据。
PUT:PUT的英文含义是放置,也就是向服务器新添加数据,就是所谓的增。
DELETE:从字面意思也能看出,这种方式就是删除服务器数据的过程。
其实get和post的区别不大,比如说安全方面,get请求参数在URL地址上会直接暴露出来,post请求参数放在request body部分,通过F12也可以看见,他们的安全性其实差不多,再加上http底层是TCP/IP,所以get和post的底层也是TCP/IP,也就是说,post和get都是TCP链接,他们之间能做的事情是一样的,你要给GET加上request body,给POST带上url参数,技术上是完全行的通的。 但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现一些不同:
如get产生一个TCP数据包,post产生两个数据包。
详细的来说就是:对于get的请求,浏览器会把HTTP header和data一并发送过去,服务器响应200(返回数据)。而对于post的请求,浏览器会先发送header,服务器响应100 continue,浏览器再次发送data,服务器响应200。
举个例子来说就是:比如说送货,get方式只需一趟就把货送到。而post得跑两趟,第一趟,过去跟服务器打个招呼,告诉他等会会送货过来,让他打开门迎接,第二趟,则是把货送了过来。
因为postT需要两步,时间上消耗的要多一点,看起来GET比POST更有效。其实这并不一定,
\1. GET与POST都有自己的语义,不能随便混用。
\2. 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
\3. 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
14.Redis如何设置密码及验证密码?
设置密码:config set requirepass 123456
授权密码:auth 123456