文章目錄
一.認識MyBatis
MyBatis是一款優秀的持久層框架,它支持定製化SQL、存儲過程,以及高級映射。它可以使用簡單的XML或註解來配置和映射原生信息,將接口和JAVA的POJOS(Plain Old Java Objects,普通的Java對象)映射成數據庫中的記錄。
MyBatis 3 提供的註解可以取代XML。例如,使用註解@Select直接編寫SQL完成數據查詢;使用高級註解@SelectProvider還可以編寫動態SQL,以應對複雜的業務需求。
CRUD註解
增加、刪除、修改和查詢時主要的業務操作,必須掌握這些基礎註解的使用方法。MyBatis提供的操作數據的基礎註解有以下4個
- @Select:用於構建查詢語句
- @Insert:用於構建添加語句
- @Update:用於構建修改語句
- @Delete:用於構建刪除語句
具體使用如下
從代碼中可以看出:首先使用@Mapper註解來標註類,把UserMapper這個DAO交給Spring管理。這樣Spring會自動生成一個實現類,不用再寫UserMapper的映射文件了。最後使用基礎的CRUD註解來添加要實現的功能。
//添加了@Mapper註解之後這個接口在編譯時會生成相應的實現類
@Mapper
public interface UserMapper{
@Select("SELECT * FROM user WHERE id=#{id}")
User queryByld(@Param("id") int id);
@Select("SELECT * FROM user limit 1000")
List<User> queryAll();
@Insert({"INSERT INTO user(name,age) VALUES(#{name},#{age})"})
int add(User user);
@Delete("DELETE FROM user WHERE id=#{id}")
int delById(int id);
@Update("UPDATE user SET name=#{name},age=#{age} WHERE id=#{id}")
int updateById(User user);
@Select("SELECT * FROM user limit 1000")
Page<User> getUserList();
}
映射註解
MyBatis的映射註解用於建立實體和關係的映射。它有以下3個註解。
- @Results:用於填寫結果集的多個字段的映射關係
- @Result:用於填寫結果集的單個字段的映射關係
- @ResultMap:根據ID關聯XML裏面的 < resultMap>
可以在查詢SQL的基礎上,指定返回的結果集的映射關係。其中,property表示實體對象的屬性名,column表示對應的數據庫字段名。使用方法如下
@Result({
@Result(property="username",column="USERNAME");
@Result(property="password",column="PASSWORD");
})
@Select("select * from user limit 1000")
List<User> list();
高級註解
MaBatis 3.x版本主要提供了以下4個CRUD的高級註解
- @SelectProvider:用於構建動態查詢SQL
- @InsertProvider:用於構建動態添加SQL
- @UpdateProvider:用於構建動態更新SQL
- @DeleteProvider:用於構建動態刪除SQL
高級註解主要用於編寫動態SQL。這裏以@SelectProvider爲例,它主要包含兩個註解屬性,其中,type表示工具類,method表示工具類的某個方法(用於返回具體的SQL)。
以下代碼可以構建動態SQL,實現查詢功能:
@Mapper
public interface UserMapper{
@SelectProvider(type=UserSql.class,method="listAll")
List<User> listAllUser();
}
UserSql工具類的代碼如下
public class UserSql{
public String listAll(){
return "select * from user limit 1000";
}
}
二.用MyBatis實現數據的增加、刪除、修改、查詢和分頁
分爲兩部分:數據增刪改和分頁
全部(兩部分合起來)的項目結構如下
1.創建springboot項目並引入依賴
引入MyBatis,Mysql,pagehelper.Thymeleaf等依賴
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-autoconfigure</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
並且添加配置文件application.properties
數據庫連接並加上數據表初始化的配置
spring.datasource.url=jdbc:mysql://127.0.0.1/book?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.proterties.hibernate.dialect=org.hibernate.dialect.MYSQL5InnoDBDialect
spring.datasource.initialization-mode=always
spring.datasource.schema=classpath:db/schema.sql
2.實現數據表的自動初始化
在項目的resource目錄下新建db目錄,並添加schema.sql文件,然後再此文件中寫入創建user表的sql語句,以便進行初始化數據表
DROP TABLE IF EXISTS user;
--IF object_id('user','U') is not NULL drop table 'user';
CREATE TABLE user(
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(255) DEFAULT NULL,
age int(11) DEFAULT NULL,
PRIMARY KEY (id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
另外還有一個問題:sql語句是不區分大小寫的,但是,編譯的時候,操作系統會將所有字符轉換成大寫的,再進行編譯。如果大寫,在編譯的時候,可以節省轉化的時間。當SQL語句很多的時候,大寫就顯得很重要了。在大型的ERP系統開發的時候,往往會要求大寫。
3.實現實體對象建模
用MyBatis來創建實體
從代碼中可以看出,用MyBatis創建實體不需要添加註解@Entity,因爲@Entity是屬於JPA的專屬註解
User.java
package com.example.demo.entity;
import lombok.Data;
@Data
public class User {
private int id;
private String name;
private int age;
}
4.實現實體和數據表的映射關係
實現實體和數據表的映射關係可以在Mapper類上添加註解@Mapper
UserMapper.java
package com.example.demo.mapper;
import com.example.demo.entity.User;
import com.github.pagehelper.Page;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface UserMapper {
@Select("SELECT * FROM user WHERE id=#{id}")
User queryById(@Param("id") int id);
@Select("SELECT * FROM user ")
List<User> queryAll();
@Insert({"INSERT INTO user(name,age) VALUES(#{name},#{age})"})
int add(User user);
@Delete("DELETE FROM user WHERE id=#{id}")
int delById(int id);
@Update("UPDATE user SET name=#{name},age=#{age} WHERE id=#{id}")
int updateById(User user);
}
5.實現增加、刪除、修改和查詢功能
創建控制器實現操作數據的API
UserController.java
package com.example.demo.controller;
import com.example.demo.entity.User;
import com.example.demo.controller.UserController;
import com.example.demo.mapper.UserMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
UserMapper userMapper;
@RequestMapping("/querybyid")
User queryById(int id){
return userMapper.queryById(id);
}
@RequestMapping("/")
List<User> queryAll(){
return userMapper.queryAll();
}
@RequestMapping("/add")
String add(User user){
return userMapper.add(user)==1?"sources":"failed";
}
@RequestMapping("/updatebyid")
String updateById(User user){
return userMapper.updateById(user)==1?"success":"failed";
}
@RequestMapping("/delbyid")
String delById(int id){
return userMapper.delById(id)==1?"success":"failed";
}
}
完成這一步,便可以啓動項目,並且進行下面的操作,得到實驗結果。
實驗結果
啓動項目,訪問如下鏈接http://localhost:8080/user/add?name=hello&age=10,會自動添加一個名爲name=hello,age=10的數據,以此類推
訪問http://localhost:8080/user/,可以查詢出所有的數據
訪問http://localhost:8080/user/querybyid?id=3,可以查找到id=3的數據,
同樣的,可以在數據庫中查看
6.配置分頁功能
分頁功能通過PageHelper來實現,上面已經添加過依賴(共有三個關於pagehelper的依賴),還需要Thymeleaf依賴
創建分頁配置類
pageHelperConfig.java
註解@Configuration表示這個類是用來做配置的
package com.example.demo.config;
import com.github.pagehelper.PageHelper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
@Configuration
public class pageHelperConfig {
@Bean
public PageHelper pageHelper(){
PageHelper pageHelper = new PageHelper();
Properties p = new Properties();
//1.offsetAsPageNum:設置爲true時,會將RowBounds第一個參數offset當成pageNum頁碼使用.
p.setProperty("offsetAsPageNum", "true");
//2.rowBoundsWithCount:設置爲true時,使用RowBounds分頁會進行count查詢.
p.setProperty("rowBoundsWithCount", "true");
//3.reasonable:啓用合理化時,如果pageNum<1會查詢第一頁,如果pageNum>pages會查詢最後一頁。
p.setProperty("reasonable", "true");
pageHelper.setProperties(p);
return pageHelper;
}
}
7實現分頁控制器
用以顯示分頁頁面
UserListController.java
package com.example.demo.controller;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@Controller
public class UserListController {
@Autowired
UserMapper userMapper;
@RequestMapping("/listall")
public String listCategory(Model m,@RequestParam(value="start",defaultValue = "0")int start,
@RequestParam(value = "size",defaultValue = "20")int size) throws Exception{
PageHelper.startPage(start,size);
List<User> cs=userMapper.queryAll();
PageInfo<User> page=new PageInfo<>(cs);
m.addAttribute("page",page);
return "list";
}
}
8創建分頁視圖
這是前端的內容,創建list.html,路徑是resources/templates/list.html
list.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>hello的web</title>
</head>
<body>
<div class="with:80%">
<div th:each="u:${page.list}">
<span scope="row" th:text="${u.id}">id</span>
<span th:text="${u.name}">name</span>
</div>
</div>
<div>
<a th:href="@{listall?start=1}">[首頁]</a>
<a th:if="${not page.IsFirstPage}" th:href="@{/listall(start=${page.pageNum-1})}">[上頁]</a>
<a th:if="${not page.IsLastPage}" th:href="@{/listall(start=${page.pageNum+1})}">[下頁]</a>
<a th:href="@{/listall(start=${page.pages})}">[末頁]</a>
<div>當前頁/總頁數:
<a th:text="${page.pageNum}" th:href="@{/listall(start=${page.pageNum})}"></a>
/<a th:text="${page.pages}" th:href="@{/listall(start=${page.pages})}"></a>
</div>
</div>
</body>
</html>
9啓動類添加@ComponentScan
package com.example.demo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
//@MapperScan("com.example.demo.mapper")
//可以使用:basePackageClasses={},basePackages={}
@ComponentScan(basePackages={"com.example.demo.mapper","com.example.demo.controller"})
@SpringBootApplication
public class MybatisCurdPageApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisCurdPageApplication.class, args);
}
}
啓動項目,首先通過訪問http://localhost:8080/listall得到下面的界面
然後通過訪問http://localhost:8080/user/add?name=hello&age=10,並且多次刷新(最好20次以上),這是爲user表添加用戶信息,用於後面的分頁顯示
再次輸入網址http://localhost:8080/listall
可以看到分頁