零基础学习SpringBoot(二)--集成MyBatis以及开启事务

1. SpringBoot集成MyBatis

1.1 准备数据库

  • 启动数据库,并通过Navicat连接


    image
  • 创建新的数据库springboot,指定数据库字符编码为utf-8, 并创建表t_person

image
  • 向表中插入几条数据
image

1.2 创建新项目

image

1.3 在pom.xml中添加相关jar依赖


 
     org.mybatis.spring.boot
     mybatis-spring-boot-starter
     2.1.3
 

 
 
     mysql
     mysql-connector-java
 

1.4 在SpringBoot的核心配置文件application.properties中配置数据源

根据自己数据库的信息修改以下内容

server:
   # 配置内嵌Tomcat端口号
   port: 8888
   servlet:
   # 配置项目上下文根
     context-path: /springboot-web

# 配置数据源
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
    username: root
    password: 12345678

1.5 代码实现

1.5.1 使用Mybatis反向工程生成接口、映射文件以及实体Bean
  • 创建Mybatis反向工程配置文件 GeneratorMapper.xml

  • 在pom.xml文件中添加反向工程依赖


 
   org.mybatis.generator
   mybatis-generator-maven-plugin
   1.3.6
   
     
     GeneratorMapper.xml
     true
     true
   
 
  • 修改GeneratorMapper.xml配置




   
   
   
   
   
   
     
   

   
   
   
   
   
     
     
   

   
   
     
   

   
   
     
   

   
   
  • 运行插件,生成相关文件
image
image
1.5.2 在controller包下创建PersonController并编写代码
package com.mufeng.springbootweb.controller;

import com.mufeng.springbootweb.model.Person;
import com.mufeng.springbootweb.services.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class PersonController {

   @Autowired
   private PersonService personService;

   @RequestMapping(value = "/springboot/getPersonDetails")
   @ResponseBody
   public Object getPersonDetails(){
     Person person = personService.findPersonById(1);
     return person;
   }

}
1.5.3 在Service包下创建service接口并编写代码
package com.mufeng.springbootweb.services;

import com.mufeng.springbootweb.model.Person;

public interface PersonService {

   /**
   * 根据用户标识获取用户详情
   * @param id
   * @return
   */
   Person findPersonById(Integer id);

}
1.5.4 在 service.impl 包下创建 service 接口并编写代码
package com.mufeng.springbootweb.services.impl;

import com.mufeng.springbootweb.mapper.PersonMapper;
import com.mufeng.springbootweb.model.Person;
import com.mufeng.springbootweb.services.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class PersonServiceImpl implements PersonService {

   @Autowired
   private PersonMapper personMapper;

   @Override
   public Person findPersonById(Integer id) {
     return personMapper.selectByPrimaryKey(id);
   }
}
1.5.5 在 Mybatis 反向工程生成的 StudentMapper 接口上加一个 Mapper 注解

@Mapper 作用:mybatis 自动扫描数据持久层的映射文件及 DAO 接口的关系

package com.mufeng.springbootweb.mapper;

import com.mufeng.springbootweb.model.Person;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface PersonMapper {
   int deleteByPrimaryKey(Integer id);

   int insert(Person record);

   int insertSelective(Person record);

   Person selectByPrimaryKey(Integer id);

   int updateByPrimaryKeySelective(Person record);

   int updateByPrimaryKey(Person record);
}

