淺入mybatis(2)(手寫簡單的mybatis)
阿新 • • 發佈:2018-12-17
淺入mybatis(1)中 我們已經完整的配置了mybatis過程。可以實現通過簡單的xml檔案就實現了資料庫的增刪改查,那麼神奇之處
在哪裡呢?這一章我們簡單的實現下mybatis的實現原理,不足之處 敬請諒解
首先我個人手寫的一個流程圖如下 (我們可以先敲程式碼 再反過來看這個圖)
我寫的demo流程如下:
一:建立User實體類
二:按照流程圖所示 建立userMapperXml 將id和 sql存起來(這裡將xml寫成java檔案 其實原始的也是將xml檔案解析為map id作為key sql作為value的方式儲存起來的 這裡就不做詳細介紹)
三:mapper介面 改介面對應我們xml對應的id的方法
四:建立自己的sqlSession工廠 這裡使用動態代理 將我們所有的mapper傳進來 但是我們用代理類去完成所有的操作
(這裡體現動態代理的優越性)
五:建立資料庫的連線 並使用sqlSession 的工廠類物件實現資料庫的增刪查詢
完整的demo目錄結構如下:
1.user 類:
package com.mybatis.handWriteMybatis; public class User { private int id; private String name; private Integer age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
2.xml檔案的代替類(我們模擬將id 和class存入map中)
package com.mybatis.handWriteMybatis; import java.util.HashMap; import java.util.Map; public class UserMapperXml { // 類xml的名稱空間 public static final String namespate = "com.mybatis.handWriteMybatis.UserMapper"; public static final Map<String, String> map = new HashMap<String, String>(); static { // 模擬xml中的id與sql語句 實際中是xml檔案 被解析之後放入map中 通過id去找那個對應的sql map.put("getUserById", "select * from user where id = ?"); } }
3 操作資料庫介面類
package com.mybatis.handWriteMybatis; public interface UserMapper { public User getUserById(int id); } 4.這裡是重點 建立自己的sqlsession
package com.mybatis.handWriteMybatis; import java.lang.reflect.Proxy; public class Sqlsession { private ExcutorImp excutorImp = new ExcutorImp(); //查詢資料庫操作 public <T> T selectOne(String statement, Object parameter) { return excutorImp.query(statement, parameter); } //用動態代理完成傳入的Mapper介面要完成的操作 public <T> T getMapper(Class<T> tClass) { return (T) Proxy.newProxyInstance( tClass.getClassLoader(), new Class[] {tClass}, new MyMapperHandler<T>(this)); } }
代理類MyMapperHandler如下:
package com.mybatis.handWriteMybatis; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class MyMapperHandler<T> implements InvocationHandler { Sqlsession sqlsession = null; public MyMapperHandler(Sqlsession sqlsession) { this.sqlsession = sqlsession; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("執行invoke方法"); System.out.println(method.getDeclaringClass().getName()); System.out.println("args " + args[0]); if (method.getDeclaringClass().getName().equals(UserMapperXml.namespate)) { String sql = UserMapperXml.map.get(method.getName()); System.out.println(sql); return sqlsession.selectOne(sql, String.valueOf(args[0])); } return null; } }
5.建立連線 進行測試
<1>增刪查詢的總介面
package com.mybatis.handWriteMybatis; public interface ConnectionExcutor { public <T> T query(String statement, Object parament); }
<2>資料庫的連線以及實現上面介面的操作 package com.mybatis.handWriteMybatis; import org.junit.Test; import java.sql.*; public class ExcutorImp implements ConnectionExcutor { @Override public <T> T query(String statement, Object parament) { Connection connection = null; PreparedStatement preparedStatement = null; connection = getConnection(); try { PreparedStatement pre = connection.prepareStatement(statement); String str = (String) parament; pre.setInt(1, Integer.parseInt(str)); ResultSet set = pre.executeQuery(); User user = new User(); while (set.next()) { user.setName(set.getString(2)); } return (T) user; } catch (SQLException e) { e.printStackTrace(); } return null; } private static Connection getConnection() { String driver = "com.mysql.jdbc.Driver"; String url = "jdbc:mysql://localhost:3306/generator?characterEncoding=UTF-8"; String username = "root"; String password = "123456"; try { Class.forName(driver); Connection connection = DriverManager.getConnection(url, username, password); System.out.println("連線成功"); return connection; } catch (Exception e) { e.printStackTrace(); } return null; } @Test public void testCon() { Connection connection = ExcutorImp.getConnection(); System.out.println(connection); } }
測試程式碼:
package com.mybatis.handWriteMybatis; public class TestMybatis { public static void main(String[] args) { Sqlsession sqlsession = new Sqlsession(); UserMapper mapper = sqlsession.getMapper(UserMapper.class); User userById = mapper.getUserById(6); System.out.println(userById.getName()); } }
測試結果如下:
以上就是簡單的實現mybatis的實現 其中最主要的還是動態代理的設計思想。