----简单自定义mybatis流程----
一.首先封装daoMapperxml文件和sqlMapconfig配置文件,如何封装:
(1).封装我们的Mapper.xml文件,提取名称空间namespace,提取方法名id,提取我们的结果类型resultType,再提取我们的sql语句sqlStatement创建实例对象封装.
(2).封装我们的sqlMapconfig.xml操作数据库的配置文件,提取数据源datasource(c3p0,德鲁伊...),再提取连接数据库四个步骤:driver驱动,地址URL,用户名username和密码password,还有最后一个接口映射文件信息,由于实际开发中会有多个,所以可以使用一个Map集合来定义Map<String,Mapper>datasource,接着创建实例封装.
二.解析xml文件,这里使用dom4j解析,然后创建我们的数据源对象:
(1).解析sqlMapconfig.xml文件
//这边使用无参构造方法来解析xml文件和加载数据源datasource!
public Configuration(){
loadXpathSqlMapConfig();
creatDatasource();

}

/**
* 解析数据库配置文件
*/
public void loadXpathSqlMapConfig(){
try {
//通过类加载器加载配置文件
InputStream resource = this.getClass().getClassLoader().getResourceAsStream("SqlMapConfig.xml");
//采用dom4j解析xml配置文件
SAXReader saxReader = new SAXReader();
Document read = saxReader.read(resource);
Element rootElement = read.getRootElement();
//System.out.println(rootElement);
List<Element> nodesList = rootElement.selectNodes("//property");//语法要求要加"//"
for (Element element : nodesList) {
String name = element.attributeValue("name");
String value = element.attributeValue("value");
if ("driver".equals(name)){
driver=value;
}
if ("url".equals(name)){
url=value;
}
if ("username".equals(name)){
username=value;
}
if ("password".equals(name)){
password=value;
}
}
List<Element> list = rootElement.selectNodes("//mapper");
for (Element element : list) {
String xpath = element.attributeValue("resource");
loadMapperXml(xpath);

} catch (Exception e) {
e.printStackTrace();
}

}

/**
* 创建数据源对象设置连接数据库参数
*
*/
public void creatDatasource(){

try {
//创建数据源对象
dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);

} catch (Exception e) {
e.printStackTrace();
}

}
(2).解析interfaceMapperXml文件.封装到我们的Mapper中!
/**
* 解析interfaceMapperXml文件
* @param xpath
*/
public void loadMapperXml(String xpath) {
mappers = new HashMap<>();
try {
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(xpath);
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(inputStream);
Element rootElement = document.getRootElement();
String namespace = rootElement.attributeValue("namespace");
List<Element> elements = rootElement.elements();
Mapper mapper = new Mapper();
for (Element element : elements) {
String id = element.attributeValue("id");
String resultType = element.attributeValue("resultType");
String sqlStatement = element.getText();
mapper.setId(id);
mapper.setNamespace(namespace);
mapper.setResultType(resultType);
mapper.setSqlStatement(sqlStatement);
String key=namespace+"."+id;
mappers.put(key,mapper);
}
} catch (Exception e) {
e.printStackTrace();
}
}
三.创建核心对象SqlSession对象,旧版Mybatis前常用SqlSession对象中的增删查改方法,现在新版Myatis常用getMapper方法,面向接口的编程方式,需要接口名与mapper的命名空间属性值保持一致,从而将接口与mapper文件对应起来。当namespace绑定某一接口之后,可以不用写该接口的实现类,MyBatis会通过接口的完整限定名查找到对应的mapper配置来执行SQL语句.里边使用了动态代理技术.
public class SqlSession {

public <T> T getMapper(Class<T> type){
T proxy= (T) Proxy.newProxyInstance(
this.getClass().getClassLoader(),
new Class[]{type},
new MapperProxy()

);

return proxy;
}
}

