1. 程式人生 > >MyBatis概述和Hello示例程式以及傳統的CRUD

MyBatis概述和Hello示例程式以及傳統的CRUD

 

目錄

 

1.MyBatis概述

1、mybatis簡介

2、mybatis歷史

3、為什麼要使用mybatis

4.理解 SqlSession及其子父類的含義!

2.MyBatis的Hello示例程式

1、建立一個數據庫和一個單表

2、搭建mybatis開發環境

3、建立Pojo物件User

4、在src目錄建立mybatis-config.xml核心配置檔案

5、建立UserMapper.xml配置檔案

6、傳統mybatis的hello world 示例程式碼

程式碼流程:

關於Mybatis的配置檔案提示功能:

關於log4j的提示:

注意:

7.加入log4j配置

匯入‘log4j-1.2.17.jar’包

在工程下的config資料夾中建立 "log4j.properties"檔案

列印結果:

3、傳統方式mybatis的增,刪,改,查實現

         UserDao:

編寫UserMapper.xml中的配置

編寫UserDao測試

插入記錄並返回主鍵

列印結果:



1.MyBatis概述

1、mybatis簡介

MyBatis 是支援定製化 SQL、儲存過程以及高階對映的優秀的持久層框架。

MyBatis 避免了幾乎所有的 JDBC 程式碼和手動設定引數以及獲取結果集。

MyBatis可以使用簡單的XML或註解用於配置和原始對映,將介面和Java的POJO(Plain Old Java Objects,普通的Java物件)對映成資料庫中的記錄.

2、mybatis歷史

原是apache的一個開源專案iBatis, 2010年6月這個專案由apache software foundation 遷移到了google code,隨著開發團隊轉投Google Code旗下,ibatis3.x正式更名為Mybatis ,程式碼於2013年11月遷移到Github(下載地址見後)。

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

3、為什麼要使用mybatis

MyBatis是一個半自動化的持久化層框架。

jdbc程式設計---當我們使用jdbc持久化的時候,sql語句被硬編碼到java程式碼中。這樣耦合度太高。程式碼不易於維護。在實際專案開發中會經常新增sql或者修改sql,這樣我們就只能到java程式碼中去修改。

Hibernate和JPA

長難複雜SQL,對於Hibernate而言處理也不容易

內部自動生產的SQL,不容易做特殊優化。

基於全對映的全自動框架,javaBean存在大量欄位時無法只對映部分欄位。導致資料庫效能下降。

 

對開發人員而言,核心sql還是需要自己優化

sql和java編碼分開,功能邊界清晰,一個專注業務、一個專注資料。

可以使用簡單的XML或註解用於配置和原始對映,將介面和Java的POJO對映成資料庫中的記錄。成為業務程式碼+底層資料庫的媒介

4.理解 SqlSession及其子父類的含義!

SqlSession的使用範圍

  • SqlSession中封裝了對資料庫的操作,如:查詢、插入、更新、刪除等。
  • SqlSession通過SqlSessionFactory建立。
  • SqlSessionFactory是通過SqlSessionFactoryBuilder進行建立。

SqlSessionFactoryBuilder

SqlSessionFactoryBuilder用於建立SqlSessionFacoty,SqlSessionFacoty一旦建立完成就不需要SqlSessionFactoryBuilder了,因為SqlSession是通過SqlSessionFactory建立的。所以可以將SqlSessionFactoryBuilder當成一個工具類使用,最佳使用範圍是方法範圍即方法體內區域性變數。

SqlSessionFactory

SqlSessionFactory是一個介面,介面中定義了openSession的不同過載方法,SqlSessionFactory的最佳使用範圍是整個應用執行期間,一旦建立後可以重複使用,通常以單例模式管理SqlSessionFactory。

SqlSession

SqlSession是一個面向使用者的介面,sqlSession中定義了資料庫操作方法。
每個執行緒都應該它自己的SqlSession例項。SqlSession的例項不能共享使用,它也是執行緒不安全的。因此最佳的範圍是請求或方法範圍。絕對不能將SqlSession例項的引用放在一個類的靜態欄位或例項欄位中。

2.MyBatis的Hello示例程式

1、建立一個數據庫和一個單表

drop database if exists mybatis;

create database mybatis;

use mybatis;
 ## 建立單表
####################################################################
create table t_user(
	`id` int primary key auto_increment,
	`last_name`	varchar(50),
	`sex` int
);

insert into t_user(`last_name`,`sex`) values('wsp168',1);

select * from t_user;

mysql資料庫、表 建立結果:

2、搭建mybatis開發環境

建立一個java工程

導 入 需 要 的 jar 包:

  1. log4j-1.2.17.jar
  2. mybatis-3.4.1.jar
  3. mysql-connector-java-5.1.7-bin.jar

