1. 程式人生 > >mybatis學習筆記1——基礎知識

mybatis學習筆記1——基礎知識

原生JDBC程式中問題的總結

例:使用jdbc查詢mysql資料庫中使用者表的記錄

public String searchStudent(String number) throws SQLException{
		conn = DBUtil.getConnection();
		String sql = "select * from student"+
				" where number=?";
		PreparedStatement ptmt = conn.prepareStatement(sql);
		ptmt.setString(1, number);
		ResultSet rs = ptmt.executeQuery();
		String str = null;
		while(rs.next()){
			str = rs.getString("name")+" "+
					rs.getString("number")+
					" "+rs.getInt("math")
					+" "+rs.getInt("chinese");		
		}
                conn.close();
		return str;
	}

問題總結:

(1)資料庫連結,使用時建立,不使用時立即釋放,頻繁連結資料庫,造成資料庫資源浪費,影響資料庫效能。

            常用的解決方法是通過資料庫連線池來管理資料庫連結

(2)將sql語句硬編碼到java程式碼當中,如果sql語句修改,需要重寫編譯java程式碼,不利於修改維護

        設想解決方案:將sql語句配置在xml檔案中,

(3)向preparedStatement中設定引數,佔位符與設定的引數值硬編碼在java程式碼中,不利於系統維護

         設想解決方案:將sql語句和佔位符和設定變數全部配置在xml中

(4)從ResultSet結果集中遍歷結果資料是,存在硬編碼,將獲取表的欄位進行硬編碼

        設想解決方案:將查詢結果集,自動對映成java物件

於是mybatis因此而生。

mybatis是什麼?

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

      Mybatis讓程式設計師的主要精力放在sql上,通過mybatis提供的對映方式,自由靈活的生成(半自動化,大部分需要程式設計師編寫sql)滿足需求的sql語句

       Mybatis可以向preparedStatement中輸入的引數自動進行輸入對映

,將查詢結果集靈活的對映成java物件(輸出對映

mybatis的特點:

  • 簡單易學:本身就很小且簡單。沒有任何第三方依賴,最簡單安裝只要兩個jar檔案(mysql等資料庫連結jar和mybatis的核心jar)+配置幾個sql對映檔案易於學習,易於使用,通過文件和原始碼,可以比較完全的掌握它的設計思路和實現。

  • 靈活:mybatis不會對應用程式或者資料庫的現有設計強加任何影響。 sql寫在xml裡,便於統一管理和優化。通過sql基本上可以實現我們不使用資料訪問框架可以實現的所有功能,或許更多。

  • 解除sql與程式程式碼的耦合:通過提供DAO層,將業務邏輯和資料訪問邏輯分離,使系統的設計更清晰,更易維護,更易單元測試。sql和程式碼的分離,提高了可維護性。

  • 提供對映標籤,支援物件與資料庫的orm欄位關係對映

  • 提供物件關係對映標籤,支援物件關係組建維護

  • 提供xml標籤,支援編寫動態sql。

mybati框架原理(工作流程):

mybatis功能架構:

我們把Mybatis的功能架構分為三層:

(1)API介面層:提供給外部使用的介面API,開發人員通過這些本地API來操縱資料庫。介面層一接收到呼叫請求就會呼叫資料處理層來完成具體的資料處理。

(2)資料處理層:負責具體的SQL查詢、SQL解析、SQL執行和執行結果對映處理等。它主要的目的是根據呼叫的請求完成一次資料庫操作。

(3)基礎支撐層:負責最基礎的功能支撐,包括連線管理、事務管理、配置載入和快取處理,這些都是共用的東西,將他們抽取出來作為最基礎的元件。為上層的資料處理層提供最基礎的支撐。

入門程式

設定需求為:

根據使用者的id來查詢使用者的資訊

新增使用者

刪除使用者

1.準備:

先匯入兩個jar包:mybatis核心jar和mysql的連結jar

2.配置log4j

log4j需要再匯入log4j的jar

3.專案工程結構

SqlMapConfig.xml是mybatis的全域性配置檔案,sqlmap包下存放的是mapper.xml的對映檔案

4.配置SqlMapConfig.xml

與原生JDBC不同,mybatis將資料庫連結部分配置在SqlMapConfig.xml中,在和spring整合之後enviroments標籤將被廢除,該部分了解即可

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

    	<!-- 和spring整合後environments配置將廢除 -->
    	<environments default="development">
    		<environment id="development">
    			<!-- 使用 jdbc進行事務管理,使用mybatis進行事務控制-->
    				<transactionManager type="JDBC"/>
    				<dataSource type="POOLED">
    				    <property name="driver" value="com.jdbc.mysql.Driver"/>
    					<property name="url" value="資料庫URL"/>
    					<property name="username" value="使用者名稱"/>
    					<property name="password" value="密碼"/>
    				</dataSource>
    		</environment>
    	</environments>



 </configuration>

5.實現java程式碼:根據使用者id查詢使用者資訊

     1)建立pojo類,加入get、set方法