public class MapperProxy implements InvocationHandler {

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//加载映射文件和配置文件
Configuration configuration = new Configuration();
//数据源
ComboPooledDataSource dataSource = configuration.getDataSource();
//执行的sql语句
Map<String, Mapper> mappers = configuration.getMappers();
String methodName = method.getName();
String className = method.getDeclaringClass().getName();

String key=className+"."+methodName;
System.out.println(key);
Mapper mapper = mappers.get(key);

return Executor.findAll(mapper,dataSource.getConnection());
}
}
四.创建我们的SqlSessionFactory会话工厂对象,通过里面的openSession()方法打开(得到)我们的核心Sqlsession会话对象;
* @Description: 会话工厂对象对象,此对象提供一个openSession()方法
*/
public class SqlSessionFactory {

public static SqlSession openSession(){
return new SqlSession();
}
}
五.创建Executor工具类 执行数据库操作并且封装结果集返回:
public class Executor {

public static <T> List<T> findAll(Mapper mapper, Connection connection){

List<T> resultList =new ArrayList<T>();
PreparedStatement preparedStatement=null;
ResultSet resultSet=null;
try {
//获取到sql语句
String sqlStatement = mapper.getSqlStatement();
//获取返回值类型
String resultType = mapper.getResultType();
//转成字节码对象
Class<?> aClass = Class.forName(resultType);
preparedStatement = connection.prepareStatement(sqlStatement);
//执行完返回resultSet 封装结果集
resultSet = preparedStatement.executeQuery();
handleResult(resultList,aClass,resultSet);
} catch (Exception e) {
e.printStackTrace();
}finally {
close(connection,preparedStatement,resultSet);
}

return resultList;

}

/**
* 处理结果集方法
* @param resultList
* @param aClass
* @param resultSet
*/
private static void handleResult(List resultList, Class<?> aClass, ResultSet resultSet) {
try {
//首先获取到元数据
ResultSetMetaData metaData = resultSet.getMetaData();
//获取元数据字段数量
int columnCount = metaData.getColumnCount();

//获取字段名称,因为多个,所以使用数组保存
String[] columnNames= new String[columnCount];
for (int i = 1; i <= columnNames.length; i++) {
columnNames[i-1]= metaData.getColumnName(i);
}
//循环取数据
while (resultSet.next()){
//通过反射技术给成员变量赋值
Object o = aClass.newInstance();//这个对象表示是User对象
//便利字段名称数组
for (int i = 0; i < columnNames.length; i++) {
//resultSet.getObject():获取此的当前行中指定列的值
Object object = resultSet.getObject(columnNames[i]);

Field field = aClass.getDeclaredField(columnNames[i]);
field.setAccessible(true);
field.set(o,object);
}
resultList.add(o) ;
}

} catch (Exception e) {
e.printStackTrace();
}

}

/**
* 释放资源
* @param connection
* @param preparedStatement
* @param resultSet
*/
private static void close(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet) {
try {
if (connection!=null) connection.close();
if (preparedStatement!=null) preparedStatement.close();
if (resultSet!=null) resultSet.close();
} catch (Exception e) {
e.printStackTrace();
}
}

}

六.测试:
public class MybatisTest {

public static void main(String[] args) {

//测试
SqlSession sqlSession = SqlSessionFactory.openSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> userList = mapper.findAll();
for (User user : userList) {
System.out.println(user);
}
}
}
输出测试数据如下:

