写写Mybatis

今天写一下Mybatis

直接上代码,框架完成后放解释的图

public class MySqlsession {
    private Excutor excutor = new MyExcutor();
    private MyConfiguration myConfiguration = new MyConfiguration();

    public <T> T selectOne(String statement , Object parameter) {
        return excutor.query(statement , parameter);
    }

    public <T> T getMapper(Class<T> clazz) {
        //动态代理调用
        return (T) Proxy.newProxyInstance(clazz.getClassLoader() , new Class[]{clazz} ,
                new MyMapperProxy(myConfiguration , this));
    }
}
public class MyMapperProxy implements InvocationHandler {
    private MySqlsession mySqlsession;
    private MyConfiguration myConfiguration;

    public MyMapperProxy(MyConfiguration myConfiguration ,MySqlsession mySqlsession) {
        this.mySqlsession = mySqlsession;
        this.myConfiguration = myConfiguration;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        MapperBean readMapper = myConfiguration.readMapper("userMapper.xml");
        //是否是xml文件对应的接口
        if(!method.getDeclaringClass().getName().equals(readMapper.getInterfaceName())) {
            return null;
        }

        List<Function> list = readMapper.getList();
        if(null != list || 0 != list.size()) {
            for(Function function : list) {
                if(method.getName().equals(function.getFuncName())) {
                    return mySqlsession.selectOne(function.getSql() , String.valueOf(args[0]));
                }
            }
        }

        return null;
    }
}
public class MyConfiguration {
    private static ClassLoader loader = ClassLoader.getSystemClassLoader();

    /**
     * 读取xml信息并处理
     * @param resource
     * @return
     */
    public Connection bulid(String resource) {
        try {
            InputStream stream = loader.getResourceAsStream(resource);
            SAXReader reader = new SAXReader();
            Document document = reader.read(stream);
            Element root = document.getRootElement();
            return evalDataSource(root);
        } catch (Exception e) {
            throw new RuntimeException("error occured while evaling xml" + resource);
        }
    }

    private Connection evalDataSource(Element node) throws ClassNotFoundException {
        if(!node.getName().equals("database")) {
            throw new RuntimeException("root shoule be <database>");
        }

        String driverClassName = null;
        String url = null;
        String username = null;
        String password = null;

        //获取属性节点
        for(Object item : node.elements("property")) {
            Element i = (Element)item;
            String value = getValue(i);
            String name = i.attributeValue("name");
            if(name == null || value == null) {
                throw new RuntimeException("[database]:<property> should contain name and value");
            }
            //赋值
            switch (name) {
                case "url" : url = value; break;
                case "username" : username = value; break;
                case "password" : password = value; break;
                case "driverClassName" : driverClassName = value; break;
            }
        }
        Class.forName(driverClassName);
        Connection connection = null;
        try {
            //建立数据库链接
            connection = DriverManager.getConnection(url , username , password);
        } catch (SQLException e) {
            System.out.println("凉凉:数据库链接错误");
        }
        return connection;
    }

    //获取property属性的值,如果有value值,则读取;否则读取内容
    private String getValue(Element node) {
        return node.hasContent() ? node.getText() : node.attributeValue("value");
    }

    public MapperBean readMapper(String path) {
        MapperBean mapper = new MapperBean();
        try {
            InputStream stream = loader.getResourceAsStream(path);
            SAXReader reader = new SAXReader();
            Document document = reader.read(stream);
            Element root = document.getRootElement();
            //把mapper节点的namespace值存为接口名
            mapper.setInterfaceName(root.attributeValue("namespace".trim()));
            //用来存储方法的List
            List<Function> list = new ArrayList<Function>();
            //遍历根节点下所有子节点
            for(Iterator rootIter = root.elementIterator() ; rootIter.hasNext();) {
                Element e = (Element)rootIter.next();
                //以resources/UserMapper.xml为例
                //select
                String sqlType = e.getName().trim();
                //getUserById
                String funcName = e.attributeValue("id").trim();
                //select * from user where id = ?
                String sql = e.getText().trim();
                //org.chielong.bean.User
                String resultType = e.attributeValue("resultType").trim();
                Object newInstance = Class.forName(resultType).newInstance();

                //用来存储一条方法的信息
                Function fun = new Function();
                fun.setSqlType(sqlType);
                fun.setFuncName(funcName);
                fun.setSql(sql);
                fun.setResultType(newInstance);
                list.add(fun);
            }
            mapper.setList(list);
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        return  mapper;
    }
}
public class MapperBean {
    //接口名
    private String interfaceName;

    //接口下所有方法
    private List<Function> list;

    //getter & setter
}
public class Function {
    private String sqlType;
    private String funcName;
    private String sql;
    private Object resultType;
    private String parameterType;
    
    //getter & setter
}

 

public interface Excutor {
    public <T> T query(String statement , Object parameter);
}
public class MyExcutor implements Excutor{
    private MyConfiguration xmlConfiguration = new MyConfiguration();

    @Override
    public <T> T query(String sql, Object parameter) {
        Connection connection = getConnection();
        ResultSet set = null;
        PreparedStatement pre = null;

        try {
            pre = connection.prepareStatement(sql);
            //设置参数
            pre.setString(1 , parameter.toString());
            set = pre.executeQuery();
            User u = new User();
            while(set.next()) {
                u.setId(set.getString(1));
                u.setUsername(set.getString(2));
                u.setPassword(set.getString(3));
            }
            return (T) u;
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if(set != null) {
                    set.close();
                }
                if(pre != null) {
                    pre.close();
                }
                if(connection != null) {
                    connection.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    private Connection getConnection() {
        try {
            return xmlConfiguration.bulid("config.xml");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

(本来想写字的...想了想还是画图更直观)

(自从用了processon画图...真香)

public interface UserMapper {
    public User getUserById(String id);
}
public class User {
    private String id;
    private String username;
    private String password;

    //getter & setter & toString
}
<?xml version="1.0" encoding="UTF-8"?>

<mapper nameSpace="org.chielong.mapper.UserMapper">
    <select id="getUserById" resultType="org.chielong.bean.User">
        select * from user where id = ?
    </select>
</mapper>

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值