3、建立Pojo物件User

不呼叫介面方法,直接對映到xml檔案中!

 

package com.webcode.pojo;

public class User {
	
	private Integer id;
	private String lastName;
	private Integer sex;
	public User(Integer id, String lastName, Integer sex) {
		super();
		this.id = id;
		this.lastName = lastName;
		this.sex = sex;
	}
	public User() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public Integer getSex() {
		return sex;
	}
	public void setSex(Integer sex) {
		this.sex = sex;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", lastName=" + lastName + ", sex=" + sex + "]";
	}
	
}

4、在src目錄建立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/mybatis"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="com/webcode/pojo/UserMapper.xml"/>
  </mappers>
</configuration>

配置檔案程式碼獲取方法

:

5、建立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">
  <!-- 
  		namespace名稱空間
  		取值一般有兩種情況:
  			一種情況是:使用javaBean的全類名
  			二種情況是:使用Mapper介面的全類名
   -->
<mapper namespace="com.webcode.pojo.User">
	<!-- 
  	select標籤用來配置一個select語句
  		id 用來配置一個唯一的標識
  		resultType 是查詢完之後一條記錄對應轉換成為的javaBean物件
  		#{id}是佔位符
   -->
  <select id="selectUserById" resultType="com.webcode.pojo.User">
    	select id,last_name lastName,sex from t_user where id = #{id}  
  </select>
</mapper>

 

6、傳統mybatis的hello world 示例程式碼

 

package com.webcode.pojo.test;

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;
import org.junit.Test;

import com.webcode.pojo.User;

public class UserTest {

	

	@Test
	public void testselectUserById() throws IOException {
		//從配置檔案讀取指定的資源,以輸入流的形式返回
		InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
		
		// 通過sqlSessionFactoryBuilder建立SqlSessionFactory(從輸入流獲取連線條件,建立連線工廠)
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);		
		System.out.println(sqlSessionFactory);
		
		//從工廠中獲取一個連線(看成是資料庫連線池即可),相當於 以前的Connection物件,每次用來都用關閉
		SqlSession openSession = sqlSessionFactory.openSession();
		
		try {
			/*由相對路徑對映到xml檔案中的id,調動執行sql語句,
			並以resultType定義的型別返回到請求端或者是客戶端*/
			User user = openSession.selectOne("com.webcode.pojo.User.selectUserById",1);
			System.out.println(user);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			openSession.close();//釋放資源
		}
	}

}

 

列印結果:     User [id=1, lastName=wsp168, sex=1]

程式碼流程:

關於Mybatis的配置檔案提示功能:

 

關於log4j的提示:

如果不想看到,解決方案為:

只要在應用的classpath中建立一個名稱為log4j.properties的檔案, 檔案的具體內容如下:

# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

注意:

7.加入log4j配置

匯入‘log4j-1.2.17.jar’包

在工程下的config資料夾中建立 "log4j.properties"檔案

\u4E0B\uFF1A 

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

 

列印結果:

DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
[email protected]2929
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 1585787493.
DEBUG [main] - Setting autocommit to false on JDBC Connection [[email protected]]
DEBUG [main] - ==>  Preparing: select id,last_name lastName,sex from t_user where id = ? 
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <==      Total: 1
User [id=1, lastName=wsp168, sex=1]
DEBUG [main] - Resetting autocommit to true on JDBC Connection [[email protected]]
DEBUG [main] - Closing JDBC Connection [[email protected]]
DEBUG [main] - Returned connection 1585787493 to pool.

 

3、傳統方式mybatis的增,刪,改,查實現

 

UserDao:

package com.webcode.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import com.webcode.pojo.User;
/**
 * @author 鮀城小帥
 * */
/**
 * 
 * 注意:在建立連線時,底層自動對事務commit做了false定義,而沒有提交的事務會自動回滾。
 * 		在執行CRUD時要手動提交事務,即,在執行語句後,session.commit();
 * */
public class UserDao {

	
	private SqlSessionFactory sqlSessionFactory;
	
	
	/*
	 * 建立sql會話工廠方法
	 * */
	public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
		
