1. 程式人生 > >MyBatis的學習(一)——MyBatis介紹及實現CRUD操作

MyBatis的學習(一)——MyBatis介紹及實現CRUD操作

一、MyBatis介紹

MyBatis 本是apache的一個開源專案iBatis, 2010年這個專案由apache software foundation 遷移到了google code,並且改名為MyBatis 。2013年11月遷移到Github。

IBATIS一詞來源於“internet”和“abatis”的組合,是一個基於Java的持久層框架。iBATIS提供的持久層框架包括SQL Maps和Data Access Objects(DAO)

MyBatis是一個支援普通SQL查詢儲存過程高階對映的優秀持久層框架。MyBatis消除了幾乎所有的JDBC程式碼和引數的手工設定以及對結果集的檢索封裝。MyBatis可以使用簡單的XML或註解用於配置和原始對映,將介面和Java的POJO(Plain Old Java Objects,普通的Java物件)對映成資料庫中的記錄。

mybatis提供一種“半自動化”的ORM實現。MyBatis需要手動寫SQL,後期可以逆向工程!

這裡的“半自動化”,是相對Hibernate等提供了全面的資料庫封裝機制的“全自動化”ORM實現而言,“全自動”ORM實現了POJO和資料庫表之間的對映,以及 SQL 的自動生成和執行。

二、MyBatis特點

  • 簡單易學:本身就很小且簡單。沒有任何第三方依賴,最簡單安裝只要兩個jar檔案+配置幾個sql對映檔案易於學習,易於使用,通過文件和原始碼,可以比較完全的掌握它的設計思路和實現。
  • 靈活:mybatis不會對應用程式或者資料庫的現有設計強加任何影響。 sql寫在xml裡,便於統一管理和優化。通過sql基本上可以實現我們不使用資料訪問框架可以實現的所有功能,或許更多。
  • 解除sql與程式程式碼的耦合:通過提供DAO層,將業務邏輯和資料訪問邏輯分離,使系統的設計更清晰,更易維護,更易單元測試。sql和程式碼的分離,提高了可維護性。
  • 提供對映標籤,支援物件與資料庫的orm欄位關係對映
  • 提供物件關係對映標籤,支援物件關係組建維護
  • 提供xml標籤,支援編寫動態sql(SQL動態拼接)

效能: JDBC >  MyBatis(半自動)  >  Hibernate(全自動)

三、MyBatis使用流程

  • 1) 建立SqlSessionFactory
  • 2) 通過SqlSessionFactory建立SqlSession物件
  • 3) 通過SqlSession操作資料庫
  • 4) 呼叫session.commit()提交事務
  • 5) 呼叫session.close()關閉會話

四、搭建MyBatis環境

①下載MyBatis的jar包

這裡通過maven管理

②準備資料庫

這裡建立一個user表:

③建立主配置檔案: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>

	<!-- 引入外部配置檔案 外部的資料庫連線資訊 -->
	<properties resource="jdbc.properties" />
	<!--設定entity包下的別名-->
	<typeAliases>
		<package name="com.little.entity"/>
	</typeAliases>
	<!-- 環境   environment 元素體中包含對事 務管理和連線池的環境配置   -->
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>

	<!-- 對映 -->
	<mappers>
	  <package name="com.little.mapper"/>
	</mappers>

</configuration>

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/mybatis1102?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=1234

到這裡,準備工作完成,接下來可以進行查詢測試

五、查詢測試

①新建實體類User

package com.little.entity;

import java.util.Date;

public class User {

	private Integer id;
	private String name;
	private Date time;
	private String address;

	public User() {
		super();
	}

	public User(Integer id, String name, Date time, String address) {
		this.id = id;
		this.name = name;
		this.time = time;
		this.address = address;
	}

	public Integer getId() {
		return id;
	}

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

	public String getName() {
		return name;
	}

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

	public Date getTime() {
		return time;
	}

