MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,而且更名爲MyBatis 。iBATIS一詞來源於「internet」和「abatis」的組合,是一個基於Java的持久層框架。iBATIS提供的持久層框架包括SQL Maps和Data Access Objects(DAO)。html
MyBatis參考資料官網:https://mybatis.github.io/mybatis-3/zh/index.html。java
官網對Mybatis的介紹更加具備權威性:mysql
1)、簡單易學git
mybatis自己就很小且簡單。沒有任何第三方依賴,最簡單安裝只要兩個jar文件+配置幾個sql映射文件易於學習,易於使用,經過文檔和源代碼,能夠比較徹底的掌握它的設計思路和實現。github
2)、靈活sql
mybatis不會對應用程序或者數據庫的現有設計強加任何影響。 sql寫在xml裏,便於統一管理和優化。經過sql基本上能夠實現咱們不使用數據訪問框架能夠實現的全部功能,或許更多。數據庫
3)、解除sql與程序代碼的耦合apache
經過提供DAL層,將業務邏輯和數據訪問邏輯分離,使系統的設計更清晰,更易維護,更易單元測試。sql和代碼的分離,提升了可維護性。對開發人員而言,核心sql仍是須要本身優化:sql和java編碼分開,功能邊界清晰,一個專一業務、 一個專一數據。編程
4)、提供映射標籤,支持對象與數據庫的orm字段關係映射。 安全
5)、提供對象關係映射標籤,支持對象關係組建維護。
6)、提供xml標籤,支持編寫動態sql。
1)、編寫SQL語句時工做量很大,尤爲是字段多、關聯表多時,更是如此。
2)、SQL語句依賴於數據庫,致使數據庫移植性差,不能更換數據庫。
3)、框架仍是比較簡陋,功能尚有缺失,雖然簡化了數據綁定代碼,可是整個底層數據庫查詢實際仍是要本身寫的,工做量也比較大,並且不太容易適應快速數據庫修改。
SQL夾在Java代碼塊裏,耦合度高致使硬編碼內傷,維護不易且實際開發需求中sql是有變化,頻繁修改的狀況多見。
長難複雜SQL,對於Hibernate而言處理也不容易,內部自動生產的SQL,不容易作特殊優化。基於全映射的全自動框架,大量字段的POJO進行部分映射時比較困難。 致使數據庫性能降低。
MyBatis是iBatis的升級版,用法有不少的類似之處,可是MyBatis進行了重要的改進。
1)、Mybatis實現了接口綁定,使用更加方便。
在ibatis2.x中咱們須要在DAO的實現類中指定具體對應哪一個xml映射文件, 而Mybatis實現了DAO接口與xml映射文件的綁定,自動爲咱們生成接口的具體實現,使用起來變得更加省事和方便。
2)、對象關係映射的改進,效率更高。
3)、MyBatis採用功能強大的基於OGNL的表達式來消除其餘元素。
DROP TABLE IF EXISTS `t_user`; CREATE TABLE `t_user` ( `t_id` int(11) NOT NULL AUTO_INCREMENT, `t_username` varchar(20) NOT NULL, `t_password` varchar(8) NOT NULL, PRIMARY KEY (`t_id`) ) -- ---------------------------- -- Records of t_user -- ---------------------------- INSERT INTO `t_user` (t_username,t_password) VALUES ( 'lisi', '123456'); INSERT INTO `t_user` (t_username,t_password) VALUES ( 'wanger', '654321'); INSERT INTO `t_user` (t_username,t_password) VALUES ( '李四', '123123'); INSERT INTO `t_user` (t_username,t_password) VALUES ( '王二', '321321');
<?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> <!-- default="development" 開發環境 default="work" 發佈環境 --> <environments default="development"> <environment id="development"> <!-- 配置事物 --> <transactionManager type="JDBC"></transactionManager> <!-- 配置數據源 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://192.168.61.22:3306/test" /> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> </configuration>
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> <param name="Encoding" value="UTF-8" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" /> </layout> </appender> <logger name="java.sql"> <level value="debug" /> </logger> <logger name="org.apache.ibatis"> <level value="info" /> </logger> <root> <level value="debug" /> <appender-ref ref="STDOUT" /> </root> </log4j:configuration>
public class User { private Integer id; private String username; private String password; }
<?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" > <!-- 配置SQL語句,與實體類操做的對應關係。 --> <!-- 保證惟一性 --> <mapper namespace="com.softjx.model.UserMapper"> <!-- 將返回的數據 與對象對應。將返回的數據,按照配置組裝成對應的對象。 --> <select id="selectAll" resultType="com.softjx.model.User"> select t_id as id,t_username as username,t_password password from t_user </select> <select id="selectById" resultType="com.softjx.model.User"> select t_id as id,t_username as username,t_password password from t_user where t_id=#{id}; </select> </mapper>
<!-- 導入映射文件 --> <mappers> <mapper resource="com/softjx/model/UserMapper.xml" /> </mappers>
public class TestMybatis { private SqlSession session; @Before public void read() throws Exception { // 構建mybatis的執行對象 FileInputStream fis = new FileInputStream("src/config.xml"); SqlSession session = new SqlSessionFactoryBuilder().build(fis) .openSession(); // InputStream inputStream = // Resources.getResourceAsStream("config.xml"); // SqlSession session = new // SqlSessionFactoryBuilder().build(inputStream).openSession(); this.session = session; } @Test public void TestSelectAll() { System.out.println("查詢全部用戶"); try { List<User> users = session .selectList("com.softjx.model.UserMapper.selectAll");// 根據字符找sql語句 for (User user : users) { System.out.println(user.getId() + " " + user.getUsername() + " " + user.getPassword()); } } finally { session.close(); } } @Test public void TestSelectById() { System.out.println("查詢全部用戶"); try { User user = session .selectOne("com.softjx.model.UserMapper.selectById",2);// 根據字符找sql語句 System.out.println(user.getId() + " " + user.getUsername() + " " + user.getPassword()); } finally { session.close(); } } }
SqlSession 的實例不是線程安全的,所以是不能被共享的。
SqlSession每次使用完成後須要正確關閉,這個關閉操做是必須的。
1.全局配置文件沒有指定mapper文件。
2.數據庫配置出錯。
3.jdbc驅動沒有加載。
4.select 查詢語句沒有轉化javabean中屬性。
5.全局配置文件路徑不對。
6.log4j.xml文件沒有。
7.id名稱寫錯了。
<insert id="insertUser"> insert into t_user (t_username,t_password) values (#{username},#{password}) </insert> <update id="updateUser"> update t_user set t_username = #{username}, t_password = #{password} where t_id = #{id} </update> <delete id="deleteUser"> delete from t_user where t_id = #{id} </delete>
測試添加,修改,刪除
@Test public void TestInserUser() { System.out.println("添加一個用戶"); try { User user=new User(); user.setUsername("pkd"); user.setPassword("888888"); int count=session.insert("com.softjx.model.UserMapper.insertUser",user);// 根據字符找sql語句 session.commit(); System.out.println(count); } finally { session.close(); } } @Test public void TestUpdateUser() { System.out.println("更新一個用戶"); try { User user=new User(); user.setId(1); user.setUsername("pkd"); user.setPassword("888888"); int count=session.update("com.softjx.model.UserMapper.updateUser",user);// 根據字符找sql語句 session.commit(); System.out.println(count); } finally { session.close(); } } @Test public void TestDeleteUser() { System.out.println("更新一個用戶"); try { int count=session.delete("com.softjx.model.UserMapper.deleteUser",1);// 根據字符找sql語句 session.commit(); System.out.println(count); } finally { session.close(); } }
接口代碼:
public interface UserMapper { //查詢全部用戶 public List<User> selectAll(); //查詢全部用戶 public List<User> selectAll1(); //查詢一個用戶 public User selectById(Integer id); //添加用戶 public int insertUser(User user); //修改用戶 public int updateUser(User user); //刪除用戶 public int deleteUser(Integer id); }
Mapper.xml映射文件:
<!-- 使用接口方式 加載命名空間 使用代理模式 --> <mapper namespace="com.softjx.dao.UserMapper"> <!-- 查詢數據表中的全部記錄,並封裝User對象集合 --> <select id="selectAll" resultType="com.softjx.model.User"> select t_id as id,t_username as username,t_password password from t_user </select> <select id="selectAll1" resultType="com.softjx.model.User"> select * from t_user1 </select> <!-- 根據id查詢數據表中的一條記錄,並封裝User對象 --> <select id="selectById" resultType="com.softjx.model.User"> select t_id as id,t_username as username,t_password password from t_user where t_id=#{id}; </select> <!-- 添加用戶 --> <insert id="insertUser"> insert into t_user (t_username,t_password) values (#{username},#{password}) </insert> <!-- 更新用戶 --> <update id="updateUser"> update t_user set t_username=#{username},t_password=#{password} where t_id=#{id} </update> <!-- 刪除用戶 --> <delete id="deleteUser"> delete from t_user where t_id=#{id} </delete>
測試代碼:
//查詢全部 @Test public void TestSelectAll1() { System.out.println("查詢全部用戶"); //獲取接口的實現類對象 //會爲接口自動的建立一個代理對象,代理對象去執行增刪改查方法 try { UserMapper mapper=session.getMapper(UserMapper.class); System.out.println(mapper); List<User> users=mapper.selectAll(); System.out.println(users); for (User user : users) { System.out.println(user.getId() + " " + user.getUsername() + " " + user.getPassword()); } } finally { session.close(); } } //查詢一個用戶 @Test public void TestSelectById() { System.out.println("查詢一個用戶"); //獲取接口的實現類對象 //會爲接口自動的建立一個代理對象,代理對象去執行增刪改查方法 try { UserMapper mapper=session.getMapper(UserMapper.class); User user=mapper.selectById(2); System.out.println(user); System.out.println(user.getId() + " " + user.getUsername() + " " + user.getPassword()); } finally { session.close(); } } //添加用戶測試 @Test public void TestInserUser() { System.out.println("添加一個用戶"); try { User user=new User(); user.setUsername("pppp"); user.setPassword("666666"); UserMapper mapper=session.getMapper(UserMapper.class); int count=mapper.insertUser(user); session.commit();//這裏必定要提交,否則數據進不去數據庫中 //session.rollback(); System.out.println(count); } finally { session.close(); } } //修改用戶測試 @Test public void TestUpdateUser() { System.out.println("修改用戶"); try { User user=new User(); user.setId(10); user.setUsername("yyy"); user.setPassword("11111"); UserMapper mapper=session.getMapper(UserMapper.class); int count=mapper.updateUser(user);// 根據字符找sql語句 session.commit(); //session.rollback(); System.out.println(count); } finally { session.close(); } } //刪除用戶測試 @Test public void TestDeleteUser() { System.out.println("刪除用戶"); try { UserMapper mapper=session.getMapper(UserMapper.class); int count=mapper.deleteUser(10);// 根據字符找sql語句 session.commit(); //session.rollback(); System.out.println(count); } finally { session.close(); } }
1.SqlSession 的實例不是線程安全的,所以是不能被共享的。
2.SqlSession每次使用完成後須要正確關閉,這個關閉操做是必須的。
3.SqlSession能夠直接調用方法的id進行數據庫操做,可是咱們通常仍是推薦使用SqlSession獲取到Dao接口的代理類,執行代理對象的方法,能夠更安全的進行類型檢查操做。