Mybatis业务逻辑(1)
1. 引入Mybatis
项目初始化完成之后,可以在 pom.xml 文件中看到如下依赖
org.springframework.boot
spring-boot-starter-jdbc
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.3
mysql
mysql-connector-java
runtime
2. 创建数据
* 我们使用 Navicat 连接 MySql 数据库,在 Navicat 图形界面中创建一些简单的数据,这里使用KBAQ的知识库数据,表名为nlpccqa
文章图片
文章图片
3. 创建程序目录
我们在 com.example 目录下新建四个目录,分别是 controller、dao、entity、service。
controller层负责具体的业务模块流程的控制
entity层用于存放我们的实体类,与数据库中的属性值基本保持一致,实现set和get的方法
dao层主要是做数据持久层的工作,负责与数据库联络,封装了增删改查基本操作
service层主要负责业务模块的逻辑应用设计,具体要调用到已定义的DAO层的接口
然后在 resource 目录下新建 mapper 目录。这个 mapper 目录是用来存放 SQL 语句的地方。
文章图片
顺便提一下,我们知道的 MVC 框架,即 model-view-controller 三层架构。这里 model层=entity层,与数据库的数据表对应,view层和 controller层结合非常紧密,需要联合起来一起开发。可以简单理解为 view层是做前端界面的展示,controller层做业务模流程块的控制。
如果在网上看到有 mapper层这个概念,就记住,mapper层=dao层,就是对数据库进行数据持久化操作。
不管是什么框架,我们很多时候都会与数据库进行交互。如果遇到一个场景我们都要去写SQL语句,那么我们的代码就会很冗余。所以,我们就想到了把数据库封装一下,让我们的数据库的交道看起来像和一个对象打交道,这个对象通常就是DAO。当我们操作这个对象的时候,这个对象会自动产生SQL语句来和数据库进行交互,我们就只需要使用DAO就行了。通常我们在DAO层里面写接口,里面有与数据打交道的方法。SQL语句通常写在mapper文件里面的。
Service层是建立在DAO层之上的,建立了DAO层后才可以建立Service层,而Service层又是在Controller层之下的,因而Service层应该既调用DAO层的接口,又要提供接口给Controller层的类来进行调用,它刚好处于一个中间层的位置。每个模型都有一个Service接口,每个接口分别封装各自的业务处理方法。
4. 理解后台访问流程
文章图片
————————————————
用户从页面前端,也就是我们所说的 view 层进行查询访问,进入到 controller 层找到对应的接口,接 着 controller 进行对 service 层进行业务功能的调用,service 要进入 dao 层查询数据,dao 层调用 mapper.xml 文件生成 sql 语句到数据库中进行查询。
在数据库中查询到数据,dao 层拿到实体对象的数据,接着交付给 service 层,接着 service 进行业务 逻辑的处理,返回结果给 controller,controller 根据结果进行最后一步的处理,返回结果给前端页 面。
创建一个访问用户信息的流程为:entity->dao->mapper->service->controller,这里 mapper 指的是存放 SQL 语句的 xml 文件。
5. 核心文件配置
这里我们可以使用 application.properties 文件,也可以使用 application.yml 文件来进行配置,当然推荐使用 application.yml 文件。
如果用 application.yml 在第一次启动项目的时候报错,项目右侧 maven -> lifecycle -> clean一下即可。
文章图片
参数解读:
- driver-class-name:mysql驱动
- url:mysql连接的url,默认是3306端口,zzz是数据库名,useSSL是使用安全套阶层连接进行数据传输(如果true出错可以选择false),serverTimezone设置时区,亚洲时区请设置上海或者香港,不要设置北京,因为系统里没有这个时区。
- username 是用户名,password 是密码
- mybatis.mapper-locations:用于将配置路径下的 * .xml 文件加载到 mybatis 中
# 方法一:只有一个路径 mybatis.mapper-locations= classpath:mapper/*.xml# 方法二:有多个路径 mybatis.mapper-locations= classpath:mapper/*.xml,classpath:mapper/user/*.xml
- type-aliases-package:指定POJO扫描包来让 mapper.xml 文件的 resultType 自动扫描到自定义POJO,这样就不用每次指定完全限定名
* # mapper.xml文件中设置
# 完全限定名# 指定了POJO扫描包之后
————————————————
6. 编写entity
我们在编写entity时遵循POJO的思想。这里需要提及“POJO最小侵入性编程”的概念,POJO(Plain Ordinary Java Object)意思是普通Java对象。类的成员是私有的,且有一系列的 setter and getter方法来提供访问。
POJO的内在含义是指那些没有从任何类继承、也没有实现任何接口,更没有被其它框架侵入的java对象。POJO的格式是用于数据的临时传递,它只能装载数据,作为数据存储的载体,而不具有业务逻辑处理的能力。
一般来讲,是 entity 中要取的数据应该和数据表相对应,但不一定要全部取出。
我们在刚才建立的 entity 目录中新建 User 类,定义属性 id、username、age。
————————————————
7. 编写Dao
springboot 集成 mybatis 开发有两种版本,注解版和配置文件版。
注解版不需要配置任何文件,拿来即用,主要依靠的是注解来生成 sql 语句。配置文件版与注解版相比,仅仅稍微复杂一点,两者的区别仅为mapper层处理的处理方式不一样。配置文件版多了一个xml文件,但是配置更加灵活,逻辑结构更加清晰,可读性更强。
【Mybatis业务逻辑(1)】注解版,用 @Mapper 注解标识,我们使用#{id}来标识参数。@Mapper 注解把 mapper 这个 DAO 交给 Spring 管理,不再写 mapper 映射文件
@Mapper
public interface UserDao {
@Select("select * from user where id=#{id}")
public User getUserById(int id);
@Delete("delete from user where id=#{id}")
public int deleteUserById(int id);
}
配置文件版,需要给编写的 dao 增加注解 @Repository。
@Repository注解修饰哪个类,则表明这个类具有对对象进行CRUD(增删改查)的功能。
而且@Repository是@Component注解的一个派生品,所以被@Repository注解的类可以自动的被@ComponentScan 通过路径扫描给找到。因此@Repository注解的类也能@Autowired实现自动装配。
通常将dao接口注入到service层的时候,需要写@Resource这个注解。加上@Repository,就是springboot生成一个bean,自动注入service的相关引用中。
我们在 dao 目录中新建 UserDao 接口,定义好方法。
文章图片
使用@Param进行传参,当映射器需要多个参数时,这个注解可以 给映射器方法的每个参数来取个名字,这里有两点好处:
- 在 xml 文件中不需要再指定参数类型 parameterType,使用@Param注解来声明参数时,如果使用 #{} 或 ${} 的方式都可以,当你不使用@Param注解来声明参数时,必须使用使用 #{}方式。如果使用 ${} 的方式,会报错
- 当传递对象时,使用 #{对象.属性} 可以更清晰地提示自己
使用配置文件版时,我们还需要在主程序中通过使用@MapperScan可以指定要扫描的Mapper类的包的路径。
文章图片
@MapperScan是要spring启动时,扫描到所有的Mapper文件,并生成代理类交给spring容器管理;
8. 编写Mapper
在 mapper 目录下新建 UserMapper.xml 文件。
mapper.xml 的文件头信息我们一般不会去记忆,都是直接从官网给出的教程中复制 xml 的头信息,网址是:https://mybatis.org/mybatis-3...
select * from `user` where id=#{Userid}select * from `user` where age=#{age}
查询的话我们用 select 标签,id 指定为方法名,resultType指明返回类型,标签中间写 SQL 语句。因为我们在yml里已经配置了 type-aliases-package: com.example.demo.entity,直接写 User 即可。 不需要完全限定名。
编写 Mapper.xml 文件主要注意三点:
- namespace相对应dao接口
- id相对应dao方法
- resultType相对应返回类型
我们需要在实现类中使用 @Service 注解,才能被 SpringBoot 扫描,在 Controller 中使用 @Autowired 注入service,在 service 中使用 @Autowired 自动装配UserDao
package com.example.demo.service;
import com.example.demo.dao.UserDao;
import com.example.demo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service("UserService")
public class UserService {
@Autowired
private UserDao userDao;
public User queryUser(int id){
return userDao.getUserById(id);
}public List findAge(int age){
return userDao.getUserByAge(age);
}
}
10. 编写Controller
在 controller 目录中新建 UserController 类
这里我们使用 Restful 风格,直接返回数据。
使用 @Autowired 注解自动装配 UserService。编写接口为 UserService 传输数据
package com.example.demo.controller;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/getUser")
public User getUser(@RequestParam("id") int id){
returnuserService.queryUser(id);
}@GetMapping("/age")
public List AgeGet(@RequestParam("age") int age){
returnuserService.findAge(age);
}
}
11. 测试接口
文章图片
返回了age=4 的所有用户的 JSON 数据。采用 get 方式传输的,所以必须使用 GetMapping。
文章图片
返回了id=3的用户数据。
推荐阅读
- Mybatis业务逻辑(2)
- 业务数据治理体系化思考与实践
- Mybatis之通用mapper使用注解的方式写动态sql-小结
- MyBatis Plus 自带BaseMapper解析
- 解决 mybatis mapper配置文件与接口名称必须一致问题
- MyBatis Mapper文件简述
- MyBatisCodeHelper-Pro|MyBatisCodeHelper-Pro IDEA写SQL表和表字段没有提示的问题(mapper里表和字段报红)
- MyBatis mapper记录
- 如何使用Salesforce自动化你的业务流程
- MyBatismybatis Plus 的Wrapper查询