1. 程式人生 > 實用技巧 >初學Mybatis筆記

初學Mybatis筆記

Mybatis

一、初識mybatis

中文文件:https://mybatis.org/mybatis-3/zh/getting-started.html
(1)Mybatis是一個數據持久層的框架
(2)實現SQL與程式碼分離
(3)避免了JDBC程式碼以及手動設定引數和獲取結果集

二、第一個Mybatis程式

基本步驟:

0、先匯入包 -- 連線資料庫的驅動包、Mybatis依賴包、Junit測試包、Lombok

1、獲取執行SQL的sqlSession物件(xml配置檔案 -> SqlSessionFactory -> SqlSession) -- 封裝為一個工具類

https://www.cnblogs.com/yulinfeng/p/6002379.html

2、獲取sqlSession物件需要載入mybatis-config.xml配置檔案

3、常規操作編寫資料類dto|pojo

4、編寫mapper(以前的Dao介面)

5、編寫對應的mapper.xml(以前的Dao的實現類)

6、編寫測試類進行測試

0、先匯入包 -- 連線資料庫的驅動包、Mybatis依賴包、Junit測試包、Lombok

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ch</groupId>
    <artifactId>jdbcstudy</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- 新增連線資料庫的驅動 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!-- 新增mybatis依賴包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
        <!-- 新增測試類Junit測試包 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!-- 簡化資料類的get,set等方法,匯入lombok依賴包 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>
</project>

1、獲取執行SQL的sqlSession物件(xml配置檔案 -> SqlSessionFactory -> SqlSession) -- 封裝為一個工具類

package com.ch.util;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

/**
 * 獲取執行SQL的SQLSession物件
 *
 * 獲取的步驟:載入配置檔案 -> sqlSessionFactory -> sqlSession
 *
 * 參照官方文件理解sqlSessionFactoryBuilder、SQLSessionFactory、SQLSession的區別。
 */
public class SqlSessionUtil {

    private static SqlSessionFactory ssf;

