话不多说,直接上干货!

package cn.test;

import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Timestamp; import org.junit.Test; import cn.core.domain.User; public class UseMyBatis { /**
* 模拟MyBites根据sql动态创建对象.
* @throws Exception
*/
@Test
public void simulation() throws Exception{
//className应该是传参或者是读取配置文件读出来的一个指定类型,这里为了测试直接先写死了。
String className="cn.core.domain.User";
//加载驱动,下面是jdbc的一段代码
Class.forName("com.mysql.jdbc.Driver");
Connection conn=DriverManager.getConnection("jdbc:mysql://192.168.1.68/base", "root", "root");
String sql="select * from base_user where user_id=?";
PreparedStatement ps=conn.prepareStatement(sql);
ps.setString(1, "00a8ea6b8b524205bc0af1c3249abe54");
ResultSet rs=ps.executeQuery();
//循环获取每行数据
while (rs.next()) {
//每一行就表示一个对象,通过反射将实体类创建出来
Object object=Class.forName(className).newInstance();
//通过ResultSetMetaData这个对象获取查询语句的原始列名,列总数以及列的类型
ResultSetMetaData data=rs.getMetaData();
//获取列总数
int count=data.getColumnCount();
//循环得到列名和列类型
for (int i = 1; i <= count; i++) {
String column=data.getColumnName(i);//获取列名
String typeName=data.getColumnTypeName(i);//获取列类型
String setMethodName=bulidSetMethod(column);//获取具体实体类中的set方法名
//根据列类型去获取列数据,具体参考数据库的类型将和rs.getXXX对应上去取值即可
if("VARCHAR".equals(typeName)){
String value=rs.getString(column);//取值
//通过方法名进行反射得到具体的方法对象
Method method=object.getClass().getMethod(setMethodName,String.class);
//执行这个方法并对应的字段去赋值
method.invoke(object, value);
}else if("DATETIME".equals(typeName)){//操作同上,只不过类型换成了时间类型
Timestamp value=rs.getTimestamp(column);
Method method=object.getClass().getMethod(setMethodName,Timestamp.class);
method.invoke(object, value);
}
//将数据库的类型都列出来,剩余的和上述差不多就不一一写出来了....
}
//下面这块就到了我们实际运用的过程了 这块可以根据业务需要 返回会单个object或者是list
User user=(User)object;
System.out.println(user);
} } /**
* 将列名转换成对应的set方法名.
* @param columnName 列名
* @return set方法名
*/
public String bulidSetMethod(String columnName){
String c1="set";
String c2=columnName.substring(0,1).toUpperCase();
String c3=columnName.substring(1);
return c1+c2+c3;
} }

OK,java中所有的持久化框架底层全是jdbc去实现的,那么通过jdbc模拟一个MyBites主要是通过java反射的机制去实现的,通过反射sql的列名得到具体的set方法名,通过执行set方法给字段注入具体的值,所以框架本身并不难,只要想通了其中的点,其实实现起来也就几行代码而已。

