MyBatis前身是apache的一個開源項目iBatis,2010年這個項目由apache software foundation 遷移到了google code,而且更名爲MyBatis2013年11月遷移到Github。html
他是一個支持普通SQL查詢,存儲過程和高級映射的優秀持久層框架。他消除了幾乎全部的JDBC代碼和參數的手工設置以及對結果集的檢索封裝,支持簡單的XML或註解用於配置和原始映射,將接口和Java的POJO(Plain Old Java Objects,普通的Java對象)映射成數據庫中的記錄。java
這一節,咱們將學習如何將mybatis整合到咱們的項目中,輔助數據庫操做。mysql
一樣採用SpringInitializer建立項目,選擇以下模塊:web
引入mybatis只需引入依賴spring
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency>
從其
artifactId
咱們能夠了解到,這不是官方包。sql
咱們按整合jdbc與數據源那一章節配置的方式將基礎環境配置好。docker
server: port: 8086 spring: datasource: username: root password: 123456 url: jdbc:mysql://10.21.1.47:3306/joyblack?characterEncoding=utf8&serverTimezone=GMT driver-class-name: com.mysql.cj.jdbc.Driver initialization-mode: always sql-script-encoding: utf-8 schema: - classpath:sql/joyblack.sql
而後倒入咱們建立數據庫以及倒入數據的sql文件,爲了偷懶,咱們統一將其放在schema邏輯中。該腳本建立了兩張表user以及department,分別表明用戶信息以及用戶所在的部門信息,並導入了3個冒險者用戶以及2個工會部門。數據庫
/* Navicat MySQL Data Transfer Source Server : docker Source Server Version : 50505 Source Host : 10.21.1.47:3306 Source Database : joyblack Target Server Type : MYSQL Target Server Version : 50505 File Encoding : 65001 Date: 2018-12-20 09:45:44 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `department` -- ---------------------------- DROP TABLE IF EXISTS `department`; CREATE TABLE `department` ( `id` int(11) NOT NULL, `department_name` varchar(30) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of department -- ---------------------------- INSERT INTO `department` VALUES ('1', '鄉下冒險者公會'); INSERT INTO `department` VALUES ('2', '城市冒險者公會'); -- ---------------------------- -- Table structure for `user` -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL, `user_name` varchar(20) NOT NULL, `login_name` varchar(20) NOT NULL, `deparment_id` int(11) NOT NULL DEFAULT 1, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES ('1', '阿庫婭', 'akuya', '1'); INSERT INTO `user` VALUES ('2', '克里斯汀娜', 'crustina', '1'); INSERT INTO `user` VALUES ('3', '惠惠', 'huihui', '1');
咱們接下來跑一下應用程序,初始化數據庫信息。爲了運行快速一點,以後咱們應該把配置文件中的 schema:- classpath:sql/joyblack.sql
給註釋掉,下次就不要在初始化了。apache
接下來咱們建立對應的Bean,關聯數據庫表實體。json
package com.zhaoyi.mbweb.bean; public class User { private Integer id; private String loginName; private String userName; private Integer departmentId; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getLoginName() { return loginName; } public void setLoginName(String loginName) { this.loginName = loginName; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public Integer getDepartmentId() { return departmentId; } public void setDepartmentId(Integer departmentId) { this.departmentId = departmentId; } }
package com.zhaoyi.mbweb.bean; public class Department { private Integer id; private String departmentName; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getDepartmentName() { return departmentName; } public void setDepartmentName(String departmentName) { this.departmentName = departmentName; } }
準備工做完成了,咱們能夠準備使用mybatis了。
接下來咱們就可使用mybatis提供的便利操做數據庫了,不過也有不一樣的操做方式,咱們先一個一個的來。
基於註解的方式無需指明任何配置,直接編寫相關的註解語句便可,咱們只專一本身的Mapper就能夠了。
接下來咱們測試一下怎麼使用基於註解的方式操做數據庫。咱們新建一個Mapper接口,裏面包括了基本的增刪查改操做:
package com.zhaoyi.mbweb.mapper; import com.zhaoyi.mbweb.bean.Department; import org.apache.ibatis.annotations.*; @Mapper public interface DepartmentMapper { // insert a derpartment. // @Options(useGeneratedKeys = true, keyProperty = "id") may you want get insert data generated id. @Insert("insert into department(id,department_name) values(#{id}, #{departmentName})") int insertDepartment(Department department); // delete a department by id. @Insert("delete from department where id = #{id}") int deleteDepartment(Integer id); // query a department by id. @Select("select * from department where id = #{id}") Department getDepartmentById(Integer id); // update a department information. @Update("update department set department_name=#{departmentName} where id=#{id}") int updateDepartment(Department department); }
其中:
@Mapper
指定這是一個操做數據庫的Mapper;@Options(useGeneratedKeys = true, keyProperty = "id")
,這樣,在插入後mybatis就會自動的將id屬性回寫到你的插入對象中了;#{xxx}
語法提取參數中傳遞的值;而後,編寫一個controller來測試這些操做,爲了方便,咱們就只測試查詢和插入操做便可:
package com.zhaoyi.mbweb.controller; import com.zhaoyi.mbweb.bean.Department; import com.zhaoyi.mbweb.mapper.DepartmentMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController public class DepartmentController { @Autowired private DepartmentMapper departmentMapper; @GetMapping("/department/{id}") public Department getDepartment(@PathVariable("id") Integer id){ return departmentMapper.getDepartmentById(id); } @GetMapping("/department") public Department insertDepartment(Department department){ departmentMapper.insertDepartment(department); return department; } }
其中:
getDepartment
映射/department/{id}
的請求,用於處理查詢某個id的部門信息,id寫在路徑參數中;insertDepartment
映射/department?xxx=xxx
的請求,用於插入get傳遞的參數中指定的部門信息;一切完畢,運行項目後,咱們分別測試兩個操做的結果:
http://localhost:8086/department/2
,咱們能夠獲得如下的輸出:{"id":2,"departmentName":null}
http://localhost:8086/department?id=3&name=廣州冒險者公會
,咱們獲得如下的輸出:{"id":3,"departmentName":"廣州冒險者公會"}
並能夠在數據庫中看到該條數據。這就是基於註解的方式來使用mybatis操做數據庫。
細心的朋友應該會發現,查詢的部門信息的時候返回的數據的departmentName
的值爲空。這顯然是不對的,咱們能夠留意到在數據庫中咱們的命名方式是下劃線的department_name,而bean中則是departmentName。這就須要咱們開啓駝峯映射規則,來提醒mybatis將數據庫的下劃線字段和bean的駝峯變量關聯起來。
如何修改呢?
咱們觀察mybatis的自動配置類
@EnableConfigurationProperties({MybatisProperties.class}) @AutoConfigureAfter({DataSourceAutoConfiguration.class}) public class MybatisAutoConfiguration { ... @Bean @ConditionalOnMissingBean public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { SqlSessionFactoryBean factory = new SqlSessionFactoryBean(); factory.setDataSource(dataSource); factory.setVfs(SpringBootVFS.class); if (StringUtils.hasText(this.properties.getConfigLocation())) { factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation())); } org.apache.ibatis.session.Configuration configuration = this.properties.getConfiguration(); if (configuration == null && !StringUtils.hasText(this.properties.getConfigLocation())) { configuration = new org.apache.ibatis.session.Configuration(); } // 從這裏能夠知道能夠經過配置ConfigurationCustomizer來操做mybatis的配置 if (configuration != null && !CollectionUtils.isEmpty(this.configurationCustomizers)) { Iterator var4 = this.configurationCustomizers.iterator(); while(var4.hasNext()) { ConfigurationCustomizer customizer = (ConfigurationCustomizer)var4.next(); customizer.customize(configuration); } } factory.setConfiguration(configuration); if (this.properties.getConfigurationProperties() != null) { factory.setConfigurationProperties(this.properties.getConfigurationProperties()); } if (!ObjectUtils.isEmpty(this.interceptors)) { factory.setPlugins(this.interceptors); } if (this.databaseIdProvider != null) { factory.setDatabaseIdProvider(this.databaseIdProvider); } if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) { factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage()); } if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) { factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage()); } if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) { factory.setMapperLocations(this.properties.resolveMapperLocations()); } return factory.getObject(); } ... }
能夠發現,咱們能夠經過增長ConfigurationCustomizer
類型的Bean,就能夠修改mybatis的配置信息了。添加配置:
package com.zhaoyi.mbweb.config; import org.apache.ibatis.session.Configuration; import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer; import org.springframework.context.annotation.Bean; @org.springframework.context.annotation.Configuration public class MyBatisConfig { @Bean public ConfigurationCustomizer configurationCustomizer(){ return new ConfigurationCustomizer(){ @Override public void customize(Configuration configuration) { // 開啓駝峯映射規則 configuration.setMapUnderscoreToCamelCase(true); } }; } }
接下來,咱們重啓項目,就能夠發現,能夠正常的得到部門信息了,繼續訪問剛纔的地址http://localhost:8086/department/2
,獲取id爲2的部門信息:
{"id":2,"departmentName":"城市冒險者公會"}
經過前面的介紹,咱們須要留意一點,就是編寫Mapper的時候要爲其添加@Mapper
註解,這樣才能讓mybatis識別這些mapper。可是在實際的開發過程當中,Mapper確定是一個很多的量的,至少,爲了簡潔考慮,您須要爲每一個數據表映射一個Mapper,有沒有一種一勞永逸的方法呢?
有!
咱們只需在MyBaticConfig加上掃描註解或者SpringBoot的啓動類上添加@MapperScan(value="your mapper packagePath")
,例如,咱們能夠在上面的mybatis配置類這樣寫:
// batch scan all mapper class. @MapperScan(value = "com.zhaoyi.mbweb.mapper") @org.springframework.context.annotation.Configuration public class MyBatisConfig {
com.zhaoyi.mbweb.mapper
是個人mapper所在的包名,請按您本身的包名進行填寫。
更多信息請參考: 官方文檔
前面咱們使用了基於註解的方式對數據庫進行了操做,如今,咱們試試另一種方式,經過配置文件的方式來使用mybatis操做數據庫。爲了方便,咱們接下來的這種方式就來操做user表進行演示便可。
首先,編寫一個user的mapper
package com.zhaoyi.mbweb.mapper; import com.zhaoyi.mbweb.bean.User; public interface UserMapper { int insertUser(User user); int deleteUser(Integer id); User getUserById(Integer id); int updateUser(User user); }
和以前的DepartmentMapper
不一樣的是,咱們這裏並無添加註解,由於,咱們將會把他們寫在對應的mybatis SQL映射文件中。
接下來咱們要指定Mybatis配置文件以及Mybatis SQL映射文件的路徑,在配置文件中添加以下配置
server: port: 8086 spring: datasource: username: root password: 123456 url: jdbc:mysql://10.21.1.47:3306/joyblack?characterEncoding=utf8&serverTimezone=GMT driver-class-name: com.mysql.cj.jdbc.Driver initialization-mode: always sql-script-encoding: utf-8 #schema: # - classpath:sql/joyblack.sql mybatis: # mybatis配置文件 config-location: classpath:mybatis/mybatis-config.xml # SQL映射文件路徑,查看源碼他是一個String數組,不過咱們直接配置"*"通配符便可,表明全部的xml文件 mapper-locations: classpath:mybatis/mapper/*.xml
在資源文件夾下建立mybatis文件夾,並放入mybatis-config.xml(和全局配置指定的路徑一致)配置文件
<?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="mapUnderscoreToCamelCase" value="true" /> </settings> </configuration>
裏面配置一些相關配置,例如數據庫鏈接信息等,但這些咱們已經在數據源配置了,這裏就無需配置。
若是咱們沒有在mybatis的主配置文件中配置mapUnderscoreToCamelCase
,這時候咱們去查詢部門相關的信息,發現名字又爲空了。由於當使用配置文件以後,咱們的自定義配置中設置的駝峯式映射邏輯已經被配置文件的默認配置覆蓋掉了。所以,咱們須要在配置文件中指定駝峯時映射規則:
<?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="mapUnderscoreToCamelCase" value="true" /> </settings> </configuration>
能夠發現,配置項mapUnderscoreToCamelCase
和咱們使用配置文件的屬性名是如出一轍的。
從這裏能夠看出,兩種方式混用也是能夠的,可是問題很明顯,配置會衝突。因此你們在開發的時候最好仍是選擇其中一種方式,從始至終進行,避免管理上的複雜以及邏輯的混亂。
對應配置文件建立一個mapper文件夾,用於放咱們的SQL映射文件,在這裏咱們建立一個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.zhaoyi.mbweb.mapper.UserMapper"> <!-- int insertUser(User user); int deleteUser(Integer id); User getUserById(Integer id); int updateUser(User user);--> <insert id="insertUser"> insert into user(id, login_name, user_name, department_id) values (#{id}, #{loginName}, #{userName}, #{departmentId}) </insert> <delete id="deleteUser"> delete from user where id = #{id} </delete> <select id="getUserById" resultType="com.zhaoyi.mbweb.bean.User"> select * from user where id = #{id} </select> <update id="updateUser"> update user set user_name = #{userName} where id = #{id} </update> </mapper>
接下來就是編寫controller測試curd4個操做了。
package com.zhaoyi.mbweb.controller; import com.zhaoyi.mbweb.bean.User; import com.zhaoyi.mbweb.mapper.UserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @Autowired private UserMapper userMapper; @RequestMapping("/user/insert") public User insertUser(User user){ userMapper.insertUser(user); return user; } @RequestMapping("/user/delete/{id}") public Integer insertUser(@PathVariable("id") Integer id){ return userMapper.deleteUser(id); } @RequestMapping("/user/select/{id}") public User getUser(@PathVariable("id") Integer id){ return userMapper.getUserById(id); } @RequestMapping("/user/update") public User updateUser(User user){ userMapper.updateUser(user); return user; } }
測試:
{"id":4,"loginName":"youyou","userName":"悠悠","departmentId":2}
這時候查看數據庫,記錄已經增長。 2. 訪問:http://localhost:8086/user/update?id=4&userName=悠悠改,修改新增長的悠悠的信息 {"id":4,"loginName":null,"userName":"悠悠","departmentId":null} 由於咱們返回的是傳入的參數,因此其餘兩個字段的空值是正常的。
1
返回的是操做影響的記錄條數,顯然是1條,而且數據庫中記錄已經被刪除。
{"id":2,"loginName":"crustina","userName":"克里斯汀娜","departmentId":1}
以上就是基於配置方式整合mybatis了,能夠根據本身的須要,選擇本身喜歡的開發方式。以前開發的項目差很少也是兩種方式的混合體,可是時代在進步,既然用了springboot就不能少了JPA相關的理念,接下來,咱們就學習JPA相關的東西,看看spring data還有什麼有趣的內容。