瞎j8封装第二版之用xml文件来代理dao接口
也是重新整理了之前的那篇
话不多说直接上代码
首先是结构
依赖pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>yebatis</groupId> <artifactId>com.yck.yebatis</artifactId> <version>1.0-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.42</version> </dependency> </dependencies> </project>
一些基本类
用来封装一个dao信息的Mapper类
package com.yck.yebaitis; import java.util.List; public class Mapper { private String mapperClass; private List<Function> functions; public String getMapperClass() { return mapperClass; } public void setMapperClass(String mapperClass) { this.mapperClass = mapperClass; } public List<Function> getFunctions() { return functions; } public void setFunctions(List<Function> functions) { this.functions = functions; } }
封装一条方法信息的Function类
package com.yck.yebaitis; public class Function { private String name; private String type; private Class<?> resultClass; private String sql; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getType() { return type; } public void setType(String type) { this.type = type; } public Class<?> getResultClass() { return resultClass; } public void setResultClass(Class<?> resultClass) { this.resultClass = resultClass; } public String getSql() { return sql; } public void setSql(String sql) { this.sql = sql; } }
常量
package com.yck.yebaitis; public class FunctionConstants { public static final String ADD = "add"; public static final String DELETE = "delete"; public static final String UPDATE = "update"; public static final String SELECT = "select"; }
实现功能的DaoFactory
package com.yck.yebaitis; import com.yck.jdbc.DataUtil; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import com.yck.util.StringUtil; import com.yck.exception.NoConfigFileException; import java.io.File; import java.io.FileFilter; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.*; public class DaoFactory { private static final String configPath = "src/dao/mapper"; private static DaoFactory instance; private DaoFactory() { } public static DaoFactory getInstance() { if (instance == null) { synchronized (DaoFactory.class) { if (instance == null) instance = new DaoFactory(); } } return instance; } public Map<String, Object> getDaoMap() { Map<String, Object> map = null; try { File[] files = getAllFiles(); map = new HashMap<>(files.length); for (File file : files) { Mapper mapper = readerMapper(file); Object obj = implDao(mapper); map.put(mapper.getMapperClass(), obj); } } catch (NoConfigFileException | ClassNotFoundException | DocumentException e) { e.printStackTrace(); } return map; } private Object implDao(Mapper mapper) throws ClassNotFoundException { ClassLoader classLoader = DaoFactory.class.getClassLoader(); final Mapper temp = mapper; //加载一个接口类 Class<?> interfaze; interfaze = classLoader.loadClass(mapper.getMapperClass()); /* 代理实现方法 之前我是理解错了,我以为是在执行下面这个方法时,就已经实现了类似我们自己写一个DaoImpl,其实它就只是返回了一个代理类实例 */ return Proxy.newProxyInstance(classLoader, new Class[]{interfaze}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) { List<Function> functions = temp.getFunctions(); for (Function func : functions) { if (func.getName().equals(method.getName())) { if (func.getType().equals(FunctionConstants.SELECT)) { if (method.getReturnType().equals(List.class)) { return DataUtil.queryForList(func.getSql(), func.getResultClass(), args); } else { return DataUtil.queryForObject(func.getSql(), func.getResultClass(), args); } } else { return DataUtil.excuteUpdate(func.getSql(), args); } } } return null; } }); } private File[] getAllFiles() throws NoConfigFileException { FileFilter fileFilter = new FileFilter() { public boolean accept(File pathname) { String fileName = pathname.getName().toLowerCase(); return fileName.endsWith(".xml"); } }; File configPath = new File("src/mapper"); File[] files = configPath.listFiles(fileFilter); if (files == null || files.length == 0) { throw new NoConfigFileException("file not find"); } return files; } private Mapper readerMapper(File file) throws DocumentException, ClassNotFoundException { SAXReader reader = new SAXReader(); Mapper mapper = new Mapper(); Document doc = reader.read(file); Element root = doc.getRootElement(); //读取根节点 即dao节点 mapper.setMapperClass(root.attributeValue("class").trim()); //把dao节点的class值存为接口名 List<Function> list = new ArrayList<>(); //用来存储方法的List for (Iterator<?> rootIter = root.elementIterator(); rootIter.hasNext(); ) //遍历根节点下所有子节点 { Function fun = new Function(); //用来存储一条方法的信息 Element e = (Element) rootIter.next(); String type = e.getName().trim(); switch (type) { case FunctionConstants.ADD: fun.setType(FunctionConstants.ADD); break; case FunctionConstants.DELETE: fun.setType(FunctionConstants.DELETE); break; case FunctionConstants.UPDATE: fun.setType(FunctionConstants.UPDATE); break; case FunctionConstants.SELECT: fun.setType(FunctionConstants.SELECT); break; default: continue; } fun.setName(e.attributeValue("id").trim()); fun.setSql(e.getText().trim()); String resultType = e.attributeValue("resultType"); if (!StringUtil.isBlank(resultType)) { fun.setResultClass(Class.forName(resultType)); } list.add(fun); } mapper.setFunctions(list); return mapper; } }
测试用类
实现IUserDao的xml文件就是最底下的userdao.xml
<?xml version="1.0" encoding="UTF-8"?> <dao id="userdao" class="dao.IUserDao"> <select id="selectById" resultType ="po.User"> select * from t_user where id = ? </select> <update id="updateName"> update t_user set name = ? where id = ? </update> <delete id="deleteById"> delete from t_user where id=? </delete> <insert id="add"> insert into t_user(name,age,score,create_time,update_time) values(?,?,?,now(),now()); </insert> <select id="getAll" resultType = "po.User"> select * from t_user; </select> </dao>
测试代码
import com.yck.yebaitis.DaoFactory; import dao.IUserDao; import po.User; import java.util.List; import java.util.Map; public class Test { public static void main(String[] args) { Map<String,Object> daoMap = DaoFactory.getInstance().getDaoMap(); IUserDao dao = (IUserDao) daoMap.get("dao.IUserDao"); List<User> users = dao.getAll(); System.out.println("查询多条记录:"+users); System.out.println("*******************************************"); User user = dao.selectById(2); System.out.println("查询一条记录:"+user); System.out.println("*******************************************"); int i = dao.updateName("二傻",2); System.out.println("更新一条记录:"+i); System.out.println("*******************************************"); List<User> userList = dao.getAll(); System.out.println("更新一条记录后查询所有记录:"+user); System.out.println("*******************************************"); } }
测试结果
大王让我写代码 23:15:19
瞎j8封装第二版之用xml文件来代理dao接口的更多相关文章
- 瞎j8封装第二版之数据层的封装
看了以前写的代码,对就是下面这个 手把手封装数据层之DataUtil数据库操作的封装 觉得以前写的代码好烂啊!!!,重新理了一下思路,写得更规范和简练,应该效率也会高很多,用了一下下午写的连接池(半废 ...
- 瞎j8封装第二版之数据库连接池
写得很蛋疼,本来想支持多线程的,奈何对多线程和连接池理解着实太菜: 所以,起码是能拿到连接了... 但是还是不太懂这个连接池 我也是半抄别人的,以后再搞一搞这个吧. 先是配置文件 理想是很丰满的,奈何 ...
- 一只菜鸟的瞎J8封装系列的目录
因为这是一个系列...也就是我们所说的依赖关系.后面很多方法都是基于我前面封装的工具来进行的,所以我列一个目录供大家参考... 一只菜鸟的瞎J8封装系列 一.手把手封装数据层之DButil数据库连接 ...
- 计算器-- 利用re模块 利用函数封装 第二版
import re remove_parentheses = re.compile('\([^()]+\)') def Remove_Parentheses(obj, s): # 找到内层的括号并且返 ...
- Idea mybatis maper接口与mapper.xml文件关联 会根据接口中的方法点在mxl中生成相应sql方法
- mapper.xml是怎样实现Dao层接口
上午写了一个简单的 从xml读取信息实例化一个Bean对象.下午就开始想mybatis是怎么通过xml文件来实现dao层接口的,一开始想直接用Class.forName(String name)然后调 ...
- java Domj4读取xml文件
先概括,再以代码形式给出. 获取节点: Iterator Element.nodeIterator(); //获取当前标签节点下的所有子节点 获取 标签: Element Document.get ...
- mybatis 基础(二) xml文件中的其他知识点
mybatis xml文件中一些标签的使用 此标签主要用作 配置 "别名" 如果实体类与数据库中字段名在不区分大小写的情况下相同的话, 那就不需要配置resultMap,因为mys ...
- MyBatis(七):使用注解替代xml文件
本文是按照狂神说的教学视频学习的笔记,强力推荐,教学深入浅出一遍就懂!b站搜索狂神说或点击下面链接 https://space.bilibili.com/95256449?spm_id_from=33 ...
随机推荐
- IT连创业系列:App产品上线后,运营怎么搞?(中)
等运营篇写完,计划是想写一个IOS系列,把IT连App里用到和遇到的坑都完整的和大伙分享. 不过写IOS系列前,还是要认真把这个运营篇写完,接下来好好码字!!! 上篇说到,我们计划去一次富士康门口,拉 ...
- easyUI整合富文本编辑器KindEditor详细教程(附源码)
原因 在今年4月份的时候写过一篇关于easyui整合UEditor的文章Spring+SpringMVC+MyBatis+easyUI整合优化篇(六)easyUI与富文本编辑器UEditor整合,从那 ...
- memcached复制-repcached
1.前言 由于memcached把数据都放到内存里,因此性能是极高的,正因为如此,不可避免会造成数据丢失,repcached就派上用场了,它可以实现memcached的主从复制 2.安装repcach ...
- leetcode#42 Trapping rain water的五种解法详解
leetcode#42 Trapping rain water 这道题十分有意思,可以用很多方法做出来,每种方法的思想都值得让人细细体会. 42. Trapping Rain WaterGiven n ...
- ##7.Dashboard web管理界面-- openstack pike
##7.Dashboard web管理界面 openstack pike 安装 目录汇总 http://www.cnblogs.com/elvi/p/7613861.html ##.Dashboard ...
- 百度OCR文字识别-身份证识别
简介 一.介绍 身份证识别 API 接口文档地址:http://ai.baidu.com/docs#/OCR-API/top 接口描述 用户向服务请求识别身份证,身份证识别包括正面和背面. 请求说明 ...
- CCF-201509-3-生成模板系统
问题描述 试题编号: 201509-3 试题名称: 模板生成系统 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 成成最近在搭建一个网站,其中一些页面的部分内容来自数据库中不同 ...
- linux运维、架构之路-Zabbix监控应用及分布式
一.Zabbix监控集群应用 1.监控端口 net.tcp.listen[port] 检查 TCP 端口 是否处于侦听状态.返回 0 - 未侦听:1 - 正在侦听 net.tcp.port[<i ...
- UWP 共享文件——接收者
UWP上共享,分为接收者(别人共享数据给你,你接收了,然后在做你的处理)和发送者(你给别人发送数据,就像你的App支持图片共享到微信好友或者朋友圈那样,虽然UWP上的微信并不支持这样子) 很简单(参考 ...
- Python的控制语句
1. 控制语句 控制语句是用来改变程序执行的顺序.程序利用控制语句有条件地执行语句,循环地执行语句或者跳转到程序中的其他部分执行语句. Python支持三种不同的控制语句:if,for和while, ...