对于SpringBoot 集成mybatis和事务管理的记录
(学习地址:https://www.majiaxueyuan.com/front/couinfo/36)
目录
1.集成mybatis
1.添加依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.42</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
第一个是链接数据库的依赖包
第二个是mybatis 的包
2.创建数据库
我用的 navicat
然后去连接自己的数据库,我的是用的learnboot数据库的user表:
3.访问数据库
程序的依赖和数据库都建好了后就可以通过代码去访问数据库了
application.properties中添加属性:
spring.datasource.url=jdbc:mysql://localhost:3306/learnboot?characterEncoding=utf-8
spring.datasource.username=yourname
spring.datasource.password=yourpwd
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
和我以前访问数据库的方法不一样,以前用的是自己写的DButils类去访问
(比如我以前的:https://blog.csdn.net/qq_28198181/article/details/82501031)
现在需要使用@Mapper注解就几乎实现了,在这之前,我需要一个实体类User
User类代码如下:
public class User {
private int id;
private String username;
private String gender;
....//getter setter方法
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", gender='" + gender + '\'' +
'}';
}
}
这个时候就可以创建一个mapper包,里面放置一个UserMappers接口:
接口里的方法(最简单的查询方法):
@Component
@Mapper
public interface UserMappers {
@Select("select * from user where id = #{id}")
public User SelectUser(@Param("id") Integer id);
}
@Component 是将这个类(接口)加载到容器里
@Mapper 使用Mapper注解让系统自己扫包到这里
@Select("SQL 语句") 使用数据库语句
新建了一个UsersController类,然后 自动加载UserMappers, 写一个根据id查询user数据的方法,返回一个json串
@Component
@RestController
@RequestMapping("/user")
public class UsersController {
@Autowired
UserMappers userMappers;
@RequestMapping("/getuser")
public Object getUserById(Integer id) {
return userMappers.SelectUser(id);
}
}
数据库里我已经模拟了几条数据如下:
这个时候我可以去启动程序了QAQ,访问路径是users/getusers?id=1
我在改下访问为id=2和3,可以看看
id=2是没有数据,id为3可以看到数据,因为数据库里id=2的数据被我删掉了
基本流程就是如上.
试试基本的增删改查操作:
1).插入数据
UserMapper里添加方法(我是数据库有自增的,所以插入命令没有写完)
完整的应该是在Insert里面写
insert into user(id,username,gender) values(#{id},#{username},#{gender})
@Insert("INSERT INTO user VALUES(null,#{username},#{gender})")
public int InsertUser(@Param("username")String username,@Param("gender")String gender);
UsersController里添加方法
@RequestMapping("/addusers")
public Integer addUser(String username, String gender) {
return userMappers.InsertUser(username, gender);
}
结果:
2).查看数据
略
3).修改数据
UserMappers:
@Update("UPDATE user SET username = #{username} WHERE id = #{id}")
int UpdateUserNameById(@Param("username") String username, @Param("id") Integer id);
UsersController:
@RequestMapping("/updateusers")
public Integer updateUserNameById(String username, Integer id) {
return userMappers.UpdateUserNameById(username, id);
}
结果:
->
4).删除数据
UserMappers:
@Delete("DELETE from user where id = #{id}")
int DeleteUserById(@Param("id")Integer id);
UsersController:
@RequestMapping("/deluser")
public Integer DeleteUser(Integer id) {
return userMappers.DeleteUserById(id);
}
结果:
补充:
@RequestMapping 是一个通用的注解
对于get和set方法应该分的细一点
get方法(也就是直接在地址栏输入数值)应该用@GetMapping
post方法(数值隐藏在body里面的)应该用@PostMapping
单纯举个例子:
查询 用@Getting注解
添加 用@Posttingz注解
@GetMapping("/getusers")
public Object getUserById(Integer id) {
return userMappers.SelectUser(id);
}
@PostMapping("/addusers")
public Integer addUser(String username, String gender) {
return userMappers.InsertUser(username, gender);
}
关于集成mybatis的一些简单操作如上。
2.事务管理
1.事务特点
什么是事务:
.多个SQL作为单一逻辑单元进行执行的操作
特性:ACID
原子性 多个SQL要么一并执行 要么不执行
一致性 事务完成,必须使所有数据保持一致
隔离性 只当前事务的修改必须与其他事物隔离开,不能同时操作同一个数据
持久性 事务执行完毕 对数据的影响是永久的
@Transcational 集成的事务注解
2.实现一个事务流程的处理方法
需要service层去处理业务,如果处理成功就将数据一次性写入数据库,如果失败则回滚
需要用到红色标注的注解@Transcational
举个例子:使用事务模式 我先修改一个对象的名字,然后删除这个对象的下一个对象,
1.新建一个serviceimpl包,里面放了一个userServiceImpl类去实现userservice包下的一个userService接口
userService接口内容:
@Component
public interface UserService {
//执行事务
public void transfor();
}
实现类:
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserMapper userMapper;
@Override
@Transactional //集成好的事务注解
public void transfor() {
...................
}
}
包的路径
然后完善实现类里的方法:
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserMapper userMapper;
@Override
@Transactional //集成好的事务注解
public String transfor(String username, Integer id) {
Integer n = userMapper.update(username, id);
System.out.println("更新了:" + n + " 行");
//这里模仿在执行事务时出现错误
n = n / 0;
Integer m = userMapper.delete(id + 1);
System.out.println("删除了" + m + " 行");
return "更新也删除了";
}
}
在Controller方法中加入相关方法
@Autowired
UserService userService;
@GetMapping("/trans")
public String Trans(String username, Integer id) {
return userService.transfor(username, id);
}
执行程序
结果为:
发生异常,那么执行的更新也是没成功的
如果我把模拟异常的那个去掉
//n = n/0;
再次执行查看
后台数据库显示:
3号下的4号被删除了 说明整个事务成功执行了
如果我把@Transcational删掉
那么这个就不是事务 即便中间有问题,前面写入数据库的也写进去了,这样就不满足事务的特点了。
关于事务如上。