1. 程式人生 > >SpringBoot學習筆記(三):SpringBoot整合Mybatis、SpringBoot事務管理、SpringBoot多資料來源

SpringBoot學習筆記(三):SpringBoot整合Mybatis、SpringBoot事務管理、SpringBoot多資料來源

SpringBoot整合Mybatis

第一步我們需要在pom.xml裡面引入mybatis相關的jar包

   <dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>mysql<
/groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.21</version> </dependency>

在application.properties中填寫我們的連線資料庫相關的配置資訊

spring.datasource.url=jdbc:mysql://localhost:3306/springboot_mjxy?characterEncoding=utf-8 //?後面的是為了解決向資料庫中post資料時候的亂碼
spring.datasource.
username=root spring.datasource.password=admin spring.datasource.driver-class-name=com.mysql.jdbc.Driver #mybatis.mapper-locations=classpath:mapper/*.xml

首先自己在建一個位於entity包下面的User類對應於下面的這個表,並且提供get set方法。

在springboot_mjxy資料庫中新建一張user表,新增一條資料,結構如下:
在這裡插入圖片描述
然後我們新建一個commapper的包,在包下新建一個Interface名為:UserMapper程式碼如下:注意使用Mapper註解讓系統自己掃包到這裡

@Mapper
public interface UserMapper {

@Select("select * from user where id = #{id}")
User selectUserById(@Param("id") Integer id);

@Insert("INSERT INTO user (`id`, `username`, `sex`) VALUES (NULL, #{name}, #{sex});")
int insert(@Param("name") String name, @Param("sex") String sex);

}

然後我們按照正常實際生產的方式來進行獲取資料,新建Service層和實現層,這裡就只貼實現層的程式碼如下:
這裡也需要Service註解,也是讓系統自動掃包

@Service
public class UserServiceImpl implements UserService {

@Autowired
private UserMapper userMapper;

@Override
public User getUserById(Integer id) {
return userMapper.selectUserById(id);
}

@Override
public void insertUser(String name, String sex) {
userMapper.insert(name, sex);
}
}

最後我們新建一個Controller進行訪問資料,UserController程式碼如下:這裡我們就用RestController註解返回JSON

@RestController
@RequestMapping("/user")
public class UserController {

@Autowired
private UserService userService;

@RequestMapping("/get") //restful風格 @GetMapping
public Object getUser(Integer id) {
return userService.getUserById(id);
}

@RequestMapping("/add")  //restful風格 @PostMapping
public Object add(String name) {
System.out.println("add");
userService.insertUser(name, "SEX");
return "SUCCESS";
}
}

最後將專案啟動,什麼都不用做變動,直接通過瀏覽器訪問:http://127.0.0.1:8080/user/get?id=1,瀏覽器返回結果
到這裡就整合完畢了我們的MyBatis,我們這裡就不講深入了,這裡只要學習過SSM框架的都很簡單了,後面我們會整合一個非常牛X的框架,Mybatis-Plus,到時候你們會發現完全不用自己寫SQL了

SpringBoot事務管理

什麼是事物???
是指多個SQL作為單個邏輯工作單元執行的一系列操作,要麼完全地執行,要麼完全地不執行。
事物的四大特性(ACID):
原子性(Atomicity):對於其資料修改,要麼全都執行,要麼全都不執行。
一致性(Consistency):事務在完成時,必須使所有的資料都保持一致狀態。
隔離性(Isolation):由併發事務所作的修改必須與任何其它併發事務所作的修改隔離。
永續性(Durability):事務完成之後,它對於系統的影響是永久性的。

這裡只需要一個註解就搞定了:
@Transactional

小例子:
在UserMapper中新增兩個SQL,一個更新,一個刪除

@Update("UPDATE user SET username =#{name} WHERE id = #{id}")
int update(@Param("name") String name, @Param("id") Integer id);

@Delete("DELETE from user where id = #{id}")
void delete(@Param("id") Integer id);

然後在Service中寫一個事務測試方法

@Transactional
public void transcationtest(Integer id) {
           // 我們要做的操作,我們將某個使用者的NAME更新成待刪除,然後去刪除,但是中間我們製造一個異常出來
userMapper.update("DeleteTHIS", id);
System.out.println("異常之前");
int a = 2 / 0;
System.out.println("異常之後");
userMapper.delete(id);
}

然後執行檢視效果,發現Update根本不會成功,因為下面出現錯誤了,自動回滾。

SpringBoot多資料來源

什麼是多資料來源:多資料來源指的是如果一個web專案用到了多個數據庫,那麼就需要連線多個數據庫操作,這就是多資料來源。
多資料來源的好處:我要用到A資料庫(mysql)中 的某些資料進行資料驗證,並且要將資料插入B資料庫中。這樣做的好處是,不需要改變A中資料庫的結構,就算是連線更多資料庫的話,都不需要考慮其中結構問題,但是這就需要一個web項 目跟多個數據庫進行連線操作的技術。
專案結構:
在這裡插入圖片描述
配置檔案中,看配置檔案(代表兩個資料來源:用spring.datasource.test*區別):

spring.datasource.test1.driverClassName = com.mysql.jdbc.Driver
spring.datasource.test1.url = jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
spring.datasource.test1.username = root
spring.datasource.test1.password = admin

spring.datasource.test2.driverClassName = com.mysql.jdbc.Driver
spring.datasource.test2.url = jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8
spring.datasource.test2.username = root
spring.datasource.test2.password = admin

然後為每個配置源配置一個載入類:

/這裡配置mapper所在的包
@Configuration
@MapperScan(basePackages = "com.majiaxueyuan.mapper.test1", sqlSessionTemplateRef = "test1SqlSessionTemplate")//掃描的包
public class DataSource1Config {

@Bean(name = "test1DataSource")
@ConfigurationProperties(prefix = "spring.datasource.test1")//對應上面配置檔案中的名字
          
@Primary//primary代表主庫
public DataSource testDataSource() {
return DataSourceBuilder.create().build();
}

@Bean(name = "test1SqlSessionFactory")
@Primary
public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}

@Bean(name = "test1TransactionManager")
@Primary
public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}

@Bean(name = "test1SqlSessionTemplate")
@Primary
public SqlSessionTemplate testSqlSessionTemplate(
@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}

建一個相同的mapper
將裡面的test1全部改為test2,通過controller進行相應的操作。

這樣的話就配置完成,可以呼叫不用的Mapper,實際上是儲存在不同的庫中。
這裡大家會發現如果使用事務並且製造一個異常的話,會很明顯的出現幾種不同的效果,我們讓mapper1和mapper2在不同順序下面插入資料並且在中間丟擲異常,發現只有一個插入成功了,另外一個沒成功,為什麼呢?就是因為@Primary的原因,這樣就設定了主資料庫。這裡會發現設定了Primary的資料庫只要出錯都不會插入成功,都會事務回滾,大家注意了!!!!!

如果涉及到a資料庫去呼叫b資料庫,一般不會涉及到多資料來源的問題,因為,SpringBoot是分散式的微服務,將每個服務封裝起來呼叫相應的api即可。