简单自定义mybatis流程!!
----简单自定义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流程!!的更多相关文章
- 搭建一个简单的mybatis框架
一.Mybatis介绍 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以 ...
- 【Mybatis】简单的mybatis增删改查模板
简单的mybatis增删改查模板: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE map ...
- 自定义 Mybatis 框架
分析流程 1. 引入dom4j <dependencies> <!--<dependency> <groupId>org.mybatis</groupI ...
- (转)sl简单自定义win窗体控件
sl简单自定义win窗体控件 相信大家接触过不少win窗体控件ChildWin子窗口就的sl自带的一个 而且网上也有很多类似的控件,而今天我和大家分享下自己制作个win窗体控件,希望对初学 ...
- 如何做个简单安卓App流程
有同学做毕业设计,问怎样做个简单安卓App流程,我是做服务端的,也算是经常接触app,想着做app应该很简单吧,不就做个页面,会跳转,有数据不就行了,我解释了半天,人家始终没听懂,算了,我第二天问了下 ...
- 【javascript】Promise/A+ 规范简单实现 异步流程控制思想
——基于es6:Promise/A+ 规范简单实现 异步流程控制思想 前言: nodejs强大的异步处理能力使得它在服务器端大放异彩,基于它的应用不断的增加,但是异步随之带来的嵌套.难以理解的代码让 ...
- SSM-MyBatis-01:IDEA的安装,永久注册和简单的MyBatis用例
一,IDEA的安装和永久注册 1.安装: 那到安装包,下一步,选路径,上面可以选操作系统64/32位,下面是程序的默认打开方式,可以不必勾选,也可以全选 路径一定不包含中文,重点 2.永久注册: 将此 ...
- Mybatis动态SQL简单了解 Mybatis简介(四)
动态SQL概况 MyBatis 的强大特性之一便是它的动态 SQL 在Java开发中经常遇到条件判断,比如: if(x>0){ //执行一些逻辑........ } Mybatis应用中,S ...
- UI设计篇·入门篇·绘制简单自定义矩形图/设置按钮按下弹起颜色变化/设置图形旋转
Android的基本控件和图形有限,难以满足所有的实际需要和设计需求,好在Android给出了相对完善的图形绘制和自定义控件的API,利用这些API,可以基本满足设计的需求. 自定义图像和控件的方法: ...
随机推荐
- redis.windows.conf配置详解
redis.windows.conf配置详解 转自:https://www.cnblogs.com/kreo/p/4423362.html # redis 配置文件示例 # 当你需要为某个配置项指定内 ...
- 关于格林尼治时间(GMT)和DateTime相互转换的分享
普及一下什么是格林尼治时间? 世界时UT即格林尼治 平太阳时间,是指格林尼治所在地的标准时间,也是表示地球自转速率的一种形式.以地球自转为基础的时间计量系统.地球自转的角度可用地方子午线相对于地球上的 ...
- SpringCloud学习笔记(5):Hystrix Dashboard可视化监控数据
简介 上篇文章中讲了使用Hystrix实现容错,除此之外,Hystrix还提供了近乎实时的监控.本文将介绍如何进行服务监控以及使用Hystrix Dashboard来让监控数据图形化. 项目介绍 sc ...
- java使用FileSystem上传文件到hadoop文件系统
import java.io.FileNotFoundException; import java.io.IOException; import java.net.URI; import org.ap ...
- CentOS在VMware中的安装
1.启动VMware 2.新建一台虚拟机,选择典型 3.选择稍后安装操作系统 4.选择引导系统为Linux,系统版本为Centos 5.选择安装位置 6.选择最大磁盘容量 7.点击自定义硬件,进行硬件 ...
- Java第二次作业第一题
编写图形界面程序,在窗体中设置菜单栏,在菜单栏上添加"file"菜单,在文件菜单中添加"new"和"quit"两个菜单项,其中"q ...
- spring中基于注解使用ehcache
继续上篇,这篇介绍服务层缓存,基于注解的方式使用ehcache 注解的标签主要有4个:@Cacheable.@CacheEvict.@CachePut.@Caching,他们的用法是: @Cachea ...
- 【linux】linux固定ip
vi /etc/sysconfig/network-scripts/ifcfg-ens33 ifcfg-ens33为ifconfig显示的网卡名 TYPE="Ethernet"P ...
- vue报错:[Vue warn]: Do not use built-in or reserved HTML elements as component id: header
报错的信息大致是不要将内置或保留的HTML元素用作组件ID 解决的办法是修改name符合规范或者直接删除组件内的name属性.
- 将maven项目导入到eclipse中
一,前言 本文来演示一下如何将一个新的maven项目到入到eclipse中. 在文章使用命令行创建maven web项目中我们使用maven命令行,创建了web工程,接下来为了开发方便我要将新建的工程 ...