Mybatis入門學習一

簡介

什麼是mybatis:mybatis是一款優秀的持久層框架,支持定製化SQL、存儲過程以及高級映射,避免了幾乎所有的JDBC代碼和手動設置參數以及獲取結果集。Mybatis可以使用簡單的XML或者註解來配置和映射原生類型、接口和Java的POJO爲數據庫中的記錄。

mybatis開始

先去mybatis官網點了這裏

第一步:引入maven

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>x.x.x</version>
</dependency>

第二步:Building SqlSessionFactory from XML(搭建SqlSessionFactory環境):

<?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="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>

編寫的工具類:
官網中要求必須在類中引入:
String resource = “org/mybatis/example/mybatis-config.xml”;
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(inputStream);
這是通過Builder獲得SqlSessionFactory的方式。
工具類:

package com.mao.utils;

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;

//sqlSessionFactory --> sqlSession
public class MybatisUtil {

    private static SqlSessionFactory sqlSessionFactory;

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

    //既然有了SqlsessionFactory,顧名思義,我們可以從中得到SqlSession實例.
    //SqlSession包含了面向數據庫執行SQL命令所需要的方法
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }

}

寫一個實體類映射數據庫中的表:

package com.mao.pojo;

import lombok.Data;

@Data
public class User {

    private int id;
    private String username;
    private String password;
}

有了實體類就可以去定義一個數據訪問層接口:

package com.mao.dao;

import com.mao.pojo.User;

public interface UserDao {

    User getUser(Integer id);
}

其具體的實體類並不用寫,而是通過指定的mapper配置文件來實現即可:

<?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.mao.dao.UserDao">
    <select id="getUser" resultType="com.mao.pojo.User">
    select * from user where id = #{id}
  </select>
</mapper>

注意:這裏要指定mapper的命名空間,即是所對應的接口,select標籤中的id對應指定的方法名,resultType就是返回值。

注意:當sqlSession用完的時候應當關閉,否則會造成內存的浪費。

CRUD

1.namespace

namespace中的包名要和Dao/Mapper中的接口的包名一致。

UserDao接口

package com.mao.dao;

import com.mao.pojo.User;

import java.util.List;


public interface UserDao {
    /**
     * 通過id返回User
     * @param id
     * @return
     */
    User getUserById(Integer id);

    /**
     * 返回所有User
     * @return
     */
    List<User> getUserList();

    /**
     * 添加用戶
     * @param user
     * @return
     */
    int addUser(User user);

