mybatis是一個持久層的框架,是apache下的頂級項目。java
mybatis託管到goolecode下,再後來託管到github下(https://github.com/mybatis/mybatis-3/releases)。mysql
mybatis讓程序將主要精力放在sql上,經過mybatis提供的映射方式,自由靈活生成(半自動化,大部分須要程序員編寫sql)知足須要sql語句。git
mybatis能夠將向 preparedStatement中的輸入參數自動進行輸入映射,將查詢結果集靈活映射成java對象。(輸出映射)程序員
根據用戶id(主鍵)查詢用戶信息github
根據用戶名稱模糊查詢用戶信息spring
添加用戶sql
刪除 用戶數據庫
更新用戶apache
java環境:jdk1.7.0_72安全
eclipse:indigo
mysql:5.1
mybatis運行環境(jar包):
從https://github.com/mybatis/mybatis-3/releases下載,3.2.7版本
lib下:依賴包
mybatis-3.2.7.jar:核心 包
mybatis-3.2.7.pdf,操做指南
加入mysql的驅動包
配置mybatis的運行環境,數據源、事務等。
映射文件命名:
User.xml(原始ibatis命名),mapper代理開發映射文件名稱叫XXXMapper.xml,好比:UserMapper.xml、ItemsMapper.xml
在映射文件中配置sql語句。
Id:表示映射文件的sql,將sql語句封裝到mappedStatement對象中,因此id成爲statement的id
resultType:將單條結果映射成java對象
在sqlMapConfig.xml中加載User.xml:
使用User.xml,添加根據用戶名稱模糊查詢用戶信息的sql語句。
(1)paramterType---輸入參數類型,resultType---返回java類型
(2)注意:sql語句中 佔位符---#{value}
字符串拼接---’%${value}%’ 可能引發sql注入(好比輸入value=OR 1=1 OR)
(3)selectOne查詢一條,selectList返回多條結果
在 User.xml中配置添加用戶的Statement
mysql自增主鍵,執行insert提交以前自動生成一個自增主鍵。
經過mysql函數獲取到剛插入記錄的自增主鍵:
LAST_INSERT_ID()
是insert以後調用此函數。
修改insertUser定義:
使用mysql的uuid()函數生成主鍵,須要修改表中id字段類型爲string,長度設置成35位。
執行思路:
先經過uuid()查詢到主鍵,將主鍵輸入 到sql語句中。
執行uuid()語句順序相對於insert語句以前執行。
經過oracle的序列生成主鍵:
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
SELECT 序列名.nextval()
</selectKey>
insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address})
在映射文件中經過parameterType指定輸入 參數的類型。
在映射文件中經過resultType指定輸出結果的類型。
#{}表示一個佔位符號,#{}接收輸入參數,類型能夠是簡單類型,pojo、hashmap。
若是接收簡單類型,#{}中能夠寫成value或其它名稱。
#{}接收pojo對象值,經過OGNL讀取對象中的屬性值,經過屬性.屬性.屬性...的方式獲取對象屬性值。
${}表示一個拼接符號,會引用sql注入,因此不建議使用${}。
${}接收輸入參數,類型能夠是簡單類型,pojo、hashmap。
若是接收簡單類型,${}中只能寫成value。
${}接收pojo對象值,經過OGNL讀取對象中的屬性值,經過屬性.屬性.屬性...的方式獲取對象屬性值。
selectOne表示查詢出一條記錄進行映射。若是使用selectOne能夠實現使用selectList也能夠實現(list中只有一個對象)。
selectList表示查詢出一個列表(多條記錄)進行映射。若是使用selectList查詢多條記錄,不能使用selectOne。
若是使用selectOne報錯:
org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 4
hibernate:是一個標準ORM框架(對象關係映射)。入門門檻較高的,不須要程序寫sql,sql語句自動生成了。
對sql語句進行優化、修改比較困難的。
應用場景:
適用與需求變化很少的中小型項目,好比:後臺管理系統,erp、orm、oa。。
mybatis:專一是sql自己,須要程序員本身編寫sql語句,sql修改、優化比較方便。mybatis是一個不徹底 的ORM框架,雖然程序員本身寫sql,mybatis 也能夠實現映射(輸入映射、輸出映射)。
應用場景:
適用與需求變化較多的項目,好比:互聯網項目。
企業進行技術選型,以低成本 高回報做爲技術選型的原則,根據項目組的技術力量進行選擇。
經過SqlSessionFactoryBuilder建立會話工廠SqlSessionFactory
將SqlSessionFactoryBuilder當成一個工具類使用便可,不須要使用單例管理SqlSessionFactoryBuilder。
在須要建立SqlSessionFactory時候,只須要new一次SqlSessionFactoryBuilder便可。
經過SqlSessionFactory建立SqlSession,使用單例模式管理sqlSessionFactory(工廠一旦建立,使用一個實例)。
未來mybatis和spring整合後,使用單例模式管理sqlSessionFactory。
SqlSession是一個面向用戶(程序員)的接口。
SqlSession中提供了不少操做數據庫的方法:如:selectOne(返回單個對象)、selectList(返回單個或多個對象)、。
SqlSession是線程不安全的,在SqlSesion實現類中除了有接口中的方法(操做數據庫的方法)還有數據域屬性。
SqlSession最佳應用場合在方法體內,定義成局部變量使用。
程序員須要寫dao接口和dao實現類。
須要向dao實現類中注入SqlSessionFactory,在方法體內經過SqlSessionFactory建立SqlSession
public class UserDaoImpl implements UserDao {
// 須要向dao實現類中注入SqlSessionFactory
// 這裏經過構造方法注入
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User findUserById(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("test.findUserById", id);
// 釋放資源
sqlSession.close();
return user;
}
@Override
public void insertUser(User user) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//執行插入操做
sqlSession.insert("test.insertUser", user);
// 提交事務
sqlSession.commit();
// 釋放資源
sqlSession.close();
}
@Override
public void deleteUser(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//執行插入操做
sqlSession.delete("test.deleteUser", id);
// 提交事務
sqlSession.commit();
// 釋放資源
sqlSession.close();
}
}
1、dao接口實現類方法中存在大量模板方法,設想可否將這些代碼提取出來,大大減輕程序員的工做量。
2、調用sqlsession方法時將statement的id硬編碼了
3、調用sqlsession方法時傳入的變量,因爲sqlsession方法使用泛型,即便變量類型傳入錯誤,在編譯階段也不報錯,不利於程序員開發。
程序員還須要編寫mapper.xml映射文件
程序員編寫mapper接口須要遵循一些開發規範,mybatis能夠自動生成mapper接口實現類代理對象。
開發規範:
1、在mapper.xml中namespace等於mapper接口地址
2、mapper.java接口中的方法名和mapper.xml中statement的id一致
3、mapper.java接口中的方法輸入參數類型和mapper.xml中statement的parameterType指定的類型一致。
4、mapper.java接口中的方法返回值類型和mapper.xml中statement的resultType指定的類型一致。
總結:
以上開發規範主要是對下邊的代碼進行統一輩子成:
User user = sqlSession.selectOne("test.findUserById", id);
sqlSession.insert("test.insertUser", user);
。。。。
若是mapper方法返回單個pojo對象(非集合對象),代理對象內部經過selectOne查詢數據庫。
若是mapper方法返回集合對象,代理對象內部經過selectList查詢數據庫。
mapper接口方法參數只能有一個,系統是否不利於擴展維護。
系統 框架中,dao層的代碼是被業務層公用的。
即便mapper接口只有一個參數,可使用包裝類型的pojo知足不一樣的業務方法的需求。
注意:持久層方法的參數能夠包裝類型、map。。。,service方法中建議不要使用包裝類型(不利於業務層的可擴展)。