----简单自定义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. SpringBoot 2.0 + 阿里巴巴 Sentinel 动态限流实战

    前言 在从0到1构建分布式秒杀系统和打造十万博文系统中,限流是不可缺少的一个环节,在系统能承受的范围内既能减少资源开销又能防御恶意攻击. 在前面的文章中,我们使用了开源工具包 Guava 提供的限流工 ...

  2. mysql数据库事务隔离原理

    今天在学习JDBC的时候看到了关于MySQL的事务的隔离级别的问题,感觉内容挺高级的,所以记录一篇文章,以备后面使用. 数据库隔离级别有四种,应用<高性能mysql>一书中的说明: 然后说 ...

  3. out.print()与response.sendRedirect()

    这样的情况下 out.print("<script>alert('非法操作,请重新登录!');</script>"); response.sendRedir ...

  4. Java面试-容器的遍历

    当我们用增强for循环遍历非并发容器(HashMap.ArrayList等),如果修改其结构,会抛出异常ConcurrentModificationException,因此在阿里巴巴的Java规范中有 ...

  5. 使用Bookinfo应用测试Kuma服务网格

    最近,开源API管理平台Kong服务供应商近日放出了新的开源项目Kuma.本文尝试将 bookinfo 应用部署在 Kuma 网格中,以便帮助大家更好的理解 Kuma 项目.   Kuma是能用于管理 ...

  6. 重学js之JavaScript 面向对象的程序设计(创建对象)

    注意: 本文章为 <重学js之JavaScript高级程序设计>系列第五章[JavaScript引用类型]. 关于<重学js之JavaScript高级程序设计>是重新回顾js基 ...

  7. Day 14 查找文件 find

    find 查找方式 1.按照名称进行查找 [root@oldboyedu ~]# find ./ -name "*eth0" 2.按照名称查找(不区分大小写) [root@oldb ...

  8. 用Python怎么SSH到网络设备

    0. 前言 自上一篇文章<用python怎么telnet到网络设备>,简单使用了telnetlib库给大家演示了下,但是,现实环境中仍不建议去使用telnet. SSH(Secure Sh ...

  9. redis分布式锁-基本概念与实现方式对比

    1.redis中使用WATCH实现锁机制,是最次之的方式.WATCH只会在数据被其他客户端抢先修改了的情况下,“通知”执行了这个命令的客户端,而不会阻止其他客户端对数据进行修改.此类锁成为“乐观锁” ...

  10. Linux 安装CentOS7操作系统

    作者:小啊博 QQ:762641008 转载请声明:https://www.cnblogs.com/-bobo 1.安装操作系统 开启虚拟机后会出现以下界面 Install CentOS 7 安装Ce ...