1、框架的概念:
2、框架的好处:
3、常见框架组合:
4、三层架构:
5、分层的重要性:
1、JDBC技术:
2、Spring的JdbcTemplate:
3、Apache的DBUtils:
以上解决方案都不是框架:
1、jdbc程序的回顾:
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//通过驱动管理类获取数据库链接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8","ro
ot", "root");
//定义 sql 语句 ?表示占位符
String sql = "select * from user where username = ?";
//获取预处理 statement
preparedStatement = connection.prepareStatement(sql);
//设置参数,第一个参数为 sql 语句中参数的序号(从 1 开始),第二个参数为设置的参数值
preparedStatement.setString(1, "王五");
//向数据库发出 sql 执行查询,查询出结果集
resultSet = preparedStatement.executeQuery();
//遍历查询结果集
while(resultSet.next()){
System.out.println(resultSet.getString("id")+"
"+resultSet.getString("username"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//释放资源
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(preparedStatement!=null){
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
上边使用 jdbc 的原始方法(未经封装)实现了查询数据库表记录的操作。
2、jdbc问题分析:
(1)数据库连接创建、释放频繁,造成系统资源浪费从而影响系统性能(使用数据库连接池可以解决此问题);
(2)SQL语句在代码中,(SQL变化可能较大,SQL变动需要改变Java代码)造成代码不易维护;
(3)使用preparedStatement向占位符传参数存在硬编码,(因为SQL语句的where条件是不一定的,修改SQL还需要修改Java代码)系统不易维护。
(4)结果的解析存在硬编码,(SQL变化导致Java代码变化)系统不易维护,(将数据库记录封装到pojo对象解析比较方便)。
1、创建maven工程并导入坐标;
2、创建实体类和持久层(dao)接口;
3、创建MyBatis的主配置文件:SqlMapConfig.xml
4、创建映射配置文件:IUserDao.xml
1、搭建的时候,dao的xml、Java类、mapper的起名需要一致;
2、在idea中创建目录和创建包不一样,包是三级结构,目录是一级目录;
3、mybatis的映射配置文件位置必须和dap接口的包结构相同;
4、映射配置文件的mapper标签namespace属性的取值必须是dao接口的全限定类名;
5、映射配置文件的操作配置(select、update、add、delete),ID属性的取值必须是dao接口的方法名。
(遵从了第3、4、5点之后,我们在开发中就无须再写dao的实现类)
1、ResultType:
2、ResultMap:
1、SqlMapConfig.xml中的配置内容和顺序:
2、properties属性:
-->
②、简化dataSource的代码。
(2)使用db.properties配置文件定义关联参数。
①、导入db.properties配置文件。
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis_day01
jdbc.username=root
jdbc.password=1234
②、在SqlMapConfig.xml的environments标签上边定义properties标签。
③、简化dataSource的代码。
3、typeAliases标签(类型别名):
(1)在SqlMapConfig.xml中,定义typeAliases标签。
①、typeAliases:用于配置别名。
②、type属性:实体类全限定类名。
③、alias属性:指定别名。
④、当指定了别名,就不再区分大小写。
⑤、配置别名之后,只要是用到(type=“com.test.domain.User”)type属性值的,都可以替换成别名(user)。
⑥、也可以使用下面的package属性。
⑦、package属性:用于指定要配置的别名的包。当指定之后,该包下的实体类都会注册别名,并且类名就是别名。不区分大小写。
4、mappers(映射器):
(2) 解析:
①、
当Dao接口指定了xml映射文件时,使用该标签,加载"Dao接口"关联的mapper.xml映射文件。
resource属性必须从resource目录开始。
②、
当Dao接口使用了注解配置映射信息时,使用该标签,指定"Dao接口",以便于获取接口上的注解的配置信息
③、
指定接口所在的包,则这个时候,无论接口使用的注解或者配置文件,都会自动加载.
注意: 如果Dao接口使用的是配置文件的方式,则要求
A、"配置文件所在路径"和"接口所在路径"必须一模一样
B、"配置文件的名字"和"接口的名字"必须一模一样
④、加载同一个接口映射时, , ,只能有一个.
1、连接池:
2、mybatis中的连接池:
(mybatis连接池提供了3种方式的配置)
配置的位置:
主配置文件SqlMapConfig.xml中的DataSource标签,type属性就是表示采用何种连接池方式。
type属性的取值:
①、POOLED : 使用连接池。
②、UNPOOLED : 不使用连接池。
③、JNDI : 由Tomcat提供连接池。
1、事务管理:
事务的概念:事务,指的是逻辑上的一组操作,组成这组操作的各个逻辑单元要么一起成功,要么一起失败。
事务的四大特性:ACID
(1)A:原子性(Atomicity):一是不可分割的最小操作单位,要么同时成功,要么同时失败。
(2)C:一致性(Consistency):从一个一致性的状态到另一个一致性状态。事务在执行前数据库状态和执行后数据库状态保持一致。(例如:转账前2个人的总金额是2000,转账后的总金额还是2000)。
(3)I:隔离性(Isolation):事务与事务之间不应该相互影响,执行时保持隔离的状态。
(4)D:持久性(Durability):一旦事务执行成功,对数据库的修改是持久的。
引发的并发访问的问题:
(1)事务在操作时的理想状态:所有的事务之间保持隔离,互不影响。因为并发操作,多个用户同时访问同一个数据,可能引发并发访问的问题。
(2)可能引发的问题:
①、脏读:一个事务读取到了另一个事务中尚未提交的数据。
②、幻读:一个事务中两次读取到的数据的数量不一致,要求在一个事务多次读取的数据的数量是一致的,这是 insert 或 delete 时引发的问题。
③、不可重复读:一个事务中两次读取的数据内容不一致,要求的是一个事务中多次读取时数据是一致的,这是事务 update 时引发的问题。
事务的四种隔离级别:
(1)读未提交(read uncommitted):脏读、幻读、不可重复读,都不能解决。
(2)读已提交(read committed):可避免脏读的发生。
(3)可重复读(repeatable read):可避免脏读、不可重复读的发生。
(4)串行化(serializable):三者都可以避免发生。
JDBC事务管理(通过Connection连接对象的方法进行管理):
(1)开启事务:conn.setAutoCommit(false); //true表示自动提交事务(默认), false表示手动提交事务。
(2)提交事务:conn.commit()。
(3)回滚事务:conn.rollback()。
2、mybatis的事务管理:
sqlSession = factory.openSession(true); //表示自动提交事务
sqlSession = factory.openSession(); //默认false,手动提交事务
sqlSession = factory.openSession(false);//手动提交事务
1、if标签:
2、where标签:
3、foreach标签:
(1)如果要遍历的是对象中的属性,则collection=“属性名”。
(2)如果要遍历的是传入参数本身(也就是说,传递到参数本身就是一个集合或者数组)
①、如果是list集合,则collection=“list”。
②、如果是数组,则collection=“array”。
③、如果是set集合,则:
A、第1步:在接口的方法上,添加@Param(“set”)。
//List findUserBySet(@Param("set") Set ids);
B、第2步:collection=“set”。
(3)传入参数仅限一个。
1、延迟加载:(适用于多表查询)
(1)概念:
在真正使用数据时才发起查询,不用的时候不查询。按需加载(又称懒加载)。
(2)什么情况下使用:
一对多、多对多的表关系结构中,通常采用延迟加载。
(3)坏处:
因为只有当用到数据时,才会进行数据库查询,这样在大批量数据查询时,(因为查询工作也需要消耗时间),所以可能造成用户等待时间变长,造成用户体验下降。
(4)好处:
先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能。因为查询单表要比关联查询多张表速度要快。
(节省内存,提高程序运行效率)。
2、立即加载:
(1)概念:
不管用不用,只要一调用方法,马上发起查询。
(2)什么情况下使用:
一对一、多对一的表结构中,通常采用立即加载。
1、什么是缓存:
2、为什么使用缓存:
3、什么样的数据使用缓存,什么样的数据不能使用?
(1)适用于缓存:
(2)不适用于缓存:
4、MyBatis的一级缓存:(默认开启)
5、MyBatis的二级缓存:(默认不开启)
(2)让当前的映射文件支持二级缓存(在IUserDao.xml中配置)
//
(3)让当前的操作支持二级缓存(在select标签中配置)
//useCache="true",让当前方法,支持二级缓存,每个方法要单独设置
Jdbc的问题描述与mybatis的解决:
1、问题一:据库连接创建、释放频繁,造成系统资源浪费从而影响系统性能。
解决:在SqlMapConfig.xml中配置数据库连接池,使用连接池管理数据库连接。
2、问题二:Sql语句写在代码中造成代码不易维护,实际SQL变化的可能性较大,SQL变动需要改变Java代码。
解决:将Sql语句配置在XXXMapper.xml文件中与Java代码分离。
3、问题三:向SQL语句传参数麻烦,因为SQL语句的where条件不一定,可能多也可能少,占位符需要和参数对应。
解决:mybatis自动将Java对象映射至SQL语句,通过statement中的parameterType定义输入参数的类型。
4、问题四:对结果集解析麻烦,SQL变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。
解决:mybatis自动将SQL执行结果映射至Java对象,通过statement中的resultType定义输出结果的类型。