模拟实现MyBatis中通过SQL反射实体类对象功能
话不多说,直接上干货!
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反射实体类对象功能的更多相关文章
- mybatis中映射文件和实体类的关联性
mybatis的映射文件写法多种多样,不同的写法和用法,在实际开发过程中所消耗的开发时间.维护时间有很大差别,今天我就把我认为比较简单的一种映射文件写法记录下来,供大家修改建议,争取找到一个最优写法~ ...
- java中的几种实体类对象(PO,VO,DAO,BO,POJO)
一.PO :(persistant object ),持久对象 可以看成是与数据库中的表相映射的java对象.使用Hibernate来生成PO是不错的选择. 二.VO :(value object) ...
- NSDictionary转化为实体类对象
方法一: 使用objective-c NSObject自带的方法 setValuesForKeysWithDictionary:dict 作用是: 如果NSDictionary中的key和实体类对象的 ...
- java 获取实体类对象属性值的方法
在java中我们要获得实体类对象的属性,一般情况是将实体类中的属性私有化,然后再对外提供get()与set()方法,然后再获取实体类对象的属性的时候先把对象new出来,再用变量名.get()的方法得到 ...
- mybatis高级(2)_数据库中的列和实体类不匹配时的两种解决方法_模糊查询_智能标签
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "- ...
- Mybatis中动态SQL多条件查询
Mybatis中动态SQL多条件查询 mybatis中用于实现动态SQL的元素有: if:用if实现条件的选择,用于定义where的字句的条件. choose(when otherwise)相当于Ja ...
- MyBatis中动态SQL语句完成多条件查询
一看这标题,我都感觉到是mybatis在动态SQL语句中的多条件查询是多么的强大,不仅让我们用SQL语句完成了对数据库的操作:还通过一些条件选择语句让我们SQL的多条件.动态查询更加容易.简洁.直观. ...
- 控制台输出 mybatis 中的sql语句
控制台输出 mybatis 中的sql语句 在 log4j.xml 文件中 增加如下配置 <!-- mybatis 输出的sql,DEBUG级别 --> <logger name=& ...
- MyBatis中动态SQL元素的使用
掌握MyBatis中动态SQL元素的使用 if choose(when,otherwise) trim where set foreach <SQL>和<include> 在应 ...
随机推荐
- virtualbox 安装 mac os x lion 10.7实现全屏显示!
1. 启动Virtual Box虚拟机,在虚拟机里编辑 /Library/Preferences/SystemConfiguration/com.apple.Boot.plist,找到 <dic ...
- tp3.2中的 I () 方法
I('get.id'); // 相当于 $_GET['id']
- viewsate用法
ViewState["名称"]="ssss";直接赋值取值只能在同一个页面使用, 离开页面就会失效
- Junit报错Initialization Error
出错原因是没有把方法声明为public
- Linux下rm -rf删除文件夹报错_ Device or resource busy
1.错误信息 rm: cannot remove `speechd-centos_6.2-prtl-pred-mf34/modules/t2p/py/third/g2p/.nfs00000000039 ...
- PAT——1007. 素数对猜想
让我们定义 dn 为:dn = pn+1 - pn,其中 pi 是第i个素数.显然有 d1=1 且对于n>1有 dn 是偶数.“素数对猜想”认为“存在无穷多对相邻且差为2的素数”. 现给定任意正 ...
- android中OpenMax的实现【3】OMX中主要成员
原文 http://blog.csdn.net/tx3344/article/details/8117908 通过上文知道了,每个AwesomePlayer 只有一个OMX服务的入口,但是Awesom ...
- TCP-IP and Advanced Topics 课程总结与报告
课程总结 学习了四周十六课的课程,对每一课的知识点进行总结梳理,作出一个树状的知识网络图. 本课程虽然在深度上有所欠缺,但却更有利于结构上的梳理,加深总体上对网络的理解. 本课程从Internet出发 ...
- 通用输入输出端口 - GPIO
一.概述 GPlO ( General Purpose I/0 Ports )意思为通用输入/输出端口, 通俗地说, 就是一些引脚.在芯片手册中I/O端口一般是分组的,比如有的芯片分为 A-J 共 9 ...
- python多线程知识-实用实例
python多线程使用场景:IO操作,不适合CPU密集操作型任务 1.多个线程内存共享 2.线程同时修改同一份数据需要加锁,mutex互斥锁 3.递归锁:多把锁,锁中有锁 4.python多线程, ...