1. 程式人生 > >MyBatis的學習總結一

MyBatis的學習總結一

一、MyBatis的介紹:

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

MyBtis是一個優秀的持久層框架,它對jdbc的操作資料庫的過程進行封裝,使開發者只需關注sql本身,而不需要花費精力去處理如

冊驅動、 建立connection、建立statement、手動設定引數、結果集檢索等jdbc繁雜的過程程式碼。

MyBatis通過xml或註解的方式將要執行的各種statement(statement、preparedStatement、Callablestatement)配置起來,並通過Java

物件和statement中的sql進行對映生成最終的執行sql語句,最後由MyBatis框架執行sql並將結果對映成java物件並返回。

二、MyBatis的入門案例以及基本配置:

需求:使用MyBatis完成增刪改查的基本功能

1、建立資料庫,加入測試資料(以下是sql執行檔案)

/*
Navicat MySQL Data Transfer

Source Server         : RBAC_permission
Source Server Version : 50527
Source Host           : localhost:3306
Source Database       : mybatis

Target Server Type    : MYSQL
Target Server Version : 50527
File Encoding         : 65001

Date: 2018-01-27 20:08:42
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) NOT NULL COMMENT '使用者名稱稱',
  `birthday` date DEFAULT NULL COMMENT '生日',
  `sex` char(1) DEFAULT NULL COMMENT '性別',
  `address` varchar(256) DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', '王五', null, '2', null);
INSERT INTO `user` VALUES ('10', '張三', '2014-07-10', '1', '北京市');
INSERT INTO `user` VALUES ('16', '張小明', null, '1', '河南鄭州');
INSERT INTO `user` VALUES ('24', '張三丰', null, '1', '河南鄭州');
INSERT INTO `user` VALUES ('25', '狗剩', null, '1', '北海道');
INSERT INTO `user` VALUES ('26', '王五', null, null, null);
INSERT INTO `user` VALUES ('28', '李逍遙', '2017-11-23', '男', '青島');
INSERT INTO `user` VALUES ('30', '菜呀', '2017-11-23', '男', '中國');

2、建立java工程,加入mybtis的核心包、依賴包、資料驅動包(專案結構圖如下)


3、建立SqlMapConfig.xml配置檔案。SqlMapConfig是MyBatis的核心配置檔案,配置檔案內容為資料來源、事務管理。

<?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>

	<typeAliases>
		<!-- 
			typeAlias: 起別名
				type: 指定pojo的型別
				alias: 別名,大小寫不敏感
		<typeAlias type="com.heima.pojo.User" alias="user"/>
		 -->
		 
		 <!-- 
		 	package: 批量起別名,
		 		name: 指定掃描的報名
		 		別名: 就是類名,大小寫不敏感
		  -->
		<package name="com.evil.pojo"/>		
	</typeAliases>

	<!-- 和spring整合後 environments配置將廢除 -->
	<environments default="development">
		<environment id="development">
			<!-- 使用jdbc事務管理 -->
			<transactionManager type="JDBC" />
			<!-- 資料庫連線池 -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url"
					value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
				<property name="username" value="root" />
				<property name="password" value="root" />
			</dataSource>
		</environment>
	</environments>
	
	<!-- 載入對映檔案 -->
	<mappers>
		<!-- 
			mapper標籤: 引入對映檔案
				url: 絕對路徑,不推薦使用
				resource: 相對路徑
		 -->
		<!-- <mapper resource="User.xml"/> -->
		
		<!-- 
			class: 指定介面的全路徑名稱
				1: 介面檔案和對映檔案必須在同一個包下
				2: 介面檔案和對映檔名稱必須相同,除了副檔名
		<mapper class="com.evil.mapper.UserMapper"/>
		 -->
		
		<!-- 
			package標籤: 批量掃描對映檔案
				name: 指定掃描的包名
				1: 介面檔案和對映檔案必須在同一個包下
				2: 介面檔案和對映檔名稱必須相同,除了副檔名
		 -->
		<package name="com.evil.mapper"/>
		
	</mappers>
</configuration>
4.建立實體類

package com.evil.pojo;
import java.util.Date;

public class User {
	/**
	 * 
	 */
	private Integer id;
	private String username;// 使用者姓名
	private String sex;// 性別
	private Date birthday;// 生日
	private String address;// 地址
        ..............getXXX/setXX略

5.建立介面(相當於Dao,採用的是Mybatis的動態代理方式)  

Mapper介面開發方法只需要我們編寫Mapper介面(相當於Dao介面),由Mybatis框架根據介面定義建立介面的動態代理物件。

Mapper介面開發需要遵循以下規範:

1、對映檔案的Namespace必須等於介面的全路徑名稱

2、對映檔案的sql唯一標示id必須等於介面方法的名稱

3、對映檔案的parameterType必須等於介面方法的引數型別

4、對映檔案的resultType必須等於介面方法的返回型別

package com.evil.mapper;

