您好,登錄后才能下訂單哦!
整合Mybtis對(duì)于Spring Boot來說,是非常簡(jiǎn)單的, 通過這一篇文章, 你可以無壓力快速入門,不過開始之前我要說一下我的版本信息:
maven 3.2.5
jdk 1.8
Spring Boot 2.1.6
創(chuàng)建項(xiàng)目
依然是使用idea的自動(dòng)化配置, 不過這里,我們需要勾選以下依賴:
如果你勾選了 MyBatis , 你會(huì)發(fā)現(xiàn)你的pom文件里有 :
<dependency> ?<groupId>org.mybatis.spring.boot</groupId> ?<artifactId>mybatis-spring-boot-starter</artifactId> ?<version>2.1.0</version> ?</dependency>
這條依賴
只要是帶 *-spring-boot-starter的,都是Spring Boot官方推薦的, 這里的mybatis就是, 讓我們來看一下mybatis包下的所有包:
我們發(fā)現(xiàn)它引入了, mybatis-spring 的包等等,以及還有mybatis-spring-boot-autoconfigure, 這個(gè)是自動(dòng)配置的意思, 對(duì)于Spring Boot來說,自動(dòng)配置是一大特點(diǎn)
配置Druid數(shù)據(jù)源
Spring Boot2.x的數(shù)據(jù)源 hikari 的, 而1.x則是 Tomcat的, 所以我們要配置以下自己的數(shù)據(jù)源
?<dependency> ?<groupId>com.alibaba</groupId> ?<artifactId>druid</artifactId> ?<version>1.1.16</version> ?</dependency>
引入這個(gè)依賴就好了
然后在 application.yml 配置文件下:
spring: ?datasource: ?password:?root ?username:?root ?url:?jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC ?driver-class-name:?com.mysql.cj.jdbc.Driver ?type:?com.alibaba.druid.pool.DruidDataSource ?initialSize:?5 ?minIdle:?5 ?maxActive:?20 ?maxWait:?60000 ?timeBetweenEvictionRunsMillis:?60000 ?minEvictableIdleTimeMillis:?300000 ?validationQuery:?SELECT?1?FROM?DUAL ?testWhileIdle:?true ?testOnBorrow:?false ?testOnReturn:?false ?poolPreparedStatements:?true ?#?配置監(jiān)控統(tǒng)計(jì)攔截的filters,去掉后監(jiān)控界面sql無法統(tǒng)計(jì),'wall'用于防火墻 ?filters:?stat,wall,log4j ?maxPoolPreparedStatementPerConnectionSize:?20 ?useGlobalDataSourceStat:?true ?connectionProperties:?druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
下面這一堆的屬性是不生效的, 如果想要生效, 需要特殊配置一下, Druid監(jiān)控也配置了:
package?com.carson.config; import?com.alibaba.druid.pool.DruidDataSource; import?com.alibaba.druid.support.http.StatViewServlet; import?com.alibaba.druid.support.http.WebStatFilter; import?org.springframework.boot.context.properties.ConfigurationProperties; import?org.springframework.boot.web.servlet.FilterRegistrationBean; import?org.springframework.boot.web.servlet.ServletRegistrationBean; import?org.springframework.context.annotation.Bean; import?org.springframework.context.annotation.Configuration; import?javax.sql.DataSource; import?java.util.Arrays; import?java.util.HashMap; import?java.util.Map; @Configuration public?class?DruidConfig?{ ?@ConfigurationProperties(prefix?=?"spring.datasource") ?@Bean ?public?DataSource?druid()?{ ?return?new?DruidDataSource(); ?} ?//?配置?Druid?監(jiān)控 ?//1)?配置一個(gè)管理后臺(tái)的Servlet ?@Bean ?public?ServletRegistrationBean?statViewServlet()?{ ?ServletRegistrationBean?bean?=?new?ServletRegistrationBean(new?StatViewServlet(),?"/druid/*"); ?Map<String,?String>?initParams?=?new?HashMap<>(); ?//?這里是?druid?monitor(監(jiān)視器)的?賬號(hào)密碼,?可以任意設(shè)置 ?initParams.put("loginUsername",?"admin"); ?initParams.put("loginPassword",?"123456"); ?initParams.put("allow",?""); ?initParams.put("deny",?"192.123.11.11"); ?//?設(shè)置初始化參數(shù) ?bean.setInitParameters(initParams); ?return?bean; ?} ?//?2)配置一個(gè)監(jiān)控的?filter ?@Bean ?public?FilterRegistrationBean?webStatFilter()?{ ?FilterRegistrationBean?bean?=?new?FilterRegistrationBean(); ?bean.setFilter(new?WebStatFilter()); ?Map<String,?String>?initParams?=?new?HashMap<>(); ?initParams.put("exclusions","*.js,*.css,/druid/*"); ?bean.setInitParameters(initParams); ?bean.setUrlPatterns(Arrays.asList("/*")); ?return?bean; ?} }
啟動(dòng)主類, 查看是否可以進(jìn)入到?德魯伊監(jiān)視器, 如果你報(bào)錯(cuò)了請(qǐng)?zhí)砑?log4j 依賴:
?<dependency> ?<groupId>log4j</groupId> ?<artifactId>log4j</artifactId> ?<version>1.2.17</version> ?</dependency> <!--我也不清楚為什么,?不加log4j的話就會(huì)報(bào)錯(cuò)-->
查看效果:
利用SpringBoot建表
然后在 resources/sql 下引入兩個(gè)建表的sql文件:
department.sql:
SET?FOREIGN_KEY_CHECKS?=?0; --?---------------------------- --?Table?structure?for?department --?---------------------------- DROP?TABLE?IF?EXISTS?`department`; CREATE?TABLE?`department`?( ?`id`?INT(11)?NOT?NULL?AUTO_INCREMENT, ?`departmentName`?VARCHAR(255)?DEFAULT?NULL, ?PRIMARY?KEY?(`id`) ) ?ENGINE?=?InnoDB ?AUTO_INCREMENT?=?1 ?DEFAULT?CHARSET?=?utf8;
employee.sql:
SET?FOREIGN_KEY_CHECKS?=?0; --?---------------------------- --?Table?structure?for?employee --?---------------------------- DROP?TABLE?IF?EXISTS?`employee`; CREATE?TABLE?`employee`?( ?`id`?INT(11)?NOT?NULL?AUTO_INCREMENT, ?`lastName`?VARCHAR(255)?DEFAULT?NULL, ?`email`?VARCHAR(255)?DEFAULT?NULL, ?`gender`?INT(2)?DEFAULT?NULL, ?`d_id`?INT(11)?DEFAULT?NULL, ?PRIMARY?KEY?(`id`) ) ?ENGINE?=?InnoDB ?AUTO_INCREMENT?=?1 ?DEFAULT?CHARSET?=?utf8;
并且在 application.yml 文件下寫入:
?schema: ?-?classpath:sql/department.sql ?-?classpath:sql/employee.sql ?initialization-mode:?always
schema`是與 password/username 等等同級(jí)的,哦對(duì)了, 如果你是 springboot 2.x版本以上的, 你可能需要加上initialization-mode這個(gè)屬性。
運(yùn)行主類, 查看是否建表成功,
如果你的程序在設(shè)置sql文件后 啟動(dòng)報(bào)錯(cuò)了:
重啟 idea (重啟大法好啊!)
查看 schema是否配置對(duì)了 sql文件的名字
schema:
-(空格)classpath:sql/xxx.sql
注意格式
對(duì)應(yīng)數(shù)據(jù)庫實(shí)體類
Employee.java
package?com.carson.domain; public?class?Employee?{ ?private?Integer?id; ?private?String?lastName; ?private?Integer?gender; ?private?String?email; ?private?Integer?dId; ?public?Integer?getId()?{ ?return?id; ?} ?public?void?setId(Integer?id)?{ ?this.id?=?id; ?} ?public?String?getLastName()?{ ?return?lastName; ?} ?public?void?setLastName(String?lastName)?{ ?this.lastName?=?lastName; ?} ?public?Integer?getGender()?{ ?return?gender; ?} ?public?void?setGender(Integer?gender)?{ ?this.gender?=?gender; ?} ?public?String?getEmail()?{ ?return?email; ?} ?public?void?setEmail(String?email)?{ ?this.email?=?email; ?} ?public?Integer?getdId()?{ ?return?dId; ?} ?public?void?setdId(Integer?dId)?{ ?this.dId?=?dId; ?} }
Department.java
package?com.carson.domain; 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; ?} }
記得把剛才我配置文件的 schema屬性全部注釋掉, 我們不希望下次運(yùn)行的時(shí)候會(huì)再次創(chuàng)建表
數(shù)據(jù)庫交互
- 注解版
建立一個(gè) Mapper, 把sql語句直接寫在上面
package?com.carson.mapper; import?com.carson.domain.Department; import?org.apache.ibatis.annotations.*; //?指定這是一個(gè)?mapper @Mapper public?interface?DepartmentMapper?{ ?@Select("select?*?from?department?where?id=#{id}") ?public?Department?getDepById(Integer?id); ?@Delete("delete?from?department?where?id=#{id}") ?public?int?deleteDepById(Integer?id); ?@Insert("insert?into?department(departmentName)?values(#{departmentName})") ?public?int?insertDept(Department?department); ?@Update("update?department?set?departmentName=#{departmentName}?where?id=#{id}") ?public?int?updateDept(Department?department); }
然后寫一個(gè)Controller :
package?com.carson.controller; import?com.carson.domain.Department; import?com.carson.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?//?代表返回?json?數(shù)據(jù)的?controller public?class?DeptController?{ ?@Autowired ?DepartmentMapper?departmentMapper; ?@GetMapping("/dept/{id}") ?public?Department?getDept(@PathVariable("id")?Integer?id)?{ ?return?departmentMapper.getDepById(id); ?} ?@GetMapping ?public?Department?inserDept(Department?department)?{ ?departmentMapper.insertDept(department); ?return?department; ?} }
通過?@PathVariable?可以將?URL?中占位符參數(shù)綁定到控制器處理方法的入?yún)⒅校篣RL 中的 {xxx} 占位符可以通過@PathVariable(“xxx“) 綁定到操作方法的入?yún)⒅小?/p>
啟動(dòng)主類, 輸入這個(gè): localhost:8080/dept?departmentName=AA , 這是往數(shù)據(jù)庫增加一條數(shù)據(jù):
然后查詢: localhost:8080/dept/3 , 我數(shù)據(jù)庫id是3, 所以我要查詢3:
不過發(fā)現(xiàn)一個(gè)問題, 在插入數(shù)據(jù)的時(shí)候獲取不到 id:
所以我們要使用一個(gè)@Options注解:
?@Options(useGeneratedKeys?=?true,keyProperty?=?"id") ?@Insert("insert?into?department(departmentName)?values(#{departmentName})") ?public?int?insertDept(Department?department);
添加到剛才 mapper中insert 的 @value注解上面
useGeneratedKeys : 使用生成的主鍵
keyProperty: 意思是 Department 里面的哪個(gè)屬性是主鍵, 就是我們的 id
試著插入一條數(shù)據(jù):
但是實(shí)際忘記注釋掉 schema , 導(dǎo)致每次運(yùn)行都會(huì)重新創(chuàng)建數(shù)據(jù)庫, 各位要注意
還有一個(gè)問題
我們把數(shù)據(jù)庫的字段名改成 department_name 而實(shí)體類是departmentName;
并且把sql語句也改正
?@Options(useGeneratedKeys?=?true,keyProperty?=?"id") ?@Insert("insert?into?department(department_name)?values(#{departmentName})") ?public?int?insertDept(Department?department); ?@Update("update?department?set?department_name=#{departmentName}?where?id=#{id}") ?public?int?updateDept(Department?department);
然后在進(jìn)行查詢操作的話:
我們發(fā)現(xiàn)獲取不到 departmentName 了, 以前Spring 我們是使用配置文件來應(yīng)對(duì)這種情況的, 但是我們現(xiàn)在沒有了xml文件,我們?cè)撛趺崔k呢?
世上無難事
創(chuàng)建自定義配置類:
package?com.carson.config; import?org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer; import?org.springframework.context.annotation.Bean; import?org.springframework.context.annotation.Configuration; @Configuration public?class?MyBatisConfig?{ ?@Bean ?public?ConfigurationCustomizer?configurationCustomizer()?{ ?return?new?ConfigurationCustomizer()?{ ?@Override ?public?void?customize(org.apache.ibatis.session.Configuration?configuration)? ?{ ?configuration.setMapUnderscoreToCamelCase(true); ?} ?}; ?} }
注意這里面的 setMapUnderscoreToCamelCase,意思是:
翻譯大法好啊, 我的英文太差了, 再次訪問 http://localhost:8080/dept/1 查詢操作, 我發(fā)現(xiàn)已經(jīng)不是 null了:
{"id":1,"departmentName":"jackMa"}
馬總正確的展現(xiàn)出來了!
MapperScan注解
掃描器, 用來掃描mapper接口的
我把它標(biāo)記到 啟動(dòng)類 上(你可以標(biāo)記在任何地方):
指定一個(gè)包,它會(huì)掃描這個(gè)包下所有的 mapper 接口, 防止你的mapper文件太多, 并且忘記加 @mapper 注解, 這樣可以提高正確性
- 配置文件版
注解版貌似很方便, 但是如果遇到復(fù)雜的sql , 比如動(dòng)態(tài)sql等等, 還是需要用 xml 配置文件的;
創(chuàng)建一個(gè) Employee 的Mapper接口:
package?com.carson.mapper; import?com.carson.domain.Employee; public?interface?EmployeeMapper?{ ?public?Employee?getEmpById(Integer?id); ?public?void?insertEmp(Employee?employee); }
在 resources/mybatis 下創(chuàng)建一個(gè) 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> </configuration>
在 resources/mybatis/mapper 包下創(chuàng)建 EmployeeMapper.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"> <!--?綁定接口?并且寫兩條?SQL?語句--> <mapper?namespace="com.carson.mapper.EmployeeMapper"> ?<select?id="getEmpById"?resultType="com.carson.domain.Employee"> ?select?*?from?employee?where?id?=?#{id} ?</select> ?<insert?id="insertEmp"> ?insert?into?employee(lastName,email,gender,d_id)?values?(#{lastName}, ? #{email},#{gender},#{d_id}) ?</insert> </mapper>
然后再 application.yml 配置文件下添加一條配置:
#?mybatis屬性是跟?spring?屬性平級(jí)的,?千萬不要把格式搞錯(cuò) mybatis: #?指定全局配置文件 ?config-location:?classpath:mybatis/mybatis-config.xml #?指定?mapper?映射文件,?*?代表所有? ?mapper-locations:?classpath:mybatis/mapper/*.xml
讓我們?cè)趧偛诺腄eptController類里添加一段 Controller :
?@Autowired ?EmployeeMapper?employeeMapper ? ?@GetMapping("emp/{id}") ?public?Employee?getEmp(@PathVariable("id")?Integer?id)?{ ?return?employeeMapper.getEmpById(id); ?}
啟動(dòng)主類訪問一下 localhost:8080/emp/1 , 查看結(jié)果:
我們發(fā)現(xiàn) dId沒有查詢出來, 這是因?yàn)?數(shù)據(jù)庫字段是 d_id , 而java里是 dId , 所以我們要像剛才注解版一樣, 配置一樣?xùn)|西, 讓我們打開 mapper全局配置文件添加:
<?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 : 是否開啟自動(dòng)駝峰命名規(guī)則(camel case)映射,即從經(jīng)典數(shù)據(jù)庫列名 A_COLUMN 到經(jīng)典 Java 屬性名 aColumn 的類似映射。
再次試驗(yàn):
可以看出已經(jīng)成功了
無論是哪種版本. 要根據(jù)自己的實(shí)際情況來定, 注解雖然方便, 但是復(fù)雜業(yè)務(wù)的就不行了
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。