简单自定义mybatis流程!!的更多相关文章

  1. 搭建一个简单的mybatis框架

    一.Mybatis介绍 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以 ...

  2. 【Mybatis】简单的mybatis增删改查模板

    简单的mybatis增删改查模板: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE map ...

  3. 自定义 Mybatis 框架

    分析流程 1. 引入dom4j <dependencies> <!--<dependency> <groupId>org.mybatis</groupI ...

  4. (转)sl简单自定义win窗体控件

    sl简单自定义win窗体控件      相信大家接触过不少win窗体控件ChildWin子窗口就的sl自带的一个  而且网上也有很多类似的控件,而今天我和大家分享下自己制作个win窗体控件,希望对初学 ...

  5. 如何做个简单安卓App流程

    有同学做毕业设计,问怎样做个简单安卓App流程,我是做服务端的,也算是经常接触app,想着做app应该很简单吧,不就做个页面,会跳转,有数据不就行了,我解释了半天,人家始终没听懂,算了,我第二天问了下 ...

  6. 【javascript】Promise/A+ 规范简单实现 异步流程控制思想

    ——基于es6:Promise/A+ 规范简单实现 异步流程控制思想  前言: nodejs强大的异步处理能力使得它在服务器端大放异彩,基于它的应用不断的增加,但是异步随之带来的嵌套.难以理解的代码让 ...

  7. SSM-MyBatis-01:IDEA的安装,永久注册和简单的MyBatis用例

    一,IDEA的安装和永久注册 1.安装: 那到安装包,下一步,选路径,上面可以选操作系统64/32位,下面是程序的默认打开方式,可以不必勾选,也可以全选 路径一定不包含中文,重点 2.永久注册: 将此 ...

  8. Mybatis动态SQL简单了解 Mybatis简介(四)

    动态SQL概况 MyBatis 的强大特性之一便是它的动态 SQL 在Java开发中经常遇到条件判断,比如: if(x>0){ //执行一些逻辑........ }   Mybatis应用中,S ...

  9. UI设计篇·入门篇·绘制简单自定义矩形图/设置按钮按下弹起颜色变化/设置图形旋转

    Android的基本控件和图形有限,难以满足所有的实际需要和设计需求,好在Android给出了相对完善的图形绘制和自定义控件的API,利用这些API,可以基本满足设计的需求. 自定义图像和控件的方法: ...

随机推荐

  1. JSP学习笔记(6)—— 自定义MVC框架

    仿照SpringMVC,实现一个轻量级MVC框架,知识涉及到了反射机制.注解的使用和一些第三方工具包的使用 思路 主要的总体流程如下图所示 和之前一样,我们定义了一个DispatchServlet,用 ...

  2. 阿里yum源与华为yum源的配置

    如何使用华为云提供的CentOS镜像源(x86_64)?   更新时间:  2019/08/16 11:17 查看PDF                 分享 微博 分享文档到微博 微信 扫码分享文档 ...

  3. d010:盈数、亏数和完全数

    题目: 对一个正整数N而言,将它除了本身以外所有的因子加起来的总和为S,如果S>N,则N为盈数,如果S<N,则N为亏数,而如果S=N,则N为完全数(Perfect Number).例如10 ...

  4. charles 重写工具/rewrite Srttings

    本文参考:charles 重写工具 rewrite Srttings 重写工具/rewrite Srttings and rewrite rule 功能:在通过charles时修改请求和响应 重写工具 ...

  5. .Net Standard(.Net Core)实现获取配置信息

    一.前言 在.Net Framework框架有专门获取webconfig配置的方法供我们使用,但是在.Net Core或者.Net Standard中没有可以直接使用的方法来获取配置文件信息,下面就来 ...

  6. 我用数据结构花了一夜给女朋友写了个h5走迷宫小游戏

    目录 起因 分析 画线(棋盘) 画迷宫 方块移动 结语 @(文章目录) 先看效果图(在线电脑尝试地址http://biggsai.com/maze.html): 起因 又到深夜了,我按照以往在公众号写 ...

  7. [Pandas] 04 - Efficient I/O

    SQLITE3接口 调动 SQLITE3数据库 import sqlite3 as sq3 query = 'CREATE TABLE numbs (Date date, No1 real, No2 ...

  8. JavaScript之深入对象(二)

    上一篇随笔讲解了构造函数.原型及原型链相关的知识,今天让我们一起来探讨另一个问题:this. 一     this 的指向 1,  函数预编译过程中,this指向window 我们在讲解函数预编译过程 ...

  9. Spring 梳理-数据访问-DB

    针对接口编程 DAO是指数据访问对象(data access object),它提供了数据读取和写入到数据库中的一种方式.Spring认为,它应该以接口的方式发布功能,而应用程序的其他部分需要通过接口 ...

  10. windows核心编程 第5章job lab示例程序 解决小技巧

    看到windows核心编程 第5章的最后一节,发现job lab例子程序不能在我的系统(win8下)正常运行,总是提示“进程在一个作业里”         用process explorer程序查看 ...