《SpringBoot從入門到放棄》之第(八)篇——SpringBoot整合Mybatis(大型專案開發技術首選)
一千個讀者有一千個哈姆雷特。
你們的專案中,傾向於把資料庫的語句寫在Java類裡,還是使用Mybatis框架呢?
相對來說,做一些複雜的大專案,用第三方開源的Mybatis會比較好。把資料庫操作語句抽取出來,寫在xml檔案,方便管理。
個人比較傾向於使用Mybatis,還有Mybatis的逆向工程,聽說很好使,但本人還沒用過,後續會加上部落格,敬請期待吧!
專案結構,標註的是新增的檔案:
本篇部落格接著上一篇,在 pom.xml 裡新增 Mybatis 的jar依賴:
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency>
在 resources 資料夾下建立 mybatis-config.xml 配置檔案,與application.properties同一級:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 全域性配置引數 --> <settings> <!-- 使全域性的對映器啟用或禁用快取。 --> <setting name="cacheEnabled" value="true"/> <!-- debug 模式列印 sql 語句 --> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> </configuration>
介面 UserDao,注意需要新增 @Mapper 註解,否則無法呼叫Mybatis框架:
或者在啟動的類加上:@MapperScan("com.test.dao") 註解,掃描的是Dao層的包。這樣就不需要在每個 Dao 類里加入註解@Mapper 了。
package com.test.dao; import com.test.entity.User; import org.apache.ibatis.annotations.Mapper; import java.util.List; @Mapper public interface UserDao { /** * 新增使用者 * @param user * @return */ Integer addUserMybatis(User user); /** * 根據id刪除使用者 * @param id * @return */ Integer deleteUserMybatis(Integer id); /** * 更新使用者資訊 * @param user * @return */ Integer updateUserMybatis(User user); /** * 查詢所有使用者資訊 * @return */ List<User> getUserMybatis(); }
業務層,UserServiceMybatis(為了和之前的UserService做區分):
package com.test.service;
import com.test.dao.UserDao;
import com.test.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class UserServiceMybatis {
@Autowired
private UserDao userDao;
/**
* 新增使用者
* @param user
* @return
*/
@Transactional(readOnly = false)
public Integer addUserMybatis(User user){
return userDao.addUserMybatis(user);
}
/**
* 根據id刪除使用者
* @param id
* @return
*/
@Transactional(readOnly = false)
public Integer deleteUserMybatis(Integer id){
return userDao.deleteUserMybatis(id);
}
/**
* 更新使用者資訊
* @param user
* @return
*/
@Transactional(readOnly = false)
public Integer updateUserMybatis(User user){
return userDao.updateUserMybatis(user);
}
/**
* 查詢所有使用者資訊
* @return
*/
@Transactional(readOnly = true)
public List<User> getUserMybatis(){
return userDao.getUserMybatis();
}
}
說明:可以看到我使用了事務註解 @Transactional(readOnly = true),@Transactional(readOnly = false),在一些增、刪、改、呼叫儲存過程的方法中,需要把 readOnly 設定為 false,預設的是false,可以不新增。以後的開發中,在一些關鍵的查詢操作,可以指定 readOnly 屬性。
UserMapper.xml,檔案的名字可以自定義,但需要顧名思義:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.test.dao.UserDao">
<!-- 資料庫欄位與實體類欄位的對映,column是資料庫的列名,property是實體類的屬性名 -->
<resultMap id="UserBaseResultMap" type="com.test.entity.User">
<id column="id" jdbcType="INTEGER" property="id"/>
<result column="name" jdbcType="VARCHAR" property="name"/>
<result column="signature" jdbcType="VARCHAR" property="signature"/>
</resultMap>
<!-- 新增使用者,id就是方法名 -->
<insert id="addUserMybatis">
insert into t_user (name,signature) values (#{name},#{signature})
</insert>
<!-- 刪除使用者,id就是方法名,parameterType可以寫,也可以不寫。 -->
<delete id="deleteUserMybatis" parameterType="java.lang.Integer">
delete from t_user where id = #{id,jdbcType=INTEGER}
</delete>
<!-- 修改使用者 -->
<update id="updateUserMybatis">
update t_user set name = #{name},signature =#{signature} where id = #{id}
</update>
<!-- 查詢所有使用者,將結果對映到 UserBaseResultMap 對應的屬性中,如果有多個結果集,會返回多個實體類 -->
<select id="getUserMybatis" resultMap="UserBaseResultMap">
select * from t_user
</select>
</mapper>
需要注意的是:①mapper namespace="com.test.dao.UserDao"
②諸如 select、insert、update的id,對應的是Dao層的方法名。配置檔案的 id 是不允許重複的,意思就是說,在 Dao 層裡,不允許方法過載。
想學習更多關於Mybatis的知識,可以去Mybatis中文官網學習。
MybatisController,注意,在類的簽名裡使用了 @RestController 的註解,預設的返回 Json 格式資料。
package com.test.web;
import com.test.entity.User;
import com.test.service.UserServiceMybatis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
public class MybatisController {
@Autowired
private UserServiceMybatis userServiceMybatis;
/**
* 新增使用者
* @param name
* @param signature
* @return
*/
@RequestMapping(value = "/addUserMybatis")
public Map<String,Integer> addUserMybatis(@RequestParam String name, @RequestParam String signature){
User u=new User();
u.setName(name);
u.setSignature(signature);
Integer count = userServiceMybatis.addUserMybatis(u);
Map<String, Integer> map = new HashMap<>();
map.put("count", count);
return map;
}
/**
* 根據id刪除使用者資訊
* @param id
* @return
*/
@RequestMapping(value = "/deleteUserMybatis")
public Map<String,Integer> deleteUserMybatis(@RequestParam Integer id){
Integer count = userServiceMybatis.deleteUserMybatis(id);
Map<String, Integer> map = new HashMap<>();
map.put("count", count);
return map;
}
/**
* 更新使用者資訊
* @param id
* @param name
* @param signature
* @return
*/
@RequestMapping(value = "/updateUserMybatis")
public Map<String,Integer> updateUserMybatis(@RequestParam Integer id,@RequestParam String name, @RequestParam String signature){
User u=new User();
u.setId(id);
u.setName(name);
u.setSignature(signature);
Integer count = userServiceMybatis.updateUserMybatis(u);
Map<String, Integer> map = new HashMap<>();
map.put("count", count);
return map;
}
/**
* 查詢所有使用者資訊
* @return
*/
@RequestMapping(value = "/getUserMybatis")
public List<User> getUserMybatis(){
List<User> list = userServiceMybatis.getUserMybatis();
return list;
}
}
最關鍵的,application.properties 配置:
# 服務埠
server.port=9090
# 資料庫連線配置
spring.datasource.url=jdbc:mysql://localhost:3306/mytest
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# Mybatis配置
# Mybatis掃描的mapper檔案
mybatis.mapperLocations=classpath:mappings/**/*.xml
# 掃描哪個包下的域物件
mybatis.typeAliasesPackage=com.test.entity
# Mybatis配置檔案
mybatis.configLocation=classpath:mybatis-config.xml
# mybatis.typeAliasesSuperType 掃描包以下面的這個類作為父類的域物件
如果遇到下面類似的問題,就是因為 Mybatis 的配置沒有完善
O的K,萬事俱備只欠東風,用吊炸天的 postman 測試一下:
①測試新增使用者,很OK:
去到編輯器的控制檯檢視列印的資料庫語句:
Registering transaction synchronization for SqlSession [[email protected]]
JDBC Connection [[email protected] wrapping [email protected]] will be managed by Spring
==> Preparing: insert into t_user (name,signature) values (?,?)
==> Parameters: 小米(String), 為發燒而生(String)
<== Updates: 1
②查詢所有使用者:
③修改使用者:
④刪除使用者:http://localhost:9090/deleteUserMybatis?id=2
完美整合Mybatis!
說明:其實也可以直接從 Controller 層呼叫 Dao 層,而不需要 Service 層,也是可以實現邏輯。加多一層 Service 能更好的增加許可權控制、事務管理或者其它功能。