		this.sqlSessionFactory = sqlSessionFactory;
	}
	/*
	 * 根據id查詢使用者
	 * */
	public User queryUserById(Integer id) {
		SqlSession openSession = sqlSessionFactory.openSession();
		try {
			return openSession.selectOne("com.webcode.pojo.User.selectUserById",id);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			openSession.close();//釋放資源
		}
		return null;
	}
	/*
	 * 查詢所有使用者
	 * */
	public List<User> queryUsers(){
		SqlSession session = sqlSessionFactory.openSession();

		try {
			return session.selectList("com.webcode.pojo.User.queryUsers");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			session.close();//釋放資源
		}
		return null;
	}
	/*
	 * 新增使用者
	 * */
	public int saveUser(User user) {
		SqlSession session = sqlSessionFactory.openSession();
		try {
			 int result = session.insert("com.webcode.pojo.User.saveUser",user);
			session.commit();//提交事務
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			session.close();//釋放資源
		}
		return -1;
	}
	/*
	 * 根據id刪除使用者
	 * */
	public int deleteUserById(Integer id) {
		SqlSession openSession = sqlSessionFactory.openSession();
		try {
			int delete = openSession.delete("com.webcode.pojo.User.deleteUserById",id);
			openSession.commit();//手動提交事務
			return delete;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			openSession.close();//釋放資源
		}
		
		return -1;
		
	}
	/*
	 * 修改使用者
	 * */
	public int updateUser(User user) {
		SqlSession openSession = sqlSessionFactory.openSession();
		try {
			int update = openSession.update("com.webcode.pojo.User.updateUsers",user);
			openSession.commit();//手動提交事務
			return update;
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			openSession.close();//釋放資源
		}
		return -1;
	}
	
}

編寫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">
  <!-- 
  		namespace名稱空間
  		取值一般有兩種情況:
  			一種情況是:使用javaBean的全類名
  			二種情況是:使用Mapper介面的全類名
   -->
<mapper namespace="com.webcode.pojo.User">
	<!-- 
  	select標籤用來配置一個select語句
  		id 用來配置一個唯一的標識
  		resultType 是查詢完之後一條記錄對應轉換成為的javaBean物件
  		#{id}是佔位符
   -->
  <select id="selectUserById" resultType="com.webcode.pojo.User">
  
    	select id,last_name lastName,sex from t_user where id = #{id}  
  </select>
  
  <!-- 查詢全部的User物件 -->
  <select id="queryUsers" resultType="com.webcode.pojo.User">
  		select id,last_name lastName,sex from t_user
  </select>
  
   	<!-- parameterTypr引數型別(可選)
   		useGeneratedKeys="true"		使用(或返回)資料庫生成的主鍵
		keyProperty="id"	把資料庫返回的主鍵值注入到bean物件的id屬性中
   	
   	 -->
  <insert id="saveUser" parameterType="com.webcode.pojo.User" >
  		<!-- 
  			selectKey標籤可以定義一些查詢語句,這些語句可以選擇性地在大標籤的sql語句之前或之後執行
  				我們希望,通過執行一個查詢,把最後一次生成的id返回。
  					order屬性配置執行的順序
  						BEFORE		之前
  						AFTER		之後
  					keyProperty="id"	把資料庫返回的主鍵值注入到bean物件的id屬性中
  					resultType="int"	設定selectKey查詢之後返回的型別是什麼 int 表示Integer型別
  		 -->
  		 <selectKey order="AFTER" keyProperty="id" resultType="int">
  		 		select last_insert_id()
  		 </selectKey>
  		insert into t_user (`last_name`,`sex`) values(#{lastName},#{sex}) 
  		
  </insert>
<!--   <insert id="saveUser" parameterType="com.webcode.pojo.User"  -->
<!--   	useGeneratedKeys="true" keyProperty="id"> -->
<!--   		insert into t_user (`last_name`,`sex`) values(#{lastName},#{sex})  -->
<!--   </insert> -->
  
  	<!-- 根據id刪除一個使用者 -->
  <delete id="deleteUserById" parameterType="int">
  	delete from t_user where id=#{id}  	
  </delete>
  
  <update id="updateUser" parameterType="com.webcode.pojo.User">
  	update t_user set last_name = #{lastName},sex=#{sex} where id=#{id}
  </update>
  
</mapper>

 

編寫UserDao測試

 

package com.webcode.dao.test;

import static org.junit.Assert.*;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.BeforeClass;
import org.junit.Test;

import com.webcode.dao.UserDao;
import com.webcode.pojo.User;
/**
 * @author 鮀城小帥
 * */
public class UserDaoTest {
	
	private static UserDao userDao;
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(Resources.getResourceAsStream("mybatis-config.xml"));
		userDao = new UserDao();
		userDao.setSqlSessionFactory(sqlSessionFactory);
	}

	@Test
	public void testQueryUserById() {
		System.out.println(userDao.queryUserById(1));
	}

	@Test
	public void testQueryUsers() {
		userDao.queryUsers().forEach(System.out::println);
	}

	@Test
	public void testSaveUser() {
		userDao.saveUser(new User(null, "xxx", 1));
	}

	@Test
	public void testDeleteUserById() {
		userDao.deleteUserById(3);
	}

	@Test
	public void testUpdateUser() {

		userDao.updateUser(new User(3,"aaa",0));
	}

}

插入記錄並返回主鍵

 

 

列印結果: