感受好多事物都遵循28原則,Mybatis也不例外,2成的代碼可以完成8成的需求。我就準備分析一下主要的代碼。如下是大綱(待定)java
mybatis是基於jdbc的。jdbc提供了java客戶端與關係型數據庫的一套標準接口。可以完成鏈接數據庫、提交sql語句等基本功能。那mybatis又主要作了哪些事情呢?mysql
再來對比並複習下jdbc和mybatis的demo吧。sql
import java.sql.*; public class HelloWorld { static final String user = ""; static final String password = ""; static final String url = ""; public static void main(String[] args) throws Throwable{ Class.forName("com.mysql.jdbc.Driver"); Connection connection = DriverManager.getConnection(url,user, password); Statement statement = connection.prepareStatement("select * from product where id = ?"); ((PreparedStatement) statement).setInt(1, 1); ResultSet resultSet = ((PreparedStatement) statement).executeQuery(); while (resultSet.next()){ String name = resultSet.getString("name"); double price = resultSet.getDouble("price"); String imgUrl = resultSet.getString("img_url"); System.out.println("name: "+name+" price: "+price+" imgUrl: "+imgUrl); } } }
以上是jdbc的demo。能夠看到很是的簡單粗暴。加載相應的數據庫驅動後,就能經過url、帳號、密碼來獲取鏈接了。再經過Statement來構造sql語句。結果存儲在ResultSet中。具體能夠查看jdbc的文檔。
接下來看下mybatis的demo數據庫
//Product實體類 import lombok.Data; @Data public class Product { private long id; private String name; private String imgUrl; private double price; }
//Product Mapper public interface ProductMapper { @Select("select * from product where id = #{id}") Product detail(long id); }
//DataSource工廠類 public class DataSourceFactory { public static DataSource getDataSource() { String driver = "com.mysql.jdbc.Driver"; String url = ""; String username = ""; String password = ""; return new PooledDataSource(driver, url, username, password); } }
//Environment工廠類 public class EnvironmentFactory { static Environment getEnvironment(){ return new Environment("dev", new JdbcTransactionFactory(), DataSourceFactory.getDataSource()); } }
//SQLSession工具類 public class SqlSessionFactoryUtil { private static SqlSessionFactory sqlSessionFactory = null; private static Object lock = new Object(); private static void addMapper(Configuration configuration){ configuration.addMapper(ProductMapper.class); } public static void initSqlSessionFactory() { sqlSessionFactory = null; Environment environment = EnvironmentFactory.getEnvironment(); Configuration configuration = new Configuration(environment); addMapper(configuration); synchronized (lock){ if(sqlSessionFactory == null){ sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration); } } } public static SqlSession getSqlSession() { if(sqlSessionFactory == null){ initSqlSessionFactory(); } return sqlSessionFactory.openSession(); } }
代碼可能比較多。可是仔細看,其實都是很簡單的代碼。Product實體類和ProductMapper就不說了。DataSourceFactory就是設置了下帳號密碼等用來鏈接數據庫,使用的類主要是PooledDataSource,使用鏈接池方式鏈接數據庫。EnvironmentFactory就是設置了下數據源是剛剛的DataSource,使用jdbc管理事務。SQLSession工具類就是經過SqlSessionFactoryBuilder來獲取sqlSessionFactory,再獲取SqlSession。接下來看下如何使用吧。緩存
public class TestOrderMapper { private SqlSession sqlSession = null; private ProductMapper productMapper= null; @Before public void init(){ sqlSession = SqlSessionFactoryUtil.getSqlSession(); productMapper = sqlSession.getMapper(ProductMapper.class); } @Test public void getProduct(){ Product product = productMapper.detail(1); System.out.println(product); } @After public void close() { sqlSession.close(); } }
經過這兩段代碼的對比。咱們可以看到mybatis的主要優勢是:
1.管理了數據庫鏈接。能夠看到咱們操做的並非數據庫鏈接,而是SQLSession。
2.經過註解管理sql語句。
3.將結果集映射到sql語句。
是否是和上面作的比較對應上了。mybatis
接來下該進入主題了,如何實現mybatis。
如下均爲基本思路,後面各個章節會細講。
數據庫鏈接管理咱們只考慮鏈接池,基本思路:數據庫鏈接後,將其放在一個list中。每次獲取SQLSession,list中有則取出來,若list中沒有而且未超過鏈接池最大鏈接數則獲取新的鏈接,不然等待。每次關閉SQLSession,則將鏈接放回list中。app
sql語句管理咱們只考慮註解的方式。由於xml最終仍是會轉化爲java對象。經過demo中能夠看到,咱們是將sql定義在了接口的方法註解上。咱們能夠經過反射來獲取到註解上sql語句,以及選項。這時咱們就知道這個方法該如何執行sql語句了,就能夠用動態代理生成這個方法了。工具
結果集映射結果集映射,首先咱們要獲取方法的返回類型,所以最重要的仍是反射。若是還考慮懶加載的話,那就要用到動態代理了。ui