先運行mybatis例子
public class SqlSessionFactoryTest {
public static void main(String[] args) throws IOException {
String resource = "mybatis/mybatis-config.xml";
Reader reader = Resources.getResourceAsReader(resource);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(reader);
System.out.println(sqlSessionFactory);
}
}
運行結果
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@1d56ce6a
DEBUG [main] - Created connection 1865127310.
DEBUG [main] - ooo Connection Opened
DEBUG [main] - ==> Executing: select * from Role where id = ?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Columns: id, name, desc
DEBUG [main] - <== Row: 1, name, test
org.mybatis.example.domain.Role@16b3fc9e
以上代碼對應分析的源碼過程
下面的例子不用在意,可直接跳過
核心代碼演示
jdbc訪問數據庫
public class MySQLDemo {
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://127.0.0.1/mybatis";
// 數據庫的用戶名與密碼,需要根據自己的設置
static final String USER = "root";
static final String PASS = "root";
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try {
// 註冊 JDBC 驅動
Class.forName(JDBC_DRIVER);
// 打開鏈接
System.out.println("連接數據庫...");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
// 執行查詢
System.out.println(" 實例化Statement對象...");
stmt = conn.createStatement();
String sql;
sql = "select * from Role";
ResultSet rs = stmt.executeQuery(sql);
// 展開結果集數據庫
while (rs.next()) {
// 通過字段檢索
int id = rs.getInt("id");
String name = rs.getString("name");
String desc = rs.getString("desc");
// 輸出數據
System.out.print("ID: " + id);
System.out.print(", 名稱: " + name);
System.out.print(", 描述: " + desc);
System.out.print("\n");
}
// 完成後關閉
rs.close();
stmt.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (stmt != null)
stmt.close();
} catch (SQLException se2) {
}
try {
if (conn != null)
conn.close();
} catch (SQLException se) {
}
}
System.out.println("Goodbye!");
}
}
運行結果
連接數據庫...
實例化Statement對象...
ID: 1, 名稱: name, 描述: test
Goodbye!
核心功能改造
將上述jdbc訪問改造爲工具類
public class SQLUtils {
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://127.0.0.1/mybatis";
// 數據庫的用戶名與密碼,需要根據自己的設置
static final String USER = "root";
static final String PASS = "root";
public static void executeSql(String sql) {
Connection conn = null;
Statement stmt = null;
try {
// 註冊 JDBC 驅動
Class.forName(JDBC_DRIVER);
// 打開鏈接
System.out.println("連接數據庫...");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
// 執行查詢
System.out.println(" 實例化Statement對象...");
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
// 展開結果集數據庫
while (rs.next()) {
// 通過字段檢索
int id = rs.getInt("id");
String name = rs.getString("name");
String desc = rs.getString("desc");
// 輸出數據
System.out.print("ID: " + id);
System.out.print(", 名稱: " + name);
System.out.print(", 描述: " + desc);
System.out.print("\n");
}
// 完成後關閉
rs.close();
stmt.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (stmt != null)
stmt.close();
} catch (SQLException se2) {
}
try {
if (conn != null)
conn.close();
} catch (SQLException se) {
}
}
System.out.println("Goodbye!");
}
}
定義接口
public interface RoleDao {
void query();
}
這裏不定義xml,直接定義json,新建文件:priv.dengjili.mybatis.example.proxy.RoleDao.json
{
"query":"select * from Role"
}
核心代理類
public class MethodProxy implements InvocationHandler {
private String filePath;
public MethodProxy(String filePath) {
this.filePath = filePath;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String content = FileUtils.readFileToString(new File(filePath), Charset.defaultCharset());
JSONObject jsonObject = JSONObject.parseObject(content);
String sql = jsonObject.getString(method.getName());
SQLUtils.executeSql(sql);
return null;
}
public static <T> T newMethodProxy(Class<T> mapperInterface, String filePath) {
ClassLoader classLoader = mapperInterface.getClassLoader();
Class[] interfaces = new Class[]{mapperInterface};
MethodProxy proxy = new MethodProxy(filePath);
return (T) Proxy.newProxyInstance(classLoader, interfaces, proxy);
}
}
測試類
public class ProxyTest {
public static void main(String[] args) {
RoleDao dao = MethodProxy.newMethodProxy(RoleDao.class, "C:/temp-workspace/workspace/mybatis-handwritten/src/main/resources/priv.dengjili.mybatis.example.proxy.RoleDao.json");
dao.query();
}
}
運行結果
連接數據庫...
實例化Statement對象...
ID: 1, 名稱: name, 描述: test
Goodbye!
mybatis主要思想也就是上述思想