MyBatis入門

MyBatis入門

一、概述

  • MyBatis 是一款優秀的持久層框架,它支持定製化 SQL、存儲過程以及高級映射。
  • MyBatis 避免了幾乎所有的 JDBC 代碼和手動設置參數以及獲取結果集。
  • MyBatis 可以使用簡單的 XML 或註解來配置和映射原生類型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 對象)爲數據庫中的記錄。

二、官方文檔及下載

<!--mybatis-->
<dependency>
     <groupId>org.mybatis</groupId>
     <artifactId>mybatis</artifactId>
     <version>3.5.2</version>
</dependency>

三、MyBatis入門程序

3.1、搭建環境

3.1.1、創建數據庫表

CREATE DATABASE `mybatis`;
USE `mybatis`;
CREATE TABLE `user`(
	`id` INT(20) NOT NULL PRIMARY KEY,
	`name` VARCHAR(30) DEFAULT NULL,
	`pwd`VARCHAR(30)DEFAULT NULL
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `user`(`id`,`name`,`pwd`)VALUES
(1,'張三','123456'),
(2,'李四','123456')

3.1.2、創建maven項目

項目結構

在這裏插入圖片描述

pom.xml配置
  • 添加必要的maven依賴
<!--數據庫驅動-->
<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.5.2</version>
</dependency>
<!--測試-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>
  • 防止資源導出失敗的問題
<!--在build中配置resources,來防止資源導出失敗的問題-->
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

3.2、MyBatis配置文件

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">
<configuratio
    <properties resource="db.properties"/>
    
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/study/dao/UserMapper.xml"/>
    </mappers>
</configuration>
  • db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=123456

3.3、編寫代碼

3.3.1、MyBatisUtils工具類

//功能:獲取SqlSessionFactory 對象
public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            String resources = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resources);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }
}

3.3.2、User實體類

public class User {
    private int id;
    private String name;
    private String pwd;

    public User() {}

    public User(int id, String name, String pwd) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getpwd() {
        return pwd;
    }

    public void setpwd(String pwd) {
        this.pwd = pwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }
}

3.3.3、UserMapper持久層接口

public interface UserMapper {
    //根據id獲取獲取用戶
    User getUserById(int id);
    //添加用戶
    int addUser(User user);
    //根據id刪除用戶
    int deleteUserById(int id);
    //修改用戶
    int updateUesr(User user);
}

3.3.4、UserMapper.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.study.dao.UserMapper">
    
    <!--根據id查詢用戶-->
    <select id="getUserById" resultType="User">
        select * from mybatis.user where id=#{id}
    </select>
    <!--添加用戶-->
    <insert id="addUser" parameterType="User">
        insert into mybatis.user values(#{id},#{name},#{pwd})
    </insert>
    <!--刪除用戶-->
    <delete id="deleteUserById">
        delete from mybatis.user where id=#{id}
    </delete>
    <!--修改用戶信息-->
    <update id="updateUesr" parameterType="User">
        update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id}
    </update>
</mapper>
  • namespace:綁定一個對應接口

  • id:就是對應的namespace中的方法名

  • resultType:sql語句返回值類型

  • parameterType:參數類型

  • mybatis-config.xml 中註冊

<mappers>
     <mapper resource="com/study/dao/UserMapper.xml"/>
</mappers>

3.3.5、UserMapperTest測試類

public class UserMapperTest {

    @Test
    public void getUserByIdTest(){
        //獲取getUserList對象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.getUserById(1);
        System.out.println(user);
        //關閉SqlSession
        sqlSession.close();
    }
    