注意:默认情况下,MyBatis的xml映射文件不会编译到target的class目录下,所以我们需要在pom.xml中配置resource

    
            
                src/main/java
                
                    
                        **/*.xml
                    
                
            
        

1.6 启动Application应用,访问测试

image

1.7 在运行的主类上添加mapper扫描注解

注释掉PersonMapper接口上的@Mapper注解

package com.mufeng.springbootweb.mapper;

import com.mufeng.springbootweb.model.Person;
import org.apache.ibatis.annotations.Mapper;

//@Mapper
public interface PersonMapper {
    int deleteByPrimaryKey(Integer id);

    int insert(Person record);

    int insertSelective(Person record);

    Person selectByPrimaryKey(Integer id);

    int updateByPrimaryKeySelective(Person record);

    int updateByPrimaryKey(Person record);
}

在运行主类Application上加@MapperScan("com.mufeng.springbootweb.mapper")

package com.mufeng.springbootweb;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.mufeng.springbootweb.mapper")
public class SpringbootWebApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootWebApplication.class, args);
    }

}

运行测试结果

image

1.8 接口和映射文件分开

  • 修改GeneratorMapper.xml 文件中Mapper映射文件生成目标位置, 目标指向resources下的mapper文件夹下
        
        
            
        
  • 重新运行代码生成插件
image

把之前生成的映射文件删除掉

  • 在application.yml配置文件中需要指定映射文件的位置,这个配置只有接口和映射文件不再同一个包的情况下,才需要指定
mybatis:
  mapper-locations: classpath:mapper/*.xml

2. SpringBoot的事务支持

SpringBoot 使用事务非常简单,底层依然采用的是Spring本身提供的事务管理

  • 在入口类中使用注解@EnableTransactionManagement 开启事务支持

  • 在访问数据库的Service方法上添加注解@Transactional即可

在PersonController中添加更新用户的方法
    @RequestMapping(value = "/springboot/updatePersonById")
    @ResponseBody
    public Object updatePersonById(){
        int count = 0;
        try{
            Person person = new Person();
            person.setId(1);
            person.setName("MuFeng_update");
            person.setAge(20);
            count = personService.updatePersonById(person);
        }catch (Exception e){
            e.printStackTrace();
            return "fail";
        }
        return count;
    }
在PersonService接口中添加更新用户的方法
    /**
     * 根据用户id更新用户信息
     * @param person
     * @return
     */
    int updatePersonById(Person person);
在PersonServiceImpl接口实现类中更新用户信息方法进行实现,并主动制造一个异常抛出
    @Override
    public int updatePersonById(Person person) {
        int updateCount = personMapper.updateByPrimaryKeySelective(person);
        System.out.println("更新结果:" + updateCount);
        //在此构造一个除数为 0 的异常,测试事务是否起作用
        int a = 10/0;
        return updateCount;
    }
运行并测试未开启事务的情况
image
image

抛出了异常但是数据修改成功了,我们需要做的是在动作出现异常时,所有的增删改的操作都要回滚

在PersonServiceImpl更新的实现方法上添加@Transactional注解
    @Override
    @Transactional
    public int updatePersonById(Person person) {
        int updateCount = personMapper.updateByPrimaryKeySelective(person);
        System.out.println("更新结果:" + updateCount);
        //在此构造一个除数为 0 的异常,测试事务是否起作用
        int a = 10/0;
        return updateCount;
    }
在Application类上加@EnableTransactionManagement注解开始事务支持
@SpringBootApplication
@MapperScan("com.mufeng.springbootweb.mapper")
@EnableTransactionManagement
public class SpringbootWebApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootWebApplication.class, args);
    }

}

@EnableTransactionManagement是可选的,但是业务方法上必须添加@Transactional事务才生效

修改Controller的修改用户信息的代码
@RequestMapping(value = "/springboot/updatePersonById")
    @ResponseBody
    public Object updatePersonById(){
        int count = 0;
        try{
            Person person = new Person();
            person.setId(1);
            person.setName("MuFeng_update");
            person.setAge(25);
            count = personService.updatePersonById(person);
        }catch (Exception e){
            e.printStackTrace();
            return "fail";
        }
        return count;
    }
运行测试
image
image

同样抛出了异常,但是数据库的年龄信息还是之前的20,并没有被修改,说明我们的事务开启成功了

你可能感兴趣的:(零基础学习SpringBoot(二)--集成MyBatis以及开启事务)