mybatis代理模式简单实现对JDBC的封装
JDBC主要业务与次要业务分析
1. 加载驱动
2. 建立连接
3. 创建preparestatement
4. 执行sql命令
5. 关闭连接,preparestatement
主要业务是4,其他全是次要业务
(1)定义接口
public interface SqlSession { public int save(String sql)throws Exception; }
(2)接口实现类
public class DeptMapper implements SqlSession { PreparedStatement ps; @Override public int save(String sql) throws SQLException {//JDBC主要业务 输送sql int num= ps.executeUpdate(sql); return num; } }
(3)通知类
public class Invaction implements InvocationHandler { private SqlSession obj;//具体被监控对象 Connection connection ; PreparedStatement pStatement; public Invaction(SqlSession param){ this.obj =param; } @Override public Object invoke(Object porxy, Method method, Object[] params) throws Throwable { Object value; //1.执行JDBC初始次要业务 init(); //2.执行JDBC主要业务 Field psField = obj.getClass().getDeclaredField("ps"); psField.setAccessible(true); psField.set(obj, pStatement); value= method.invoke(obj, params); //3.执行JDBC结束次要业务 close(); return value; //返回被拦截方法,需要调用地方 } //次要业务 private void init()throws Exception{ Class.forName("com.mysql.jdbc.Driver"); connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/passbook", "root", "123456"); pStatement = connection.prepareStatement(""); } private void close() throws SQLException{ if(pStatement!=null){ pStatement.close(); } if(connection!=null){ connection.close(); } } }
(4)代理对象
public class SqlSessionFactory { /* * * JDK动态代理模式下,代理对象的数据类型 * 应该由监控行为来描述 * 参数: Class文件,监控类 */ public static SqlSession Builder(Class classFile)throws Exception { //1.创建被监控实例对象 SqlSession obj= (SqlSession) classFile.newInstance(); //2.创建一个通知对象 InvocationHandler adviser= new Invaction(obj); //3.向JVM申请负责监控obj对象指定行为的监控对象(代理对象) /* * loader:被监控对象隶属的类文件在内存中真实地址 * interfaces:被监控对象隶属的类文件实现接口 * h:监控对象发现小明要执行被监控行为,应该有哪一个通知对象进行辅助 */ SqlSession $proxy= (SqlSession) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), adviser); return $proxy; } }
(5)测试类
public class TestMain { public static void main(String[] args) throws Exception { Map StatementMapper = new HashMap(); StatementMapper.put("dept.save", "insert into dept(dname,location) values('java','BEIJING')"); SqlSession dao = SqlSessionFactory.Builder(DeptMapper.class); dao.save((String)StatementMapper.get("dept.save")); } }