public class User {

	//屬性名和資料庫表字段名對應
	private int id;
	private String username;
	private String sex;
	private Date birthday;
	private String address;
}

   2)建立對映檔案User.xml

在sqlmap包下建立User.xml(原始ibatis命名),使用mapper代理開發對映檔名稱叫XXXMapper.xml(與代理介面同名同目錄,後面再提), 在對映檔案中配置sql語句。(mapper標籤的namespace(名稱空間)起到唯一標識 的作用)

<?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名稱空間起到唯一標識 的作用
 <mapper namespace="test">

    <select id="findUserById" parameterType="int" resultType="cn.itcast.po.User">
		SELECT * FROM user WHERE id=#{id}
	</select>


 </mapper>

   3)在SqlMapConfig.xml中載入對映檔案

<mappers>
    <mapper resource="sqlmap/User.xml"/>
</mapper>

   4)編寫測試程式

先編寫mapper介面

public interface UserDao {
	
	//根據id查詢使用者資訊
	public User findUserById(int id) throws Exception;
	
	//新增使用者資訊
	public void insertUser(User user ) throws Exception;
	
	//刪除使用者資訊
	public void deleteUser(int id) throws Exception;

}

編寫UserDao的實現類測試,根據使用者id查詢使用者資訊

public class UserDaoImp implements UserDao{

        public void findUserById() throws IOException {
		
		//mybatis配置檔案
		String resource = "SqlMapConfig.xml";
		//得到配置檔案流
		InputStream inputStream = Resources.getResourceAsStream(resource);
		//建立會話工廠,傳入mybatis的配置檔案資訊
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		//通過工廠得到sqlSession
		SqlSession sqlSession = sqlSessionFactory.openSession();
		//通過SqlSession來操作資料庫
		//第一個引數:對映檔案中statement的id,等於=namespace+"."+statement的id
		//第二個引數:指定和對映檔案中所匹配的parameterType型別的引數
		//sqlSession.selectOne結果是與對映檔案中所匹配的resultType型別的物件
		User user = sqlSession.selectOne("test.findUserById", 1);
		System.out.println(user.getUsername());
		//釋放資源
		sqlSession.close(); 
	}

}

sqlSession.selectOne("test.findUserById,1) 這一句中selectOne的兩個引數分別為對應的對映檔案的namespace(名稱空間)加上點加上在User.xml中編寫的select標籤的id,第二個引數1則是傳入的id值,呼叫這個方法後就會去對應的

下面是在Use.xml中的select語句,拿出來對應上面

   <select id="findUserById" parameterType="int" resultType="cn.itcast.po.User">
		SELECT * FROM user WHERE id=#{id}
	</select>

#{}是一個佔位符,等同於"?"的作用,其中#{}在接收簡單型別的資料時可以任意命名比如#{id},#{value}.....等

parameterType和resultType

在對映檔案中通過parameterType指定輸入引數的型別,通過resultType來指定輸出結果裡的型別

新增使用者

1) 在User.xml中配置sql語句

<!-- 新增使用者
	parameterType:指定輸入引數型別是POJO(包含使用者資訊)
	#{}中指定pojo的屬性名,接受到pojo物件的屬性值,mybatis通過OGNL來獲取物件的屬性值 -->
	<insert id="insertUser" parameterType="cn.itcast.po.User">
		insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address})
	</insert>

 value(#{id},#{username},#{birthday},#{sex},#{address})中佔位符的中的變數必須對應user中的屬性名,否則將插入失敗,因為這裡傳入的是pojo物件,不是簡單的資料型別。

2)測試程式碼

@Test
	public void insertUser() throws IOException{
		String resource = "SqlMapConfig.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession sqlSession = sqlSessionFactory.openSession();
		User user = new User();
		user.setUsername("linda");
		user.setBirthday(new Date());
		user.setSex("1");
		user.setAddress("河南鄭州");
		sqlSession.insert("test.insertUser",user);
		//提交事務
		sqlSession.commit();
		System.out.println(user.getId());
		sqlSession.close();
	}

這裡提一下,在執行查詢之外的操作時,需要用sqlSession.commit()進行事務的提交,不然也會插入失敗。

mybatis和hibernate本質區別和應用場景

Hibernate:是一個標準的ORM(物件關係對映)框架。入門門檻高,不需要程式設計師寫sql,sql語句自動生成。對sql語句的優化,修改比較困難

應用場景:適用於需求變化不多的中小型的專案,比如後臺管理系統,erp,orm,oa…..

Mybatis:專注的是sql本身,需要程式設計師自己編寫sql語句,sql語句的修改和優化就比較方便。Mybatis是一個不完全的ORM框架,雖然程式設計師自己寫sql,但是mybatis也可以實現對映(輸入、輸出對映)。

應用場景:主要適用於需求變化較多的專案,比如:網際網路專案