瞎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 ...
随机推荐
- MongoDB中的MapReduce介绍与使用
一.简介 在用MongoDB查询返回的数据量很大的情况下,做一些比较复杂的统计和聚合操作做花费的时间很长的时候,可以用MongoDB中的MapReduce进行实现 MapReduce是个非常灵活和强大 ...
- react入门到进阶(二)
一.react属性与事件 1.State属性 State,翻译过来是状态的意思,所以它就代表着组件的状态.React把用户界面(UI)当做是状态机,想象它有不同的状态然后渲染这些状态,可以轻松让用户界 ...
- 3721:和数-poj
总时间限制: 1000ms 内存限制: 65536kB 描述 给定一个正整数序列,判断其中有多少个数,等于数列中其他两个数的和. 比如,对于数列1 2 3 4, 这个问题的答案就是2, 因为3 = ...
- Ipad弹出UIAlertControllerStyleActionSheet时发生崩溃
pad弹出UIAlertControllerStyleActionSheet时,在iphone上运行正常,但在ipad上崩溃,解决代码如下: UIAlertController *alertVc = ...
- Spring Cloud 之 Ribbon
新建Spring Boot工程,命名为ribbon 1.pom.xml添加依赖 <?xml version="1.0" encoding="UTF-8"? ...
- WPF自定义产品框架
在讲解之前先看一下效果,有助于理解: 这是客户端的效果图.整个产品分为两部分:1.WPF开发的展示效果的客户端 2.WCF开发的提供数据服务接口的服务端 本章主要讲解一下实际中开发WPF开发客 ...
- 批量去BOM头 遍历目录及子文件,文件夹 PHP源码
任意php文件,把最后一行替换成自己的目录 即可 <?php class KillBom { public static $m_Ext = ['txt', 'php', 'js', 'c ...
- input required
HTML <input> required 属性 HTML <input> 标签 实例 带有必填字段的 HTML 表单: <form action="demo ...
- 基于 HTML5 Canvas 的 3D 压力器反序列化
在实际应用中,我觉得能够通过操作 JSON 文件来操作 3D 上的场景变化是非常方便的一件事,尤其是在做编辑器进行拖拽图元并且在图元上产生的一系列变化的时候,都能将数据很直观地反应给我们,这边我们简单 ...
- Android测试:Fundamentals of Testing
原文地址:https://developer.android.com/training/testing/fundamentals.html 用户在不同的级别上与你的应用产生交互.从按下按钮到将信息下载 ...