Controller,Service,Dao,Mapper... 这些都是什么?
分层结构
后端应用整体上可分为三层:Controller,Service和Dao。
- Controller层:
- 接收前端发送的请求
- 调用Service层服务,处理请求内容
- 其他操作(e.g.视图跳转...
- Service层:
- 业务逻辑处理
- (可能)调用Dao层的服务,获取数据
- 一般分为接口和其对应实现类,接口和实现分离有如下好处:
- 解耦:更改实现逻辑只需要修改实现类,而不需要修改依赖于该接口的任何其他代码
- 易于扩展:一个接口可以有多个实现类
- Dao层:
- Data Access object,负责数据访问操作
- 一般包含两部分:
- pojo/*:定义数据表中的实体类
- mapper:定义数据访问操作接口
除此之外,在学习MyBatis时会接触到Mapper层,其与Dao层有何区别? 1. Dao层,获取数据时,数据来源不仅仅是数据库,还可能是本地文件或者内存等 2. Mapper层,
SSM
Spring+SpringMVC+MyBatis
Spring
SpringMVC
MyBatis
一款优秀的DAO框架(也是ORM,即Object-Relational Mapping,对象-关系映射框架),用以简化JDBC的开发
JDBC,Java DataBase Connectivity,一种规范,给出了Java语言操作关系型数据库的一套API,但并没有给出具体的实现。由于关系型数据库存在很多厂商,其底层实现各有不通,所以具体实现细节由各个数据库厂商提供,也称之为数据库驱动。
传统JDBC的操作如下: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18// 1.注册驱动
Class.forName("com..mysql.cj.jdbc.Driver");
// 2.获取连接对象
String url ="jdbc:mysql://<ip:port>/<table_name>";
String username ="";
String password ="";
Connection connection =DriverManager.getConnection(url,username,password);
// 3.获取执行SQL的对象statement,执行SQL,返回结果
String sql ="";
Statement statement =connection.CreateStatement();
ResultSet resultSet =statement.execute(sql);
// 4.封装结果数据
while (resultSet.next()){
//...
}
// 5.释放资源
statement.close();
connection.close();
上述过程有如下三点不便:
- 驱动,数据库地址,用户名等信息硬编码
- MyBatis中在
application.properties
中引入数据库连接信息
- MyBatis中在
- SQL结果需要手动解析,十分繁琐
- MyBatis中无需进行数据的解析
- 每次交互都需创建,释放资源,性能较低
- MyBatis会使用数据库连接池技术
MyBatis中执行SQL语句有两种方式:
- 相应
注解
中添加sql语句@Delete("delete from <table_name> where id = #{id}")
- 参数占位符:
#{...}
,会生成预编译的SQL,即对应占位符位置为?,执行时传递参数- 性能较好,每条sql语句编译之后会保存在缓存中复用,预编译sql复用率高
- 防止sql注入
- 参数占位符:
${...}
,不会生成预编译SQL
- 相应
xml文件
中添加sql语句- XML映射文件的名称与Mapper接口同名,同包名(一个在java下,一个在resources下)
- XML映射文件中namespace属性为Mapper接口的包名.文件名
- XML映射文件中sql语句的id与Mapper接口中的方法名称一致,返回类型一致
动态SQL
<if>
:用于判断条件是否成立,使用test属性进行条件判断,条件为true则拼接SQL <where>
:自动去除子句开头多余的AND 或 OR 1
2
3<if test="name !=null">
name like concat('%',#{name},'%')
</if>
<foreach>
: 1
2
3
4
5
6<delete id="">
delete from <table_name> where id in
<foreach collections="" item="id" separater="" open="" close="">
#{id}
</foreach>
</delete>
<sql><include>
:sql代码复用性 1
2
3
4
5
6
7<!-- 封装sql语句 -->
<sql id="xxx">
...
</sql>
<!-- 使用sql语句 -->
<include refid="xxx">