マイバティスとは
MyBatis は、カスタム SQL、ストアド プロシージャ、および高度なマッピングをサポートする優れた永続層フレームワークです。プリミティブ型、インターフェイス、および Java POJO (Plain Old Java Object) は、単純な XML または注釈を介してデータベース内のレコードに構成およびマッピングできます。
mybatis などのフレームワークが登場する前は、ほとんどの人が jdbc 経由でデータベースに接続し、SQL ステートメントを Java コードにつなぎ合わせて実行していました。
1. JDBC ドライバーをロードします。
Class.forName("com.mysql.jdbc.Driver") ;
2. データベース接続を作成します。
Connection con = DriverManager.getConnection(url , username , password ) ;
3. 準備されたステートメントを実行します。
Statement stmt = con.createStatement() ;
//PreparedStatement pstmt = con.prepareStatement(sql) ;
ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ;
4. データ分析のために結果セットをスキャンします。
while(rs.next()){
String name = rs.getString("name") ;
String pass = rs.getString(1) ;
}
mybatis フレームワークは、接続プールを確立するようにデータ ソースを構成できること、Java ステートメントと SQL ステートメントを個別に作成できること、SQL ステートメントを XML 構成ファイルに記述できること、インターフェイスが Java で定義されていることなど、上記のプロセスをカプセル化して最適化します。セットとエンティティ オブジェクトの変換。これにより、開発者のコーディング効率が大幅に向上し、コードの可読性が向上し、データベースのパフォーマンスが節約されます。
このチュートリアルでは次のバージョンを使用します
スプリングブーツ 2.7.0
マイボット 2.1.3
ドルイド 1.2.1
mysql5.6
統合する
プロジェクトの作成
新しい Spring Boot プロジェクトを作成します。空のプロジェクトは、前のチュートリアルで作成できます。
pomファイルを編集する
idea で新しい Maven プロジェクトを作成した後、まず pom ファイルに次の依存関係を導入する必要があります。
主に含まれるもの: mybatis 依存関係、druid 依存関係、mysql 依存関係
<properties>
<java.version>1.8</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/>
</parent>
<dependencies>
<!-- web 组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 测试 组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- jdbc 组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- mybatis 组件 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<!-- druid 组件 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.1</version>
</dependency>
<!-- mysql 组件 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.study.MainStarter</mainClass>
<jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
jar パッケージが見つからないように、依存関係をリロードすることを忘れないでください。Maven を順番にクリックし、プロジェクト名=》右クリック=》Reimport
ディレクトリ構造
以下に示すようにパッケージのディレクトリ構造を確立します。詳細は次のとおりです。
テーブル作成ステートメント
mysql5.6 データベースで設計したテーブル作成ステートメントを実行します。
CREATE DATABASE /*!32312 IF NOT EXISTS*/studydb /*!40100 DEFAULT CHARACTER SET utf8 */;
USE studydb;
DROP TABLE IF EXISTS ser_company;
CREATE TABLE ser_company (
company_id int(11) NOT NULL AUTO_INCREMENT COMMENT '公司id',
company_name varchar(64) DEFAULT NULL COMMENT '公司名称',
company_code varchar(4) DEFAULT NULL COMMENT '公司编号',
company_msg text COMMENT '公司简介',
company_crdt timestamp NULL DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (company_id)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;
データソースとmybatisの設定
次の設定を application.properties 設定ファイルに追加します。
#druid数据库连接池
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#数据库地址
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/studydb?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
#数据库账号
spring.datasource.username=root
#数据库密码
spring.datasource.password=root
#清除缓存
spring.thymeleaf.cache=false
#配置mapper映射路径
mybatis.mapper-locations=classpath:mapper/*.xml
#配置实体别名包路径
mybatis.type-aliases-package=com.study.model
#日志级别
logging.level.com.study.* = debug
上記の構成ファイル内のデータベース アドレス、アカウント、パスワード、マッパー マッピング パス、エンティティ エイリアス パス、およびログを独自のデータベースに合わせて変更する必要があることに注意してください。マッパー マッピング パスを構成すると、Spring Boot コンテナー中にこのパス内のファイルが自動的にスキャンされます。エンティティのエイリアス パッケージ パスを設定すると、xml にクラス名を記述するときにエンティティ クラスのパッケージ名を記述する必要がなくなります。ここでは、Alibaba druid データベース接続コンポーネントが使用されます。
エンティティクラス
ser_company テーブル内のエンティティに対応するエンティティ クラスを com.study.model パッケージの下に作成します。例として会社オブジェクトを考えてみましょう。このオブジェクトには、会社名、会社コード、会社情報、保管時間などのフィールドが含まれています。コードは以下のように表示されます。
package com.study.model;
import org.apache.ibatis.type.Alias;
@Alias("SerCompanyVO")
public class SerCompanyVO {
private int companyId;
private String companyName;
private String companyCode;
private String companyMsg;
private String companyCrdt;
public int getCompanyId() {
return companyId;
}
public void setCompanyId(int companyId) {
this.companyId = companyId;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getCompanyCode() {
return companyCode;
}
public void setCompanyCode(String companyCode) {
this.companyCode = companyCode;
}
public String getCompanyMsg() {
return companyMsg;
}
public void setCompanyMsg(String companyMsg) {
this.companyMsg = companyMsg;
}
public String getCompanyCrdt() {
return companyCrdt;
}
public void setCompanyCrdt(String companyCrdt) {
this.companyCrdt = companyCrdt;
}
}
だお
com.study.dao パッケージの下の SerCompanyMapper クラスを編集して、関連するインターフェイスを XML にマップします。ここでは、練習用に selectSerCompanyList などのインターフェイスを選択できます。このチュートリアルにはいくつかのインターフェイスが含まれています。クエリの追加、変更、削除に加えて。このチュートリアルには、バッチ挿入、動的ステートメントの挿入と主キーの戻り、動的ステートメントの変更などのサンプル インターフェイスが含まれています。コードは以下のように表示されます。
package com.study.dao;
import com.study.model.SerCompanyVO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface SerCompanyMapper {
/**
* 查询全部数据
* @return
*/
List<SerCompanyVO> selectSerCompanyList();
/**
* 根据id查询信息
* @return
*/
SerCompanyVO selectSerCompanyById(Integer companyId);
/**
* 固定字段插入
* @param serCompanyVO
* @return
*/
int insertSerCompanyVO(SerCompanyVO serCompanyVO);
/**
* 动态语句插入
* @param serCompanyVO
* @return
*/
int insertSerCompanyDynamic(SerCompanyVO serCompanyVO);
/**
* 批量插入
* @param list
* @return
*/
int insertCompanyBatch(List<SerCompanyVO> list);
/**
* 修改信息
* @param serCompanyVO
* @return
*/
int updateCompany(SerCompanyVO serCompanyVO);
/**
* 动态语句修改
* @param serCompanyVO
* @return
*/
int updateCompanyDynamic(SerCompanyVO serCompanyVO);
/**
* 根据id删除信息
* @param companyId
* @return
*/
int deleteCompanyById(Integer companyId);
}
XML
マッパー ディレクトリに新しい SerCompanyMapper.xml を作成し、次のコードを記述します。
namespace は、dao 層インターフェイス クラスのパスです。
resultMap は、クエリ結果セットを SerCompanyVO オブジェクトにカプセル化します。
foreach タグはリスト パラメーターを横断できます。
useGeneratedKeys と keyProperty は、挿入後に主キーを返すことができます。
<?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.study.dao.SerCompanyMapper">
<resultMap id="resultMap" type="SerCompanyVO">
<id column="company_id" property="companyId" jdbcType="INTEGER" />
<result column="company_name" property="companyName" jdbcType="VARCHAR" />
<result column="company_code" property="companyCode" jdbcType="VARCHAR" />
<result column="company_msg" property="companyMsg" jdbcType="VARCHAR" />
<result column="company_crdt" property="companyCrdt" jdbcType="VARCHAR" />
</resultMap>
<!-- 新增数据 固定语句 -->
<insert id="insertSerCompanyVO" useGeneratedKeys="true" keyProperty="companyId">
insert into ser_company(
company_name,
company_code,
company_msg,
company_crdt
) values (
#{companyName, jdbcType=VARCHAR},
#{companyCode, jdbcType=VARCHAR},
#{companyMsg, jdbcType=VARCHAR},
#{companyCrdt, jdbcType=TIMESTAMP}
)
</insert>
<!-- 新增数据 动态语句 -->
<insert id="insertSerCompanyDynamic" useGeneratedKeys="true" keyProperty="companyId">
insert into ser_company(
<if test="null != companyName and ''!= companyName">
company_name,
</if>
<if test="null != companyCode and ''!= companyCode">
company_code,
</if>
<if test="null != companyMsg and ''!= companyMsg">
company_msg,
</if>
<if test="null != companyCrdt and ''!= companyCrdt">
company_crdt
</if>
) values (
<if test="null != companyName and ''!= companyName">
#{companyName, jdbcType=VARCHAR},
</if>
<if test="null != companyCode and ''!= companyCode">
#{companyCode, jdbcType=VARCHAR},
</if>
<if test="null != companyMsg and ''!= companyMsg">
#{companyMsg, jdbcType=VARCHAR},
</if>
<if test="null != companyCrdt and ''!= companyCrdt">
#{companyCrdt, jdbcType=TIMESTAMP}
</if>
)
</insert>
<!-- 新增数据 批量插入 -->
<insert id="insertCompanyBatch">
insert into ser_company(
company_name,
company_code,
company_msg,
company_crdt
) values
<foreach collection="list" item="item" separator=",">
(
#{item.companyName, jdbcType=VARCHAR},
#{item.companyCode, jdbcType=VARCHAR},
#{item.companyMsg, jdbcType=VARCHAR},
#{item.companyCrdt, jdbcType=TIMESTAMP}
)
</foreach>
</insert>
<update id="updateCompanyDynamic" >
update ser_company set
<if test="null != companyName and ''!= companyName">
company_name = #{companyName, jdbcType=VARCHAR},
</if>
<if test="null != companyCode and ''!= companyCode">
company_code = #{companyCode, jdbcType=VARCHAR},
</if>
<if test="null != companyMsg and ''!= companyMsg">
company_msg = #{companyMsg, jdbcType=VARCHAR},
</if>
<if test="null != companyCrdt and ''!= companyCrdt">
company_crdt = #{companyCrdt, jdbcType=TIMESTAMP}
</if>
where company_id = #{companyId, jdbcType=INTEGER}
</update>
<update id="updateCompany">
update ser_company set
company_name = #{companyName, jdbcType=VARCHAR},
company_code = #{companyCode, jdbcType=VARCHAR},
company_msg = #{companyMsg, jdbcType=VARCHAR},
company_crdt = #{companyCrdt, jdbcType=TIMESTAMP}
where company_id = #{companyId, jdbcType=INTEGER}
</update>
<!-- 删除数据 -->
<delete id="deleteCompanyById">
delete from ser_company where company_id = #{companyId, jdbcType=INTEGER}
</delete>
<!-- 查询数据 -->
<select id="selectSerCompanyList" resultMap="resultMap">
select company_name, company_code, company_msg, company_crdt from ser_company
</select>
<!-- 详情查询 -->
<select id="selectSerCompanyById" resultMap="resultMap" parameterType="java.lang.Integer">
select company_id,company_name, company_code, company_msg, company_crdt from ser_company where company_id=#{companyId, jdbcType=INTEGER}
</select>
</mapper>
サービスクラスと実装クラス
com.study.service パッケージの下に新しい SerCompanyService インターフェイスを作成します。コードは次のとおりです。
package com.study.service;
import com.study.model.SerCompanyVO;
import java.util.List;
public interface SerCompanyService {
List<SerCompanyVO> querySerCompanyList();
int addCompany(SerCompanyVO serCompanyVO);
int addCompanyDynamic(SerCompanyVO serCompanyVO);
int addCompanyBatch(List<SerCompanyVO> list);
SerCompanyVO querySerCompanyById(Integer companyId);
int updateCompany(SerCompanyVO serCompanyVO);
int updateCompanyDynamic(SerCompanyVO serCompanyVO);
int deleteCompanyById(Integer companyId);
}
新しい SerCompanyServiceImpl 実装クラスを com.study.service.impl パッケージの下に作成します。コードは次のとおりです。
ここでは、先ほど作成した SerCompanyMapper を使用します。このクラスを使用して、mybatis XML 内のステートメントを呼び出します。
package com.study.service.impl;
import com.study.dao.SerCompanyMapper;
import com.study.model.SerCompanyVO;
import com.study.service.SerCompanyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SerCompanyServiceImpl implements SerCompanyService {
private Logger log = LoggerFactory.getLogger(this.getClass().getName());
@Autowired
private SerCompanyMapper serCompanyMapper;
@Override
public List<SerCompanyVO> querySerCompanyList() {
return serCompanyMapper.selectSerCompanyList();
}
@Override
public int addCompany(SerCompanyVO serCompanyVO) {
return serCompanyMapper.insertSerCompanyVO(serCompanyVO);
}
@Override
public int addCompanyDynamic(SerCompanyVO serCompanyVO) {
return serCompanyMapper.insertSerCompanyDynamic(serCompanyVO);
}
@Override
public int addCompanyBatch(List<SerCompanyVO> list) {
return serCompanyMapper.insertCompanyBatch(list);
}
@Override
public SerCompanyVO querySerCompanyById(Integer companyId) {
return serCompanyMapper.selectSerCompanyById(companyId);
}
@Override
public int updateCompany(SerCompanyVO serCompanyVO) {
return serCompanyMapper.updateCompany(serCompanyVO);
}
@Override
public int updateCompanyDynamic(SerCompanyVO serCompanyVO) {
return serCompanyMapper.updateCompanyDynamic(serCompanyVO);
}
@Override
public int deleteCompanyById(Integer companyId) {
return serCompanyMapper.deleteCompanyById(companyId);
}
}
コントローラ
com.study.controller に次のクラスを作成します。
package com.study.controller;
import com.study.model.SerCompanyVO;
import com.study.service.SerCompanyService;
import com.study.util.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Controller
public class SerCompanyController {
private Logger log = LoggerFactory.getLogger(this.getClass().getName());
@Autowired
private SerCompanyService serCompanyService;
/**
* 查询公司信息列表
* http://localhost:8080/querySerCompanyList
* @return
*/
@RequestMapping(method= RequestMethod.GET, value = "querySerCompanyList")
@ResponseBody
public List<SerCompanyVO> querySerCompanyList(){
if(log.isDebugEnabled()){
log.debug("do querySerCompanyList begin.");
}
return serCompanyService.querySerCompanyList();
}
/**
* 查询公司信息根据id
* http://localhost:8080/querySerCompanyById?companyId=1
* @return
*/
@RequestMapping(method= RequestMethod.GET, value = "querySerCompanyById")
@ResponseBody
public SerCompanyVO querySerCompanyById(Integer companyId){
return serCompanyService.querySerCompanyById(companyId);
}
/**
* 新增公司固定字段
* @param serCompanyVO
* http://localhost:8080/addCompany?companyName=百度&companyCode=321&companyMsg=百度是一家上市公司
* @return
*/
@RequestMapping(method= RequestMethod.GET, value = "addCompany")
@ResponseBody
public Map<String, Object> addCompany(SerCompanyVO serCompanyVO){
if(log.isDebugEnabled()){
log.debug("companyName:{}", serCompanyVO.getCompanyName());
}
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
serCompanyVO.setCompanyCrdt(timestamp.toString());
int num = serCompanyService.addCompany(serCompanyVO);
Map<String ,Object> map = ResultUtil.getRsMap(num);
map.put("serCompanyVO", serCompanyVO);
return map;
}
/**
* 新增公司动态字段
* http://localhost:8080/addCompanyDynamic?companyName=字节跳动&companyCode=&companyMsg=
* @param serCompanyVO
* @return
*/
@RequestMapping(method= RequestMethod.GET, value = "addCompanyDynamic")
@ResponseBody
public Map<String, Object> addCompanyDynamic(SerCompanyVO serCompanyVO){
if (log.isDebugEnabled()){
log.debug("companyName:{}", serCompanyVO.getCompanyName());
}
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
serCompanyVO.setCompanyCrdt(timestamp.toString());
int num = serCompanyService.addCompanyDynamic(serCompanyVO);
Map<String ,Object> map = ResultUtil.getRsMap(num);
map.put("serCompanyVO", serCompanyVO);
return map;
}
/**
* 批量新增公司
* http://localhost:8080/addCompanyBatch
* @return
*/
@RequestMapping(method = RequestMethod.GET, value = "addCompanyBatch")
@ResponseBody
public Map<String, Object> addCompanyBatch(){
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
String timeStr = timestamp.toString();
SerCompanyVO serCompanyVO = new SerCompanyVO();
serCompanyVO.setCompanyName("导入1");
serCompanyVO.setCompanyCode("3301");
serCompanyVO.setCompanyCrdt(timeStr);
SerCompanyVO serCompanyVO1 = new SerCompanyVO();
serCompanyVO1.setCompanyName("导入2");
serCompanyVO1.setCompanyCode("3302");
serCompanyVO1.setCompanyCrdt(timeStr);
List<SerCompanyVO> list = new ArrayList<>();
list.add(serCompanyVO);
list.add(serCompanyVO1);
int num = serCompanyService.addCompanyBatch(list);
return ResultUtil.getRsMap(num);
}
/**
* 修改公司信息 固定语句
* http://localhost:8080/updateCompany?companyId=13&companyName=百度2&companyCode=333&companyMsg=百度2是一家上市公司
* @return
*/
@RequestMapping(method = RequestMethod.GET, value = "updateCompany")
@ResponseBody
public Map<String, Object> updateCompany(SerCompanyVO serCompanyVO){
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
String timeStr = timestamp.toString();
serCompanyVO.setCompanyCrdt(timeStr);
int num = serCompanyService.updateCompany(serCompanyVO);
return ResultUtil.getRsMap(num);
}
/**
* 修改公司信息 动态语句
* http://localhost:8080/updateCompanyDynamic?companyId=13&companyName=百度3&companyCode=333
* @return
*/
@RequestMapping(method = RequestMethod.GET, value = "updateCompanyDynamic")
@ResponseBody
public Map<String, Object> updateCompanyDynamic(SerCompanyVO serCompanyVO){
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
String timeStr = timestamp.toString();
serCompanyVO.setCompanyCrdt(timeStr);
int num = serCompanyService.updateCompanyDynamic(serCompanyVO);
return ResultUtil.getRsMap(num);
}
/**
* 删除公司信息
* http://localhost:8080/deleteCompanyById?companyId=15
* @param companyId
* @return
*/
@RequestMapping(method = RequestMethod.GET, value = "deleteCompanyById")
@ResponseBody
public Map<String, Object> deleteCompanyById(Integer companyId){
int num = serCompanyService.deleteCompanyById(companyId);
return ResultUtil.getRsMap(num);
}
}
スタートアップクラス
Spring Boot 起動用に com.study に MainStarter クラスを記述します。コードは次のとおりです。
package com.study;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MainStarter {
public static void main(String[] args) {
SpringApplication.run(MainStarter.class, args);
}
}
テスト
右クリックして MainStarter クラスを実行します。次のようにコンソール出力を確認し、プロジェクトが正常に開始されることを確認します。
ブラウザを開き、インターフェイス テスト用に次のアドレスを入力し、データをクエリするインターフェイスを選択します。
http://localhost:8080/querySerCompanyList
結果は次のとおりです
他のインターフェイス アドレスはコントローラー クラスで見つかり、順番にテストできます。
さて、mybatis と Spring Boot の統合は基本的に完了しました。
最後に書きます
オープンソースは美徳です。できるだけ早くオープンソース コミュニティに参加し、美しいエコシステムを一緒に構築してください。