1. 程式人生 > >Mybatis學習一開發流程及核心API

Mybatis學習一開發流程及核心API

  • 一 MyBatis介紹

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

      MyBatis是一個優秀的持久層框架,它對jdbc的操作資料庫的過程進行封裝,使開發者只需要關注 SQL 本身,而不需要花費精力去處理例如註冊驅動、建立connection、建立statement、手動設定引數、結果集檢索等jdbc繁雜的過程程式碼。

    Mybatis通過xml或註解的方式將要執行的各種statement(statement、preparedStatemnt、CallableStatement)配置起來,並通過java物件和statement中的sql進行對映生成最終執行的sql語句,最後由mybatis框架執行sql並將結果對映成java物件並返回。

  • 二MyBatis架構

1、mybatis配置

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

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

2、通過mybatis環境等配置資訊構造SqlSessionFactory即會話工廠

3、由會話工廠建立sqlSession即會話,操作資料庫需要通過sqlSession進行。

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

5、MappedStatement也是mybatis一個底層封裝物件,它包裝了mybatis配置資訊及sql對映資訊等。mapper.xml檔案中一個sql對應一個Mapped Statement物件,sql的id即是Mapped statement的id。

6、MappedStatement對sql執行輸入引數進行定義,包括HashMap、基本型別、pojo,Executor通過Mapped Statement在執行sql前將輸入的java物件對映至sql中,輸入引數對映就是jdbc程式設計中對preparedStatement設定引數。

7、MappedStatement對sql執行輸出結果進行定義,包括HashMap、基本型別、pojo,Executor通過Mapped Statement在執行sql後將輸出結果對映至java物件中,輸出結果對映過程相當於jdbc程式設計中對結果的解析處理過程。

  • 三 環境搭建

1.導包

需要的jar包:mybatis核心包,依賴包,資料庫驅動包

mybaits的程式碼由github.com管理

下載地址:https://github.com/mybatis/mybatis-3/releases

mybatis核心包


mybatis依賴包




2.加入配置檔案

建立log4j.properties和SqlMapConfig.xml配置檔案,

建立名稱為MyBatisConfig的source folder型別的檔案存放主配置檔案和日誌檔案



在MyBatisConfig下建立log4j.properties如下:mybatis預設使用log4j作為輸出日誌資訊。

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# 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
在MyBatisConfig下建立SqlMapConfig.xml,如下:

SqlMapConfig.xmlmybatis核心配置檔案,配置檔案內容為資料來源、事務管理。

<?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>
<!-- 批量別名定義,掃描整個包下的類,別名為類名(大小寫不敏感) -->
	<package name="com.itheima.bean"/>
</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="123" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="com/itheima/mapper/UserMapper.xml"></mapper>
	</mappers>
</configuration>

3.建立實體類

bean類作為mybatis進行sql對映使用,po類通常與資料庫表對應,

資料庫user表如下圖:


package com.itheima.bean;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable {

	private static final long serialVersionUID = 1L;
	private Integer id;
	private String username;// 使用者姓名
	private String sex;// 性別
	private Date birthday;// 生日
	private String address;// 地址


	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", sex=" + sex
				+ ", birthday=" + birthday + ", address=" + address + "]";
	}

	
	

}

4.使用動態代理開發

4.1開發規範:

Mapper介面開發方法只需要程式設計師編寫Mapper介面(相當於Dao介面),Mybatis框架根據介面定義建立介面的動態代理物件,代理物件的方法體同上邊Dao介面實現類方法。

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

1、Mapper.xml檔案中的namespacemapper介面的類路徑相同。(名稱空間繫結此介面)

2、Mapper介面方法名Mapper.xml中定義的每個statementid相同

3、Mapper介面方法的輸入引數型別mapper.xml中定義的每個sql parameterType的型別相同

4、Mapper介面方法的輸出引數型別(返回值)mapper.xml中定義的每個sqlresultType的型別相同

4.2對映檔案

定義mapper對映檔案UserMapper.xml