模拟实现MyBatis中通过SQL反射实体类对象功能的更多相关文章

  1. mybatis中映射文件和实体类的关联性

    mybatis的映射文件写法多种多样,不同的写法和用法,在实际开发过程中所消耗的开发时间.维护时间有很大差别,今天我就把我认为比较简单的一种映射文件写法记录下来,供大家修改建议,争取找到一个最优写法~ ...

  2. java中的几种实体类对象(PO,VO,DAO,BO,POJO)

    一.PO :(persistant object ),持久对象 可以看成是与数据库中的表相映射的java对象.使用Hibernate来生成PO是不错的选择. 二.VO :(value object) ...

  3. NSDictionary转化为实体类对象

    方法一: 使用objective-c NSObject自带的方法 setValuesForKeysWithDictionary:dict 作用是: 如果NSDictionary中的key和实体类对象的 ...

  4. java 获取实体类对象属性值的方法

    在java中我们要获得实体类对象的属性,一般情况是将实体类中的属性私有化,然后再对外提供get()与set()方法,然后再获取实体类对象的属性的时候先把对象new出来,再用变量名.get()的方法得到 ...

  5. mybatis高级(2)_数据库中的列和实体类不匹配时的两种解决方法_模糊查询_智能标签

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "- ...

  6. Mybatis中动态SQL多条件查询

    Mybatis中动态SQL多条件查询 mybatis中用于实现动态SQL的元素有: if:用if实现条件的选择,用于定义where的字句的条件. choose(when otherwise)相当于Ja ...

  7. MyBatis中动态SQL语句完成多条件查询

    一看这标题,我都感觉到是mybatis在动态SQL语句中的多条件查询是多么的强大,不仅让我们用SQL语句完成了对数据库的操作:还通过一些条件选择语句让我们SQL的多条件.动态查询更加容易.简洁.直观. ...

  8. 控制台输出 mybatis 中的sql语句

    控制台输出 mybatis 中的sql语句 在 log4j.xml 文件中 增加如下配置 <!-- mybatis 输出的sql,DEBUG级别 --> <logger name=& ...

  9. MyBatis中动态SQL元素的使用

    掌握MyBatis中动态SQL元素的使用 if choose(when,otherwise) trim where set foreach <SQL>和<include> 在应 ...

随机推荐

  1. C/C++心得-从内存开始

    因工作与自身各方面需要,开始重新学C,其实说重新也不太准,原来只是大学里面接触过,且还未得多少精髓就转其他开发,不过也正是因此才有了重新学习的必要,基础部分的心得将通过博文记录下来,对于初学者应该有些 ...

  2. MySQL数据库----------小知识点

    **********************补2016年5月23日的博客************************* MySQL数据库 常用数据类型: int                整数 ...

  3. log4net快速使用流程

    以下内容大部分来自这里,对原作者流子表示感谢 1.Nuget安装,当前版本2.0.8 2.创建log4net.config文件,文件内容如下: <?xml version="1.0&q ...

  4. 解决iOS项目根目录下文件乱七八糟的问题

    对于一个刚做项目的新手来说,肯定会碰到一个相当蛋疼的问题,那就是你在项目中建立的文件夹与你在根目录下的文件夹完全对应不起来,说直接点就是你通过group的方式在项目中建立的文件夹在本目录下根本就没有. ...

  5. CSU - 2059 Water Problem(Z线分割平面)

    一条‘Z’形线可以将平面分为两个区域,那么由N条Z形线所定义的区域的最大个数是多少呢?每条Z形线由两条平行的无限半直线和一条直线段组成 Input 首先输入一个数字T(T<100),代表有T次询 ...

  6. TCP Flow Control and Data Transfer

    TCP Flow Control TCP Data Transfer Selective Repeat ARQ with Positive ACK Window slides a byte basis ...

  7. Keil开发的ARM程序main函数之前的汇编分析

    Keil开发的ARM程序main函数之前的汇编分析 ——BIN文件中RW段的数据移动 系统平台: STM32系列STM32F103ZE,512KB内部FLASH,64KB片内存储; FLASH地址范围 ...

  8. 在EF Core里面如何使用以前EntityFramework的DbContext.Database.SqlQuery<SomeModel>自定义查询

    问: With Entity Framework Core removing dbData.Database.SqlQuery<SomeModel> I can't find a solu ...

  9. 全渠道价值链整合云服务 B2B SOLOMO(组图)

    最近看到>中谈到“全渠道零售”(Omni-channel Retailing),指在互联网和电子商务的当今时代“零售商将能通过各种渠道与顾客互动,包括网站.实体店.服务终端.直邮和目录.呼叫中心 ...

  10. Web项目开发中常见安全问题及防范

    计算机程序主要就是输入数据 经过处理之后 输出结果,安全问题由此产生,凡是有输入的地方都可能带来安全风险.根据输入的数据类型,Web应用主要有数值型.字符型.文件型. 要消除风险就要对输入的数据进行检 ...