SpringBoot 2.1.6 集成 Mybatis
使用SpringBoot集成 Mybatis有兩種方式,本文使用IDEA搭建:
- 1.Spring Initializr
- 2.使用IDEA插件
環境信息:
OS:Win10
Jdk:JavaSE 8
Ide:Idea Ultimate
MySQL:8.0.16
MyBatis:3.5.2
Spring Boot:2.1.6.RELEASE
2.創建Web項目
Idea集成了Spring Initializr,新建項目:
-
1.選擇Spring Initializr,新建項目並填寫基本信息
-
3.選擇需要的工具
選擇Web
、MySQL Driver
和MyBatis Framework
等必要依賴:
- 4.確認完成,進行下一步。
4.集成Mybatis
4.1 創建Domain
Student
:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Student {
private Integer id;
private String name;
private Integer age;
private String sex;
private String hobbies;
private String address;
}
Score
:
@Data
@Builder
public class Score {
private Integer id;
//學生編號
private Integer studentId;
private String studentName;
//科目
private String subject;
//科目成績
private Integer subjectScore;
}
StudentScore
:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class StudentScore {
private String name;
private Integer age;
private String sex;
private Score score;
}
StudentScores
:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class StudentScores {
private String name;
private Integer age;
private String sex;
private List<Score> scoreList;
}
4.2 配置文件
application.properties
:
spring.application.name=student-service
spring.boot.admin.client.enabled=true
spring.profiles.active=dev
配置MySQL連接,MyBatis掃描包路徑等配置信息:
application-dev.yml
:
server:
connection-timeout: 30000ms
port: 8081
servlet.context-path: /
logging:
path: ./
file: st.log
#max-size: 10M
#max-history: 1
level:
root: INFO
org:
springframework:
web: INFO
com:
wxx:
sbmm:
mapper: DEBUG
spring:
data:
datasource:
# 遇到時區問題用這個
# jdbc:mysql://localhost:3306?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
url: jdbc:mysql://localhost:3306/studentService?useSSL=false&useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 12345678
# schema.sql中一般存放的是DDL腳本,即通常爲創建或更新庫表的腳本
# data.sql中一般是DML腳本,即通常爲數據插入腳本
schema: classpath:schema.sql
data: classpath:data.sql
platform: mysql
initialization-mode: always
continue-on-error: false
#data-password:
#data-username:
#schema-password:
#schema-username:
sql-script-encoding: utf-8
separator: ;
# type: com.alibaba.druid.pool.DruidDataSource
更多
MyBatis配置
可參考[Configuration部分]:http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/index.html
4.3 配置數據庫初始化腳本
schema.sql
:初始化建表SQL
CREATE DATABASE IF NOT EXISTS `studentService`;
CREATE TABLE IF NOT EXISTS `t_student` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT 'ID',
`name` VARCHAR(255) DEFAULT "" COMMENT '姓名',
`age` INT DEFAULT 10 COMMENT '年齡',
`sex` VARCHAR(255)DEFAULT "Male" COMMENT '性別',
`hobbies` VARCHAR(255) DEFAULT "" COMMENT '愛好',
`address` VARCHAR(255) DEFAULT "" COMMENT '住址',
PRIMARY KEY(`id`),
UNIQUE INDEX `idx_student_name_address` (`name`,`address`) USING BTREE
)ENGINE = INNODB DEFAULT CHARSET=utf8 AUTO_INCREMENT = 1 COMMENT '學生表';
CREATE TABLE IF NOT EXISTS `t_score` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT 'ID',
`student_id` INT DEFAULT 0 COMMENT '學生ID',
`student_name` VARCHAR(255) DEFAULT "" COMMENT '學生姓名',
`subject` VARCHAR(255) DEFAULT "" COMMENT '學科',
`subject_score` INT COMMENT '學科成績',
PRIMARY KEY(`id`),
UNIQUE INDEX `idx_score_studentname_subject` (`student_name`,`subject`) USING BTREE ,
FOREIGN KEY (student_name) REFERENCES t_student (name)
)ENGINE = INNODB DEFAULT CHARSET=utf8 AUTO_INCREMENT = 1 COMMENT '學生成績表';
data.sql
:初始化數據SQL
INSERT INTO t_student (name,age, sex, hobbies, address)
SELECT "Even",9,"Male","ShuXue,English","XiAn" FROM DUAL WHERE NOT EXISTS(SELECT 1 FROM t_student WHERE name = "Even");
INSERT INTO t_student (name,age, sex, hobbies, address)
SELECT "Weison",11,"Male","XuWen,WuLi","HeNan" FROM DUAL WHERE NOT EXISTS(SELECT 1 FROM t_student WHERE name = "Weison");
INSERT INTO t_student (name,age, sex, hobbies, address)
SELECT "Angule",13,"Female","XuWen,English","Chengdu" FROM DUAL WHERE NOT EXISTS(SELECT 1 FROM t_student WHERE name = "Angule");
INSERT INTO t_score (student_id,student_name, subject, subject_score)
SELECT 1,"Even","YuWen",90 FROM DUAL WHERE NOT EXISTS(SELECT 1 FROM t_score WHERE student_name = "Even" and subject ="YuWen");
INSERT INTO t_score (student_id,student_name, subject, subject_score)
SELECT 1,"Even","ShuXue",89 FROM DUAL WHERE NOT EXISTS(SELECT 1 FROM t_score WHERE student_name = "Even" and subject ="ShuXue");
INSERT INTO t_score (student_id,student_name, subject, subject_score)
SELECT 1,"Even","English",67 FROM DUAL WHERE NOT EXISTS(SELECT 1 FROM t_score WHERE student_name = "Even" and subject ="English");
INSERT INTO t_score (student_id,student_name, subject, subject_score)
SELECT 2,"Weison","YuWen",69 FROM DUAL WHERE NOT EXISTS(SELECT 1 FROM t_score WHERE student_name = "Weison" and subject ="YuWen");
INSERT INTO t_score (student_id,student_name, subject, subject_score)
SELECT 2,"Weison","ShuXue",94 FROM DUAL WHERE NOT EXISTS(SELECT 1 FROM t_score WHERE student_name = "Weison" and subject ="ShuXue");
INSERT INTO t_score (student_id,student_name, subject, subject_score)
SELECT 2,"Weison","English",82 FROM DUAL WHERE NOT EXISTS(SELECT 1 FROM t_score WHERE student_name = "Weison" and subject ="English");
INSERT INTO t_score (student_id,student_name, subject, subject_score)
SELECT 3,"Angule","YuWen",58 FROM DUAL WHERE NOT EXISTS(SELECT 1 FROM t_score WHERE student_name = "Angule" and subject ="YuWen");
INSERT INTO t_score (student_id,student_name, subject, subject_score)
SELECT 3,"Angule","ShuXue",73 FROM DUAL WHERE NOT EXISTS(SELECT 1 FROM t_score WHERE student_name = "Angule" and subject ="ShuXue");
INSERT INTO t_score (student_id,student_name, subject, subject_score)
SELECT 3,"Angule","English",91 FROM DUAL WHERE NOT EXISTS(SELECT 1 FROM t_score WHERE student_name = "Angule" and subject ="English");
commit;
4.4 配置SQL 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.wxx.sbmm.mapper.StudentMapper">
<!--
執行增加操作的SQL語句
1.id和parameterType 分別與StudentMapper接口中的addStudent方法的名字和 參數類型一致
2.以#{studentName}的形式引用Student參數 的studentName屬性,MyBatis將使用反射讀取Student參數的此屬性
3.#{studentName}中studentName大小寫敏感。引用其他的屬性與此一致
4.seGeneratedKeys設置爲"true"表明要MyBatis獲取由數據庫自動生成的主鍵
5.keyProperty="id"指定把獲取到的主鍵值注入到Student的id屬性
-->
<!-- 當表中字段名跟實體類字段名不一致 或 爲了返回list類型 可以定義returnMap -->
<resultMap id="studentMap" type="Student">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="sex" property="sex"/>
<result column="hobbies" property="hobbies"/>
<result column="address" property="address"/>
</resultMap>
<resultMap id="scoreResultMap" type="Score">
<id column="id" property="id"/>
<result column="student_id" property="studentId"/>
<result column="student_name" property="studentName"/>
<result column="subject" property="subject"/>
<result column="subject_score" property="subjectScore"/>
</resultMap>
<!--增刪改查 開始-->
<!--新增 1-->
<insert id="saveStudent" parameterType="Student" useGeneratedKeys="true" keyProperty="id">
insert into t_student(name,age,sex,hobbies,address)
values(#{name},#{age},#{sex},#{hobbies},#{address})
</insert>
<!--刪除 1-->
<delete id="deleteStudentByName" parameterType="String">
delete from t_student where name=#{name}
</delete>
<!--刪除 2-->
<delete id="deleteByStudent" parameterType="com.wxx.sbmm.domain.Student">
delete from t_student where name=#{name}
</delete>
<!--修改 1-->
<update id="updateStudent" parameterType="com.wxx.sbmm.domain.Student">
update t_student set
age = #{age},
sex = #{sex},
hobbies = #{hobbies},
address = #{address},
where name=#{name}
</update>
<!--查詢 1 -->
<select id="findStudentByName" parameterType="String" resultMap="studentMap">
SELECT * FROM t_student where name = #{name};
</select>
<!--查詢 2 返回list的select語句,注意resultMap的值是指向前面定義好的 -->
<select id="findStudents" resultMap="studentMap">
select * from t_student
</select>
<!--查詢 3 利用 hashMap 傳遞多個參數 -->
<select id="findStudentByMap" parameterType="map" resultType="com.wxx.sbmm.domain.Student">
select * from t_student where
<where>
1=1
<if test="name != null and name != ''">
and name = #{name}
</if>
<if test="age != null and age != ''">
and age = #{age}
</if>
<if test="sex != null and sex != ''">
and sex=#{sex}
</if>
<if test="hobbies != null and hobbies != ''">
and hobbies=#{hobbies}
</if>
<if test="address != null and address != ''">
and address=#{address}
</if>
</where>
</select>
<!--查詢 4 利用 hashMap 傳遞多個參數 -->
<select id="findStudentByStudent" parameterType="Student" resultType="com.wxx.sbmm.domain.Student">
select * from t_student where
<where>
1=1
<if test="name != null and name != ''">
and name = #{name}
</if>
<if test="age != null and age != ''">
and age = #{age}
</if>
<if test="sex != null and sex != ''">
and sex=#{sex}
</if>
<if test="hobbies != null and hobbies != ''">
and hobbies=#{hobbies}
</if>
<if test="address != null and address != ''">
and address=#{address}
</if>
</where>
</select>
<!--查詢 5 Mybatis 自帶的多個參數傳遞方法 這個時候沒有 parameterType, 但用到了類似 #{param1} 類似的參數 -->
<select id="findStudentByAgeAndSex" resultType="com.wxx.sbmm.domain.Student">
select * from t_student where age = #{param1} and sex=#{param2}
</select>
<!--增刪改查 結束-->
<!--聯合查詢 開始-->
<!--聯合查詢:
引入 association 看定義如下 這樣配置之後,就可以了,將select語句與resultMap對應的映射結合起來看。
用 association 來 得到關聯的用戶,這是多對一的情況。
-->
<resultMap id="studentScoresResultMap" type="StudentScores">
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="sex" property="sex"/>
<association property="scoreList" javaType="List">
<id column="id" property="id"/>
<result column="student_id" property="studentId"/>
<result column="student_name" property="studentName"/>
<result column="subject_core" property="subjectScore"/>
</association>
</resultMap>
<!--
複用我們前面已經定義好的resultMap 將association 中對應的映射獨立抽取出來,可以達到複用的目的
-->
<resultMap id="studentScoresAssociationResultMap" type="com.wxx.sbmm.domain.StudentScores">
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="sex" property="sex"/>
<association property="scores" javaType="List" resultMap="scoreResultMap"/>
</resultMap>
<!-- 聯合查詢 1 -->
<select id="findStudentScores" resultMap="studentScoresResultMap">
select a.name,a.age,a.sex,b.id,b.student_id,b.student_name,b.subject,b.subject_score
from t_student a,t_score b
where
a.name=b.name
</select>
<!-- 聯合查詢 2 -->
<select id="findStudentScore" resultMap="studentScoresResultMap">
select a.name,a.age,a.sex,b.id,b.student_id,b.student_name,b.subject,b.subject_score
from t_student a,t_score b
where
a.name=b.name
and b.subject = 'English'
</select>
<!-- 聯合查詢 結束 -->
</mapper>
5.代碼
5.1 創建StudentMapper
使用@Mapper
註解標明 Mapper
接口,MyBatis會幫我們去實現這個接口,該接口中方法與xml
中sql標籤ID
相對應:
package com.wxx.sbmm.mapper;
import com.wxx.sbmm.domain.Student;
import com.wxx.sbmm.domain.StudentScore;
import com.wxx.sbmm.domain.StudentScores;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
@Mapper
public interface StudentMapper {
// 增刪改查
Student saveStudent(Student student);
Integer deleteStudentByName(@Param("name") String name);
Integer deleteByStudent(Student student);
Student updateStudent(Student student);
// 5種查詢
Student findStudentByName(@Param("name") String name);
List<Student> findStudents();
List<Student> findStudentByMap(Map<String, String> map);
List<Student> findStudentByStudent(Student student);
List<Student> findStudentByAgeAndSex(Integer age, String sex);
// 關聯查詢
List<StudentScores> findStudentScores();
List<StudentScore> findStudentScore();
}
關於
Mapper
更多信息可參考:http://www.mybatis.org/spring/mappers.html#
5.2 創建Service
package com.wxx.sbmm.service;
import com.wxx.sbmm.domain.Student;
import com.wxx.sbmm.domain.StudentScore;
import com.wxx.sbmm.domain.StudentScores;
import com.wxx.sbmm.mapper.StudentMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class StudentService {
@Autowired
private StudentMapper studentMapper;
public Student addStudent(Student student) {
return studentMapper.saveStudent(student);
}
public Integer deleteStudentByName(String name) {
return studentMapper.deleteStudentByName(name);
}
public Integer deleteByStudent(Student student) {
return studentMapper.deleteByStudent(student);
}
public Student updateStudent(Student student) {
return studentMapper.updateStudent(student);
}
public Student findStudentByName(String name) {
return studentMapper.findStudentByName(name);
}
public List<Student> findStudents() {
return studentMapper.findStudents();
}
public List<Student> findStudentByMap(Map<String, String> map) {
return studentMapper.findStudentByMap(map);
}
public List<Student> findStudentByStudent(Student student) {
return studentMapper.findStudentByStudent(student);
}
public List<Student> findStudentByAgeAndSex(Integer age, String sex) {
return studentMapper.findStudentByAgeAndSex(age, sex);
}
public List<StudentScores> findStudentScores() {
return studentMapper.findStudentScores();
}
public List<StudentScore> findStudentScore() {
return studentMapper.findStudentScore();
}
}
5.3 創建Controller
package com.wxx.sbmm.controller;
import com.wxx.sbmm.domain.Student;
import com.wxx.sbmm.domain.StudentScore;
import com.wxx.sbmm.domain.StudentScores;
import com.wxx.sbmm.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
public class StudentController {
@Autowired
private StudentService studentService;
@PostMapping("/students")
public Student saveStudent(@RequestBody Student student) {
Student addStudent = studentService.addStudent(student);
return addStudent;
}
@DeleteMapping("/students/{name}")
public Integer deleteStudentByName(@PathVariable String name) {
Integer deleteNum = studentService.deleteStudentByName(name);
return deleteNum;
}
@DeleteMapping("/students")
public Integer deleteStudentByStudent(@RequestBody Student student) {
Integer deleteNum = studentService.deleteByStudent(student);
return deleteNum;
}
@PutMapping("/students")
public Student updateStudent(@RequestBody Student student) {
Student updateStudent = studentService.updateStudent(student);
return updateStudent;
}
@GetMapping("/students/{name}")
public Student findStudentByName(@PathVariable String name) {
Student student = studentService.findStudentByName(name);
return student;
}
@GetMapping("/students")
public List<Student> getStudentListByAgeAndSexAndHobbies() {
List<Student> studentList = studentService.findStudents();
return studentList;
}
@GetMapping("/students/map")
public List<Student> findStudentByMap() {
Map<String, String> map = new HashMap<>();
map.put("name", "Evwn");
List<Student> studentList = studentService.findStudentByMap(map);
return studentList;
}
@GetMapping("/students/st")
public List<Student> findStudentByStudent() {
List<Student> studentList = studentService.findStudentByStudent(Student.builder().build());
return studentList;
}
@GetMapping("/students/{age}/{sex}")
public List<Student> findStudentByAgeAndSex(@PathVariable Integer age, @PathVariable String sex) {
List<Student> studentList = studentService.findStudentByAgeAndSex(age, sex);
return studentList;
}
@GetMapping("/students/scores")
public List<StudentScores> findStudentScores() {
List<StudentScores> studentList = studentService.findStudentScores();
return studentList;
}
@GetMapping("/students/score")
public List<StudentScore> findStudentScore() {
List<StudentScore> studentScores = studentService.findStudentScore();
return studentScores;
}
}
5.4 最終項目
應該是這個樣子:
6. 測試
兩個比較複雜的接口返回:
/students/scores
:
/students/score
:
代碼 --> 鏈接