    @Test
    public void addUserTest(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        int num = mapper.addUser(new User(3,"王五","121212"));
        if (num>0) {
            System.out.println("添加成功!");
        }
        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void delectTest(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        int num = mapper.deleteUserById(0);
        if (num>0) {
            System.out.println("刪除成功!");
        }
        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void updateTest(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        int num = mapper.updateUesr(new User(1,"哈哈","111111"));
        if (num>0) {
            System.out.println("修改成功!");
        }
        sqlSession.commit();
        sqlSession.close();
    }
}
  • getUserById測試結果:
User{id=2, name='李四', pwd='123456'}

Process finished with exit code 0
  • **注意:**增刪改操作必須提交事務sqlSession.commit();

四、作用域(Scope)和生命週期

SqlSessionFactoryBuilder

​ 這個類可以被實例化、使用和丟棄,一旦創建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 實例的最佳作用域是方法作用域(也就是局部方法變量)。 你可以重用 SqlSessionFactoryBuilder 來創建多個 SqlSessionFactory 實例,但是最好還是不要讓其一直存在,以保證所有的 XML 解析資源可以被釋放給更重要的事情。

SqlSessionFactory

SqlSessionFactory 一旦被創建就應該在應用的運行期間一直存在,沒有任何理由丟棄它或重新創建另一個實例。 使用 SqlSessionFactory 的最佳實踐是在應用運行期間不要重複創建多次,多次重建 SqlSessionFactory 被視爲一種代碼“壞味道(bad smell)”。因此 SqlSessionFactory 的最佳作用域是應用作用域。 有很多方法可以做到,最簡單的就是使用單例模式或者靜態單例模式。

SqlSession

​ 每個線程都應該有它自己的 SqlSession 實例。SqlSession 的實例不是線程安全的,因此是不能被共享的,所以它的最佳的作用域是請求或方法作用域。 絕對不能將 SqlSession 實例的引用放在一個類的靜態域,甚至一個類的實例變量也不行。 也絕不能將 SqlSession 實例的引用放在任何類型的託管作用域中,比如 Servlet 框架中的 HttpSession。 如果你現在正在使用一種 Web 框架,要考慮 SqlSession 放在一個和 HTTP 請求對象相似的作用域中。 換句話說,每次收到的 HTTP 請求,就可以打開一個 SqlSession,返回一個響應,就關閉它。 這個關閉操作是很重要的,你應該把這個關閉操作放到 finally 塊中以確保每次都能執行關閉。

sion** 實例。SqlSession 的實例不是線程安全的,因此是不能被共享的,所以它的最佳的作用域是請求或方法作用域。 絕對不能將 SqlSession 實例的引用放在一個類的靜態域,甚至一個類的實例變量也不行。 也絕不能將 SqlSession 實例的引用放在任何類型的託管作用域中,比如 Servlet 框架中的 HttpSession。 如果你現在正在使用一種 Web 框架,要考慮 SqlSession 放在一個和 HTTP 請求對象相似的作用域中。 換句話說,每次收到的 HTTP 請求,就可以打開一個 SqlSession,返回一個響應,就關閉它。 這個關閉操作是很重要的,你應該把這個關閉操作放到 finally 塊中以確保每次都能執行關閉。

五、MyBatis的XML配置

1、properties(屬性)

這些屬性都是可外部配置且可動態替換的既可以在典型的 Java 屬性文件中配置,也可通過 properties 元素的子元素來傳遞。 這些屬性可以在整個配置文件中被用來替換需要動態配置的屬性值。

<properties resource="db.properties">
     <property name="username" value="root"/>
     <property name="password" value="123456"/>
</properties>
<dataSource type="POOLED">
    <property name="driver" value="${driver}"/>
    <property name="url" value="${url}"/>
    <property name="username" value="${username}"/>
    <property name="password" value="${password}"/>
</dataSource>
  • 注意:配置文件中的配置優先級大於property標籤中的配置,即會優先選擇配置文件中的配置。

2、typeAliases(類型別名)

  • 給實體類起別名
<typeAliases>
    <typeAlias type="com.study.pojo.User" alias="User"/>
</typeAliases>
  • 指定一個包名,MyBatis 會在包名下面搜索需要的 Java Bean
<typeAliases>
     <package name="com.study.pojo"/>
</typeAliases>

每一個在包 com.study.pojo 中的 Java Bean,在沒有註解的情況下,會使用 Bean 的首字母小寫的非限定類名來作爲它的別名。若有註解,則別名爲其註解值。

@Alias("_user")		//使用註解自定義別名爲 _user
public class User {...}

六、結果集映射(resultMap )

  • 修改上面實體類字段:pwd–>password
public class User {
    private int id;
    private String name;
    private String password;
    ...
}
  • 由於實體類字段與數據庫字段不一致(數據庫字段依然爲pwd),導致查出的 password=null
  • 解決辦法:使用結果集映射
<resultMap id="UserMap" type="User">
        <result column="pwd" property="password"/>
    </resultMap>
    
    <!--根據id查詢用戶-->
    <select id="getUserById" resultMap="UserMap">
        select id,name,pwd from mybatis.user where id=#{id}
    </select>
發佈了55 篇原創文章 · 獲贊 31 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章