    static {
        //1、載入mybatis的配置檔案
        String resource = "mybatis-config.xml";
        try {
            InputStream inputStream = Resources.getResourceAsStream(resource);
            //2、獲取sqlSessionFactory物件
            ssf = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //3、獲取SqlSession物件
    public static SqlSession getSqlSession(){
        return ssf.openSession();
    }
}

2、獲取sqlSession物件需要載入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>
    <!-- 官網複製 -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mysqlstudy?serverTimezone=GMT&amp;characterEncoding=utf8&amp;useSSL=true"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 特別注意:每一個mapper.xml都需要在mybatis的核心配置檔案中進行註冊 -->
    <mappers>
        <mapper resource="com/ch/mapper/StudentMapper.xml"/>
    </mappers>
</configuration>

3、常規操作編寫資料類dto|pojo

@Data
public class Student {
    private int id;
    private int score;
    private String name;
}

4、編寫mapper(以前的Dao介面)

public interface StudentMapper {
    List<Student> getAll();
}

5、編寫對應的mapper.xml(以前的Dao的實現類)

namespace:名稱空間,一定要和mapper中介面類的包名
id:名稱空間下唯一標識,就是對應的方法名
resultType:返回值的型別
parameterType:引數型別
<?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">
<!-- 使用namespace繫結對應的介面 -->
<mapper namespace="com.ch.mapper.StudentMapper">
    <!-- id對應介面中的方法名,resultType對應返回值的型別 -->
    <select id="getAll" resultType="com.ch.dto.Student">
        select * from mysqlstudy.student;
    </select>
</mapper>

6、編寫測試類進行測試

@Test
public void getAll(){
    //獲取執行SQL的物件
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    //拿到SQL可以通過介面mapper,或者通過mapper.xml檔案
    //因為是面向介面開發,所以通過介面mapper獲取
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    List<Student> all = mapper.getAll();
    for (Student s : all){
        System.out.println(s);
    }
}

三、CRUD

特別注意:

增刪改需要提交事務

  • 可以手動提交:sqlSession.commit();

  • 也可以設定為自動提交:在工具類中設定

    //3、獲取SqlSession物件
    public static SqlSession getSqlSession(){
        return ssf.openSession();
    }
    

insert

<!-- 增 -->
<insert id="insert" parameterType="com.ch.dto.Student">
    insert into student (id, score, name) values (#{id},#{score},#{name});
</insert>

delete

<!-- 刪 -->
<delete id="delete" parameterType="_int">
    delete from student where id = #{id};
</delete>

select

<!-- 查 -->
<select id="select" resultType="com.ch.dto.Student">
    select * from student where id = #{id};
</select>

update

<!-- 改 -->
<update id="update"  parameterType="com.ch.dto.Student">
    update student set score = #{score},name=#{name} where id = #{id};
</update>

MapperTest

//增
@Test
public void insert(){
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();

    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

    Student student = new Student();
    student.setId(10);
    student.setScore(82);
    student.setName("喜羊羊");
    int insert = mapper.insert(student);
    System.out.println(insert > 0 ? "插入成功" : "插入失敗");

    //增刪改一定要提交
    sqlSession.commit();
    sqlSession.close();
}

//刪
@Test
public void delete(){
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();

    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

    int delete = mapper.delete(10);
    System.out.println(delete > 0 ? "刪除成功" : "刪除失敗");

    sqlSession.commit();
    sqlSession.close();
}

//查
@Test
public void select(){
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();

    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

    Student student = mapper.select(10);
    System.out.println(student);

    sqlSession.close();
}

//改
@Test
public void update(){
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();

    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

    Student student = new Student();
    student.setId(10);
    student.setScore(82);
    student.setName("美羊羊");
    mapper.update(student);

    sqlSession.commit();
    sqlSession.close();
}

Map傳值

map可以隨意製造引數

(1)多個引數使用Map傳值,或者使用註解
(2)如果資料表字段太多,可以考慮使用map
int update2(Map<String,Object> map);
<update id="update2" parameterType="map">
    update student set score = #{sc} where id = #{id} and name = #{sname};
</update>

模糊查詢

1、直接在傳值的使用萬用字元

List<Student> students = mapper.queryByLike("%小%");

2、可以在SQL中固定死萬用字元

select * from student where name like "%"#{value}"%";
或
select * from student where `name` like concat('%',#{value},'%');

四、初始配置檔案

mybatis-config.xml

事務管理器:JDBC(預設)、MANAGED
資料來源型別:UNPOOLED、POOLED(預設)、JNDI
<configuration>
    <!-- 官網複製 -->
   	<!-- environments可以適應多種環境,但是每個SqlSessionFactory只能選擇一種環境 -->
    <!-- default選擇預設環境,對應環境的唯一id -->
    <environments default="development">
        <environment id="development">
            <!-- transactionManager事務管理器,Mybatis中有兩種:JDBC和MANAGED -->
            <transactionManager type="JDBC"/>
            <!-- 資料來源【連線資料庫】-> dbcp、c3p0、druid -->
            <!-- 內建了三種資料來源型別:unpooled、pooled、jndi -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mysqlstudy?serverTimezone=GMT&amp;characterEncoding=utf8&amp;useSSL=true"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 特別注意:每一個mapper.xml都需要在mybatis的核心配置檔案中進行註冊 -->
    <mappers>
        <mapper resource="com/ch/mapper/StudentMapper.xml"/>
    </mappers>
</configuration>

五、配置優化

0、類型別名

別名 對映的型別
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
object Object
map Map
hashmap HashMap
list List
arraylist ArrayList
collection Collection
iterator Iterator

1、屬性(properties)優化

我們可以使用properties來引入配置檔案

*注意問題:

(1)properties的位置
元素型別為 "configuration" 的內容必須匹配"(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)"

(2)優先順序
如果properties和xml(properties中配置的相關欄位)中均使用了同一欄位,優先使用外部配置檔案

db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mysqlstudy?serverTimezone=GMT&characterEncoding=utf8&useSSL=true
username=root
password=root

mybatis-config.xml

<!-- 引入配置檔案 -->
<properties resource="db.properties">
    <!-- <property name="username" value="root"/> -->
</properties>

2、別名(typeAliases)優化

介面實現類xml中,每個返回值型別或者引數型別,都需要寫對應實體類的完整包名,所以使用別名優化

可以有三種方式:(賬戶以設定別名在配置檔案中的位置)

1、固定死,每一個實體類對應一個別名

<typeAliases>
   <typeAlias type="com.ch.dto.Student" alias="student"></typeAlias>
</typeAliases>

2、較靈活,只用設定包即可,使用的是對應包下的每個實體類類名,首字母小寫

<typeAliases>
   <package name="com.ch.dto"/>
</typeAliases>

3、最靈活,在所需要的設定的實體類上面添加註解即可

@Data
@Alias("student")
public class Student {
   private int id;
   private int score;
   private String name;
}

3、對映器(Mapper)

使用對映器繫結我們的mapper檔案,有3中方式繫結

方式一:直接繫結對應的mapper.xml檔案【推薦使用】

<mappers>
    <mapper resource="com/ch/mapper/StudentMapper.xml"/>
</mappers>

方式二:使用類class進行繫結

<mappers>
    <mapper class="com.ch.mapper.StudentMapper"></mapper>
</mappers>

注意:

  • 介面和mapper配置檔案必須同名
  • 介面和mapper配置檔案必須在同一個包下

方式三:使用包對映進行繫結

<mappers>
    <package name="com.ch.mapper"/>
</mappers>

注意:

  • 介面和mapper配置檔案必須同名
  • 介面和mapper配置檔案必須在同一個包下

六、解決屬性和欄位不一致

問題描述:實體類中的屬性和資料表中的欄位名不一致,導致最後查詢的結果為null

方式一:

as起別名的方式來進行欄位和屬性對應
<select id="getAll" resultType="student">
    select id, score, name as sName from mysqlstudy.student;
</select>

方式二:【推薦使用】

使用ResultMap進行屬性和欄位名的對映
<!-- 使用resultMap進行對映,只需對映不一樣的欄位即可 -->
<resultMap id="st" type="student">
    <result column="name" property="sName"></result>
</resultMap>

<select id="getAll" resultMap="st">
    select id, score, name as sName from mysqlstudy.student;
</select>

七、Mybatis註解開發

  • 適用於簡單的SQL語句,複雜的SQL語句推薦使用xml配置檔案
  • 本質是使用反射來獲取註解
  • 底層是動態代理

1、在介面上添加註解

@Select("select * from student")
List<Student> getAll1();

2、新增mapper對映(使用類名來進行繫結)

<mappers>
    <mapper class="com.ch1.mapper.StudentMapper"></mapper>
</mappers>

CRUD

@Insert("insert into student value(#{id},#{score},#{name})")
int insert1(Student student);

@Delete("delete from student where id = #{id}")
int delete1(@Param("id") int id);

@Select("select * from student where id = #{id}")
Student select1(@Param("id") int id);

@Update("update student set score = #{score} where id = #{id}")
int update1(Student student);