    /**
     * 更新用戶
     * @param user
     * @return
     */
    int updateUser(User user);
    /**
     * 刪除指定用戶
     * @param id
     * @return
     */
    int deleteUser(int id);
}

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.mao.dao.UserDao">
    <select id="getUserById" resultType="com.mao.pojo.User">
    select * from user where id = #{id}
    </select>
    <select id="getUserList" resultType="com.mao.pojo.User">
        select * from study.user
    </select>
    <insert id="addUser" parameterType="com.mao.pojo.User">
        insert into study.user(id,username,password) values (#{id},#{username},#{password})
    </insert>
    <update id="updateUser" parameterType="com.mao.pojo.User">
        update study.user set username=#{username},password=#{password} where id=#{id}
    </update>
    <delete id="deleteUser">
        delete from study.user where id=#{id}
    </delete>
</mapper>

Junit測試

package com.mao.dao;

import com.mao.pojo.User;
import com.mao.utils.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

import static org.junit.Assert.*;

public class UserDaoTest {

    @Test
    public void getUserById() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try {
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            User user = userDao.getUserById(1);
            System.out.println(user);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            sqlSession.close();
        }
    }

    @Test
    public void getUserList() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try {
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            List<User> userList = userDao.getUserList();
            System.out.println(userList);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

    @Test
    public void addUser() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try {
            User user = new User();
            user.setId(4);
            user.setUsername("張天偉");
            user.setPassword("123456");
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            int i = userDao.addUser(user);
            System.out.println(i);
            //這一步很關鍵,增刪改等DML是需要提交事務的
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

    @Test
    public void updateUser() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try {
            User user = new User();
            user.setId(4);
            user.setUsername("張地瓜");
            user.setPassword("438");
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            int i = userDao.updateUser(user);
            sqlSession.commit();
            System.out.println(i);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }
    @Test
    public void deleteUser(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try {
            UserDao mapper = sqlSession.getMapper(UserDao.class);
            int i = mapper.deleteUser(3);
            sqlSession.commit();
            System.out.println(i);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }
}

注意

注意,要知道mysql是支持事務的,所以增刪改等DML語句需要在操作完成時提交一下事務,否則會因爲事務的ACID特性導致操作未顯示。

萬能的Map

在mybatis中使用Map的時候只需要再接口中使用Map,而在xxMapper.xml中parameterType指定爲map,就可以像一個對象一樣去使用它了。注:
1.使用Map中的參數,直接在sql中取其key即可【parameterType=map】
2.使用對象中的屬性,直接在sql中取其屬性即可【parameterType=Object】
只有一個基本類型的時候直接取該基本類型即可,多個的話就要用到map,
或者用註解,用上述的getUserById來演示一下:

Dao層接口代碼:

/**
     * 用Map來演示
     * @param map
     * @return
     */
    int getUserById2(Map<String,Object> map);

xxMapper.xml:

<select id="getUserById2" parameterType="map">
     select * from user where id = #{id}
</select>

junit:

@Test
    public void getUserById2() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try {
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put("id",1);
            User user = userDao.getUserById(1);
            System.out.println(user);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            sqlSession.close();
        }
    }

輸出結果:
在這裏插入圖片描述

注意

這裏有兩個注意點:
1.一般公司裏如果用xml配置方式的話普遍推薦使用map,因爲那時候將會遇到有很多屬性的類,用map顯然在靈活性上比對象更好操作
2.mybatis中是以方法名爲id的,所以同一個Mapper是不支持重載的,這也是爲什麼我在上面中要將方法的名字改爲getUserById2

Mybatis的配置優化

  • configuration(配置)
  • properties(屬性):這些屬性都是可外部配置且可動態替換的,既可以在典型的 Java 屬性文件中配置,亦可通過 properties 元素的子元素來傳遞。相當於可以讀取配置文件的值,還可以在其中設置值,如果存在和外部文件相同的值,優先取外部的值
  • settings(設置):對一些屬性進行配置
  • typeAliases(類型別名):設置別名,可以減少包名的輸入,增加開發效率。可以給包起別名,也可以給類取別名:下面是給類取別人
<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
  <typeAlias alias="Blog" type="domain.blog.Blog"/>
  <typeAlias alias="Comment" type="domain.blog.Comment"/>
  <typeAlias alias="Post" type="domain.blog.Post"/>
  <typeAlias alias="Section" type="domain.blog.Section"/>
  <typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>

給包取別名:

<typeAliases>
  <package name="domain.blog"/>
</typeAliases>

每一個在包 domain.blog 中的 Java Bean,在沒有註解的情況下,會使用 Bean 的首字母小寫的非限定類名來作爲它的別名。 比如 domain.blog.Author 的別名爲 author;若有註解,則別名爲其註解值。
注意:如果實體類比較少推薦用第一種,如果比較多用第二種。第一種可以在配置中取別名,第二種不行,不過可以用註解來取別名。

@Alias("author")
public class Author {
    ...
}

如果同一個類註解和配置中都有,優先取註解。

  • typeHandlers(類型處理器):無需太瞭解
  • objectFactory(對象工廠):無需太瞭解
  • plugins(插件):無需太瞭解
  • environments(環境配置)
  • environment(環境變量)
  • transactionManager(事務管理器):分位jdbc和manager,服務於ejb,如果用spring完全不用配置。
  • dataSource(數據源):連接數據庫所用,POOLED和UNPOOLED,有池和無池,如果是POOLED就在用完之後不會銷燬,而是放回POOLED。
  • databaseIdProvider(數據庫廠商標識)
  • mappers(映射器):註冊綁定我們配置的mapper.xml文件

resultMap的引用

我們在開發中可能會遇到這樣的一種情況,就是數據庫中的表字段和對應實體類的屬性名不一致,這時候查詢就會發現該屬性本來應該有值卻沒有,比如我把上面那對象中的User對象的password改爲psd,再做一次查詢得到:
在這裏插入圖片描述
這時候就要用到,resultMap了,該屬性就是可以實現把數據庫中的列名和屬性名做一個映射的效果。

代碼:

<mapper namespace="com.mao.dao.UserDao">
    <resultMap id="userMap" type="user">
        <result column="password" property="psd"></result>
    </resultMap>
    
    <select id="getUserById" resultType="user" resultMap="userMap">
        select * from user where id = #{id}
    </select>
</mapper>

實現效果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章