import java.util.List;
import com.evil.pojo.User;

public interface UserMapper {
	//根據使用者id查詢一個使用者資訊
	public User findUserById(Integer id);
	//根據使用者名稱稱模糊查詢使用者資訊列表
	public List<User> findByUserUsername(String Username);
	//新增使用者資訊
	public void addUser(User user);
}
6.建立介面的對映檔案
<?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.evil.mapper.UserMapper">
	
	<!-- 
		mybatis動態代理的開發規範
			1: 對映檔案的namespace必須等於介面的全路徑名稱
			2: 對映檔案的sql唯一標示id必須等於 介面方法的名稱
			3: 對映檔案的parameterType必須等於介面方法的 引數型別
			4: 對映檔案的resultType必須等於介面方法的返回型別
	 -->
	
	<select id="findUserById" parameterType="int" resultType="com.evil.pojo.User">
		select * from user where id = #{id}
	</select>
	
	<select id="findByUserUsername" parameterType="string" resultType="com.evil.pojo.User">
		select * from user where username like '%${value}%';
	</select>
	
	<insert id="addUser" parameterType="com.evil.pojo.User">
		insert into user(username,sex,birthday,address) values(#{username},#{sex},#{birthday},#{address});
	</insert>
	
</mapper>

7.測試

說明:@Before是在執行JUnit的@Test之前例項化SqlSessionFactory。沒必要每次訪問Mybatis的時候都要建立一個SqlSessionFactory,

只需要定義一個全域性的變數,建立一次就好。

package com.evil.test;

import java.io.InputStream;
import java.util.Date;
import java.util.List;

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

import com.evil.mapper.UserMapper;
import com.evil.pojo.User;

public class UserMapperTest {
	
	SqlSessionFactory sessionFactory;
	
	@Before
	public void testName() throws Exception {
		String resource="SqlMapConfig.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	}
	
	//新增使用者資訊
	@Test
	public void addUser(){
		SqlSession session = sessionFactory.openSession();
		UserMapper userMapper = session.getMapper(UserMapper.class);
		User user = new User();
		user.setUsername("菜呀");
		user.setSex("男");
		user.setBirthday(new Date());
		user.setAddress("中國");
		userMapper.addUser(user);
		session.commit();
	}
	
	//模糊查詢使用者資訊列表
	@Test
	public void findUserByUsername(){
		SqlSession session = sessionFactory.openSession();
		UserMapper userMapper = session.getMapper(UserMapper.class);
		List<User> list = userMapper.findByUserUsername("張");
		for (User user : list) {
			System.out.println(user);
		}
	}
	
	
	
	
	@Test
	public void findById(){
		SqlSession session = sessionFactory.openSession();
		UserMapper usermapper = session.getMapper(UserMapper.class);
		User user = usermapper.findUserById(1);
		System.out.println(user);
	}
}

三、具體的執行流程?

MyBatis流程圖(圖片來自網路:侵刪)

1、mybatis的配置

SqlMapConfig.xml,此檔案作為mybatis的全域性配置檔案,配置了myatis的執行環境等資訊。

mapper.xml檔案即sql對映檔案,檔案中配置了操作資料庫的sql語句。此檔案需要在SqlMapConfig中載入。

2、通過mybatis環境資訊構造SqlSessionFactory工廠即會話工廠,它是由SqlSessionFactoryBuilder物件呼叫build()方法建立的。

3、由會話工廠建立sqlSession即會話,該會話的作用就是完成資料庫的訪問和結果的對映。

4、mybatis底層自定義了Executor執行器介面來操作資料庫,Executor介面有兩個實現,一個是基本執行器、一個是快取執行器。

5、MappedStatement也是mybatis一個底層封裝物件,它包裝了mybatis配置資訊以及sql對映資訊等。Mapper.xml檔案中一個sql

對應一個MappedStatement物件,sql的id即是MappedStatement的id。

6、MappedStatement對sql執行輸入引數進行定義,包括HashMap、基本型別、pojo,Executor通過MappedStatement在執行sql前

將輸入的java物件對映到sql中.

7、MappedStatement對sql執行輸出結果進行定義,包括HashMap、基本型別、pojo,Excutor通過MappedStatement在執行sql後將

輸出結果對映至java物件中。


四、小問題?

1.MyBatis是怎麼樣完成實體和表之間的對映?
<select id="findUserById" parameterType="int" resultType="com.heima.pojo.User">
select * from user where id = #{id}
</select>
parameterType:引數型別,將傳入的java物件,對映成表中的欄位,加入到sql語句中。
resultType:將執行sql的的返回結果對映成Java物件。

2.MyBatis中使用#{}和${}書寫佔位符有什麼區別?

#將傳入的資料都當成一個字串,會對傳入的資料自動加上引號;$將傳入的資料直接顯示生成在SQL中。注意:使用$佔位符可能

會導致sql注入攻擊,能用#號的地方就不要使用$,寫OrderBy子句時應該用$而不是#。