Simple-ibatis hand-wrote an ORM framework

You saw

In addition to learning mybatis source code, I have completed a simple ORM framework, and have completed the execution of basic SQL and object relational mapping. Caching and transactions were added to that this week.

The source address

Previous blog address

Cache com. Simple. Ibatis. Cache

Cache interface -Cache

Public interface Cache {/** putCache */ void putCache(String key,Object val); /** getCache */ Object getCache(String key); /** clear the cache */ void cleanCache(); /** get cache keys */ int getSize(); /** Remove the cache of the key */ void removeCache(String key); }Copy the code

Provides basic caching capabilities

The basic caching implementation class -SimpleCache

public class SimpleCache implements Cache{ private static Map<String,Object> map = new HashMap<>(); @Override public void putCache(String key, Object val) { map.put(key,val); } @Override public Object getCache(String key) { return map.get(key); } @Override public void cleanCache() { map.clear(); } @Override public int getSize() { return map.size(); } @Override public void removeCache(String key) { map.remove(key); }}Copy the code

Internally, HashMap is used to implement a simple cache, which is basically a wrapper around HashMap.

Have LRU elimination strategy -LruCache

/** * @author xiabing * @description: */ public class LruCache implements Cache{private static Integer cacheSize = 100; Private static Float loadFactory = 0.75f; private Cache trueCache; private Map<String,Object> linkedCache; private static Map.Entry removeEntry; public LruCache(Cache trueCache){ this(cacheSize,loadFactory,trueCache); } public LruCache(Integer cacheSize, Float loadFactory, Cache trueCache) { this.cacheSize = cacheSize; this.loadFactory = loadFactory; this.trueCache = trueCache; this.linkedCache = new LinkedHashMap<String, Object>(cacheSize,loadFactory,true){ @Override protected boolean removeEldestEntry(Map.Entry eldest) { if(getSize() > cacheSize){ removeEntry = eldest; return true; } return false; }}; } @Override public void putCache(String key, Object val) { this.trueCache.putCache(key,val); this.linkedCache.put(key,val); if(removeEntry ! = null){ removeCache((String)removeEntry.getKey()); removeEntry = null; } } @Override public Object getCache(String key) { linkedCache.get(key); return trueCache.getCache(key); } @Override public void cleanCache() { trueCache.cleanCache(); linkedCache.clear(); } @Override public int getSize() { return trueCache.getSize(); } @Override public void removeCache(String key) { trueCache.removeCache(key); }}Copy the code

The decorator pattern is used here. LruCache is based on LinkedHashMap implementation, refer to mybatis source code. Mybatis cache implementation

Project code Presentation

See the shouldGetCache() method in the Test class in the Github project

@Test public void shouldGetCache() throws SQLException { PoolDataSource poolDataSource = new PoolDataSource (" com. Mysql. JDBC Driver ", "JDBC: mysql: / / 101.132.150.75:3306 / our - the auth", "root", "root"); Config config = new Config("com/simple/ibatis/mapper",poolDataSource); config.setOpenCache(true); Executor simpleExecutor = config.getExecutor(); UserMapper userMapper = simpleExecutor.getMapper(UserMapper.class); User user = new User(); user.setId(1); user.setName("root"); List<User> userList = userMapper.getUsers(user); List<User> userList1 = usermapper.getUsers (User); List<User> userList1 = usermapper.getUsers (User); simpleExecutor.close(); }Copy the code

This is cache. If you are interested, try it yourself

Cache is globally configurable and LruCache is generated by default. And force the cache to flush before updating, modifying, or deleting SQL operations. See the SimpleExecutor class in the project for detailed code.

Com transaction function. Simple. Ibatis. Transaction

Transaction interface -Transaction

/** * @author xiabing * @desc Add Transaction function **/ public interface Transaction {/** obtain link */ Connection getConnection() throws SQLException; /** Commit */ void commit() throws SQLException; /** rollback */ void rollback() throws SQLException; /** close */ void close() throws SQLException; }Copy the code

JDBC transaction – SimpleTransaction

package com.simple.ibatis.transaction; import com.simple.ibatis.datasource.PoolDataSource; import java.sql.Connection; import java.sql.SQLException; /** * @author xiabing * @desc public class SimpleTransaction implements Transaction{private Connection connection; Private PoolDataSource dataSource; // Data source private Integer level = connection.transaction_REPEATABLE_read; // Transaction isolation level private Boolean autoCommmit = true; Public simpleDatasource dataSource {this(dataSource,null,null); } public SimpleTransaction(PoolDataSource dataSource, Integer level, Boolean autoCommmit) { this.dataSource = dataSource; if(level ! = null){ this.level = level; } if(autoCommmit ! = null){ this.autoCommmit = autoCommmit; } } @Override public Connection getConnection() throws SQLException{ this.connection = dataSource.getConnection(); this.connection.setAutoCommit(autoCommmit); this.connection.setTransactionIsolation(level); return this.connection; } @Override public void commit() throws SQLException{ if(this.connection ! = null){ this.connection.commit(); } } @Override public void rollback() throws SQLException{ if(this.connection ! = null){ this.connection.rollback(); */ @override public void close() throws SQLException{if(! autoCommmit && connection ! = null){ connection.rollback(); } /** put back the connection pool */ if(connection! = null){ dataSource.removeConnection(connection); } /** connection set to null*/ this.connection = null; }}Copy the code

SimpleTransaction primarily transfers transaction management functionality to the database itself (i.e., connection)

Project code Presentation

@test public void shouldOpenTransaction() {/** basic configuration */ PoolDataSource PoolDataSource = new PoolDataSource (" com. Mysql. JDBC Driver ", "JDBC: mysql: / / 101.132.150.75:3306 / our - the auth", "root", "root"); Config config = new Config("com/simple/ibatis/mapper",poolDataSource); / * * set to enable the transaction, shut down automatically submit * / config. SetOpenTransaction (true); /** Get the Executor */ Executor simpleExecutor = config.getexecutor (); UserMapper userMapper = simpleExecutor.getMapper(UserMapper.class); User user = new User(); user.setId(1); user.setName("xiabing"); /** Update name to xiabing, but not commit */ usermapper.update (user); User user1 = userMapper.getUserById(1); */ system.out.println (user1.getName())); */ system.out.println (user1.getName())); /** transaction commit statement */ //simpleExecutor.com MIT (); }Copy the code

The code above can debug the Test itself on shouldOpenTransaction() in the Test class in the Github project.

conclusion

This time on the basis of the existing increase in caching and transaction functions. Another learning experience. Because the code is handwritten, there is no COPY of any code, it is not very perfect, please forgive me. If you are interested, please give me a STAR to support. Because I want to maintain this project all the time, if you are also interested, you can chat with me to do it together and write this open source project together.