	public void setTime(Date time) {
		this.time = time;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

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

②建立工具類載入xml檔案以及管理事務

package com.little.utils;

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

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

/**
 * 工具類
 * @author Administrator
 */
public class MyBatisUtils {

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

	public static SqlSession getSession() {
		return sqlSessionFactory.openSession(true); //自動提交事務
	}

	public static void close(SqlSession sqlSession) {
		if (sqlSession != null) {
			sqlSession.close();
			sqlSession = null;
		}
	}
}

③建立UserMapper介面

package com.little.mapper;

import com.little.entity.User;

import java.util.List;

public interface UserMapper {
    //全查
    public List<User> getUsers();
    //條件查
    List<User> getUser(User user);
    //增加
    Integer addUser(User user);
    //修改
    Integer updateUser(User user);
    //刪除
    Integer deleteUser(Integer id);
}

④建立UserMapper檔案

<?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">
<!--suppress ALL -->
<mapper namespace="com.little.mapper.UserMapper">
    <!--為了防止實體類屬性和資料庫列名不匹配,匹配就不用-->
    <resultMap type="User" id="UserMap">
        <!-- 主鍵 -->
        <id column="ID" property="id"/>
        <!-- 普通屬性 -->
        <result column="name" property="name"/>
        <result column="time" property="time"/>
        <result column="address" property="address"/>
    </resultMap>
    <!-- 配置查詢語句    查詢用select標籤 -->
    <select id="getUsers" resultType="User">
      SELECT * FROM USER
   </select>
    <select id="getUser" resultType="User">
      select * from user
      <where>
          <if test="null != name and ''!= name">
            and name like '%' #{name} '%'
          </if>
          <if test="null != address and '' != address">
              and address like '%' #{address} '%'
          </if>
      </where>
    </select>
    <!-- 新增 Insert標籤   增刪改 預設返回資料庫受影響的行數 不用配置
        parameterType 傳入的引數 ,可以省略 框架自動推斷
        #{} 之中是物件的屬性
   -->
    <insert id="addUser">
      insert into user values (null,#{name},#{time},#{address})
    </insert>
    <update id="updateUser">
      update user set name=#{name},time =#{time},address=#{address}
      where id=#{id}
    </update>
    <delete id="deleteUser">
      delete from user where id=#{id}
    </delete>
</mapper>

博主這裡使用的編譯工具是idea工具,所以需要在pom.xml中設定讀取UserMapper.xml的位置

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

⑤測試

package com.little.testMybatis;

import com.little.entity.User;
import com.little.mapper.UserMapper;
import com.little.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class Test01 {
    SqlSession session=null;
    UserMapper um=null;  //Dao層的物件 自動生成DAO層物件

    @Before
    public void init(){
        session = MyBatisUtils.getSession();
        um = session.getMapper(UserMapper.class);//使用底層代理 自動生成Dan層物件
    }
    @Test
    public void test1(){
        List<User> users = um.getUsers();
        for (User user : users) {
            System.out.println(user);
        }
    }
    @Test
    public void test2(){
        User u = new User();
        u.setName("a");
        u.setAddress("1");
        List<User> users = um.getUser(u);
        for (User user : users) {
            System.out.println(user);
        }
    }
    @Test
    public void test3(){
        User user = new User();
        user.setName("張三");
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        user.setTime(date);
        user.setAddress("成都");
        Integer integer = um.addUser(user);
        System.out.println(integer==1?"成功":"失敗");
    }
    @Test
    public void test4(){
        User user = new User();
        user.setId(5);
        user.setName("王五");
        user.setTime(new Date());
        user.setAddress("鄭州");
        Integer integer = um.updateUser(user);
        System.out.println(integer==1?"成功":"失敗");
    }
    @Test
    public void test5(){
        Integer integer = um.deleteUser(3);
        System.out.println(integer==1?"成功":"失敗");
    }
}