將UserMapper.xml放在mapper目錄下,效果如下


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:名稱空間,用於隔離sql -->
<!-- 還有一個很重要的作用,使用動態代理開發DAO,1. namespace必須和Mapper介面類路徑一致 -->
<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">
	<!-- 根據使用者id查詢使用者 -->
	<!-- 2. id必須和Mapper介面方法名一致 -->
	<!-- 3. parameterType必須和介面方法引數型別一致 -->
	<!-- 4. resultType必須和介面方法返回值型別一致 -->
	<select id="queryUserById" parameterType="int"
		resultType="cn.itcast.mybatis.pojo.User">
		select * from user where id = #{id}
	</select>

	<!-- 根據使用者名稱查詢使用者 -->
	<select id="queryUserByUsername" parameterType="string"
		resultType="cn.itcast.mybatis.pojo.User">
		select * from user where username like '%${value}%'
	</select>

	<!-- 儲存使用者 -->
	<insert id="saveUser" parameterType="cn.itcast.mybatis.pojo.User">
		<selectKey keyProperty="id" keyColumn="id" order="AFTER"
			resultType="int">
			select last_insert_id()
		</selectKey>
		insert into user(username,birthday,sex,address) values
		(#{username},#{birthday},#{sex},#{address});
	</insert>

</mapper>
4.2建立介面

建立UserMapper介面程式碼如下:


public interface UserMapper {
	/**
	 * 根據id查詢
	 * 
	 * @param id
	 * @return
	 */
	User queryUserById(int id);

	/**
	 * 根據使用者名稱查詢使用者
	 * 
	 * @param username
	 * @return
	 */
	List<User> queryUserByUsername(String username);

	/**
	 * 儲存使用者
	 * 
	 * @param user
	 */
	void saveUser(User user);
}
4.3載入UserMapper.xml檔案

修改SqlMapConfig.xml檔案,新增以下所示的內容:

	<!-- 載入對映檔案 -->
	<mappers>
		<mapper resource="com/itheima/mapper/UserMapper.xml"></mapper>
	</mappers>

4.4編寫測試類以及核心API使用

public class UserMapperTest {
	private SqlSessionFactory sqlSessionFactory;

	@Before
	public void init() throws Exception {
		// 建立SqlSessionFactoryBuilder
		SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
		// 載入SqlMapConfig.xml配置檔案
		InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
		// 建立SqlsessionFactory
		this.sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
	}

	@Test
	public void testQueryUserById() {
		// 獲取sqlSession,和spring整合後由spring管理
		SqlSession sqlSession = this.sqlSessionFactory.openSession();

		// 從sqlSession中獲取Mapper介面的代理物件
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		// 執行查詢方法
		User user = userMapper.queryUserById(1);
		System.out.println(user);

		// 和spring整合後由spring管理
		sqlSession.close();
	}

	@Test
	public void testQueryUserByUsername() {
		// 獲取sqlSession,和spring整合後由spring管理
		SqlSession sqlSession = this.sqlSessionFactory.openSession();

		// 從sqlSession中獲取Mapper介面的代理物件
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		// 執行查詢方法
		List<User> list = userMapper.queryUserByUsername("張");
		for (User user : list) {
			System.out.println(user);
		}

		// 和spring整合後由spring管理
		sqlSession.close();
	}

	@Test
	public void testSaveUser() {
		// 獲取sqlSession,和spring整合後由spring管理
		SqlSession sqlSession = this.sqlSessionFactory.openSession();

		// 從sqlSession中獲取Mapper介面的代理物件
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		// 建立儲存物件
		User user = new User();
		user.setUsername("劉備");
		user.setBirthday(new Date());
		user.setSex("1");
		user.setAddress("蜀國");
		// 執行查詢方法
		userMapper.saveUser(user);
		System.out.println(user);


		// 和spring整合後由spring管理
		sqlSession.commit();
		sqlSession.close();
	}
}

5.小結

  • selectOneselectList

動態代理物件呼叫sqlSession.selectOne()和sqlSession.selectList()是根據mapper介面方法的返回值決定,如果返回list則呼叫selectList方法,如果返回單個物件則呼叫selectOne方法。

  •  namespace

    mybatis官方推薦使用mapper代理方法開發mapper介面,程式設計師不用編寫mapper介面實現類,使用mapper代理方法時,輸入引數可以使用pojo包裝物件或map物件,保證dao的通用性。


  • mappers(對映器)

註冊指定包下的所有mapper介面

如:<package name="cn.itcast.mybatis.mapper"/>

注意:此種方法要求mapper介面名稱和mapper對映檔名稱相同,且放在同一個目錄中

  •  #{}和${}

    #{}表示一個佔位符號,#{}可以實現preparedStatement向佔位符中設定值,自動進行java型別和jdbc型別轉換。#{}可以有效防止sql注入。#{}可以接收屬性值。 如果parameterType傳輸單個簡單型別值,#{}括號中可以是value或其它名稱。

    ${}表示拼接sql串,通過${}可以將parameterType 傳入的內容拼接在sql中且不進行jdbc型別轉換, ${}可以接收簡單型別值或pojo屬性值,如果parameterType傳輸單個簡單型別值,${}括號中只能是value

6.mybatishibernate不同

Mybatis和hibernate不同,它不完全是一個ORM框架,因為MyBatis需要程式設計師自己編寫Sql語句。mybatis可以通過XML或註解方式靈活配置要執行的sql語句,並將java物件和sql語句對映生成最終執行的sql,最後將sql執行的結果再對映生成java物件。

Mybatis學習門檻低,簡單易學,程式設計師直接編寫原生態sql,可嚴格控制sql執行效能,靈活度高,非常適合對關係資料模型要求不高的軟體開發,例如網際網路軟體、企業運營類軟體等,因為這類軟體需求變化頻繁,一但需求變化要求成果輸出迅速。但是靈活的前提是mybatis無法做到資料庫無關性,如果需要實現支援多種資料庫的軟體則需要自定義多套sql對映檔案,工作量大。

Hibernate物件/關係對映能力強,資料庫無關性好,對於關係模型要求高的軟體(例如需求固定的定製化軟體)如果用hibernate開發可以節省很多程式碼,提高效率。但是Hibernate的學習門檻高,要精通門檻更高,而且怎麼設計O/R對映,在效能和物件模型之間如何權衡,以及怎樣用好Hibernate需要具有很強的經驗和能力才行。

總之,按照使用者的需求在有限的資源環境下只要能做出維護性、擴充套件性良好的軟體架構都是好架構,所以框架只有適合才是最好。