简单的mybatis框架实现

以查询部门表为例

      部门表sql语句

/*
Navicat MySQL Data Transfer

Source Server         : a
Source Server Version : 50027
Source Host           : localhost:3306
Source Database       : erp

Target Server Type    : MYSQL
Target Server Version : 50027
File Encoding         : 65001

Date: 2017-12-24 12:04:04
*/

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `deptment`
-- ----------------------------
DROP TABLE IF EXISTS `deptment`;
CREATE TABLE `deptment` (
  `deptId` int(11) NOT NULL auto_increment,
  `deptName` varchar(50) NOT NULL,
  `discrbe` varchar(200) default NULL,
  PRIMARY KEY  (`deptId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of deptment
-- ----------------------------
INSERT INTO deptment VALUES ('1', '技术部', '湖南');
INSERT INTO deptment VALUES ('3', '行政部', '湖南衡阳');
INSERT INTO deptment VALUES ('4', '市场部', '湖南');

-- ----------------------------
-- Table structure for `employee`
-- ----------------------------
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee` (
  `eid` int(11) NOT NULL auto_increment,
  `ename` varchar(50) NOT NULL,
  `esex` char(2) default NULL,
  `ebirthday` date default NULL,
  `ejiondate` date default NULL,
  `username` varchar(50) NOT NULL,
  `pwd` varchar(50) NOT NULL,
  `deptid` int(11) NOT NULL,
  `eno` varchar(50) NOT NULL,
  PRIMARY KEY  (`eid`),
  KEY `deptid` (`deptid`),
  CONSTRAINT `deptid` FOREIGN KEY (`deptid`) REFERENCES `deptment` (`deptId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of employee
-- ----------------------------
INSERT INTO employee VALUES ('1', 'zhangsan', '女', '2017-12-24', '2017-12-24', 'zhangsan', 'aaaaa', '1', 'YC1002');
INSERT INTO employee VALUES ('2', 'lisi', '男', '2017-12-24', '2017-12-24', 'lisi', 'aaaaa', '1', 'YC1003');
INSERT INTO employee VALUES ('3', 'lydia', '女', '2017-12-24', '2017-12-24', 'lydia', 'aaaaa', '1', 'YC1001');

      思路  

1.调用dbHelper中的方法 


自定义Mybatis:
MybatisConfig:解析配置文件  
	数据源配置信息:
		url
		driver
		username
		password
		DataSource 数据源对象存储配置信息  
	映射文件  :  XXMapper.xml  
		List<String>  mappers;
SqlSessionFactory
	解析XXMapper.xml  文件 
		id
		resultType
		paramtertype
		sql
		MapperInfo 存储每个映射语句   ---》Map  
SqlSession  
	getDataSource() -->DbHelper--->设置  getConn( )
	selectOne()
		dbHelper.find()
	selectList() 
	

所需建的包和文件   

                          

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>

<config>
	<dataSource>
		<property name="driver" value="com.mysql.jdbc.Driver"></property>
		<property name="url" value="jdbc:mysql://localhost:3306/mybatis2"></property>
		<property name="username" value="root"></property>
		<property name="password" value="admin"></property>
	</dataSource>	
  	<mappers>
  		<mapper resource="cn/itcast/dao/Deptment.xml"></mapper>
  	</mappers>
</config>

Deptment.xml

<!-- namespace:命名空间,用于隔离sql,还有一个很重要的作用,后面会讲 -->
<!-- sql语句 -->
<mapper>
		<select id="get" resultType="cn.itcast.bean.DeptmentBean">
	   	 	select * from deptment
	  </select>
  </mapper>

 DeptmentBean.java

package cn.itcast.bean;

import java.io.Serializable;
import java.util.List;

public class DeptmentBean implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Integer deptId;
	private String deptName;
	private String discrbe;
	
	
	
	
	public DeptmentBean() {
	
	}
	public DeptmentBean(Integer deptId, String deptName, String discrbe) {
		
		this.deptId = deptId;
		this.deptName = deptName;
		this.discrbe = discrbe;
	}

	public Integer getDeptId() {
		return deptId;
	}
	public void setDeptId(Integer deptId) {
		this.deptId = deptId;
	}
	public String getDeptName() {
		return deptName;
	}
	public void setDeptName(String deptName) {
		this.deptName = deptName;
	}
	public String getDiscrbe() {
		return discrbe;
	}
	public void setDiscrbe(String discrbe) {
		this.discrbe = discrbe;
	}
	@Override
	public String toString() {
		return "DeptmentBean [deptId=" + deptId + ", deptName=" + deptName + ", discrbe=" + discrbe + "]";
	}
	
	
}

DataSource.java

package cn.itcast.mybatis;

public class DataSource {
	private String url;
	private String driverClassName;
	private String user;
	private String password;
	
	public String getUrl() {
		return url;
	}
	public void setUrl(String url) {
		this.url = url;
	}
	public String getDriverClassName() {
		return driverClassName;
	}
	public void setDriverClassName(String driverClassName) {
		this.driverClassName = driverClassName;
	}
	public String getUser() {
		return user;
	}
	public void setUser(String user) {
		this.user = user;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
	
}

 DBHelper.java

package cn.itcast.mybatis;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class DBHelper {
	
	private DataSource dataSource;
	
	public DBHelper(DataSource dataSource){
		this.dataSource = dataSource;
		try {
			Class.forName(dataSource.getDriverClassName());
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	static{
//		try {
//			Class.forName(ReaderPro.getReaderPro().getProperty("driverClassName"));
//		} catch (ClassNotFoundException e) {
//			e.printStackTrace();
//		}
	}
	
	/**
	 * 获取连接的方法
	 * @return
	 */
	private Connection getConnection(){
		Connection cn =  null;
		try {
			//cn = DriverManager.getConnection(ReaderPro.getReaderPro().getProperty("url"),ReaderPro.getReaderPro());
			cn = DriverManager.getConnection(dataSource.getUrl(), dataSource.getUser(), dataSource.getPassword());
			//cn = DriverManager.getConnection("", dataSource.getUser(), dataSource.getPassword());
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return cn;
	}
	
	/**
	 * 给预编译语句中的占位符赋值
	 * @param pstmt 要赋值的预编译语句块
	 * @param params 对应的占位符?的值
	 */
	private void setParams(PreparedStatement pstmt,Object ... params){
		//给预编译执行语句中的占位符赋值
		if(params!=null && params.length>0){ //说明要执行的sql语句中有占位符?
			for(int i=0,len=params.length;i<len;i++){
				try {
					pstmt.setObject(i+1,params[i]);
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 给预编译语句中的占位符赋值
	 * @param pstmt 要赋值的预编译语句块
	 * @param params 对应的占位符?的值
	 */
	private void setParams(PreparedStatement pstmt,List<Object> params){
		//给预编译执行语句中的占位符赋值
		if(params!=null && params.size()>0){ //说明要执行的sql语句中有占位符?
			for(int i=0,len=params.size();i<len;i++){
				try {
					pstmt.setObject(i+1,params.get(i));
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	
	/**
	 * 给预编译语句中的占位符赋值
	 * @param pstmt 要赋值的预编译语句块
	 * @param params 对应的占位符?的值
	 */
	private void setParams(PreparedStatement pstmt,String ... params){
		//给预编译执行语句中的占位符赋值
		if(params!=null && params.length>0){ //说明要执行的sql语句中有占位符?
			for(int i=0,len=params.length;i<len;i++){
				try {
					pstmt.setString(i+1,params[i]);
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 关闭资源的方法
	 * @param rs 要关闭的结果集
	 * @param pstmt 要关闭的预编译语句
	 * @param con 要关闭的连接
	 */
	private void closeAll(ResultSet rs,PreparedStatement pstmt,Connection con){
		if(rs!=null){
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if(pstmt!=null){
			try {
				pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if(con!=null){
			try {
				con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 执行更新操作
	 * @param sql 要执行更新的sql语句(insert、delete、update)
	 * @param params 要执行的更新语句中占位符?的值,给定的顺序必须跟?的顺序一致
	 * @return 更新语句执行后,所影响的数据的行数
	 */
	public int update(String sql,String ... params){
		Connection con=null;
		PreparedStatement pstmt=null;
		int result=0;
		
		try {
			con=this.getConnection(); //获取连接
			//创建预编译执行语句
			pstmt=con.prepareStatement(sql);
			this.setParams(pstmt, params);
			
			//执行预编译语句,获取结果
			result=pstmt.executeUpdate();
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally{
			this.closeAll(null, pstmt, con);
		}
		return result;
	}
	
	/**
	 * 查询数据
	 * @param sql 要执行的查询语句
	 * @param params 查询语句中占位符?对应值
	 * @return 返回满足条件的所有数据
	 */
	public List<Map<String,Object>> finds(String sql,Object ... params){
		Connection con=null;
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		
		List<Map<String,Object>> list=new ArrayList<Map<String,Object>>();
		int pp = 0;
		try {
			con=this.getConnection(); //获取连接
			pstmt=con.prepareStatement(sql); //创建预编译执行语句
			this.setParams(pstmt, params); //给预编译执行语句中的占位符赋值
			rs=pstmt.executeQuery(); //执行预编译语句获取结果集
			rs = pstmt.executeQuery();
		
			ResultSetMetaData rsmd=rs.getMetaData(); //获取结果集中列的信息
			int colCount=rsmd.getColumnCount();  //获取结果集中列的数量
			String[] colNames=new String[colCount];
			
			for(int i=0;i<colCount;i++){ //通过列的索引循环获取每个列的列名
				colNames[i]=rsmd.getColumnName(i+1).toLowerCase();
				
			}
			
			Map<String,Object> map=null; //每一个map中存放一行数据
			//通过列名循环获取每个列的值
			
			
			Blob blob;
			Object obj=null;
			String typeName=null;
			byte[] bt=null;
			InputStream is=null;
			
			while(rs.next()){ //每循环一次就是一行数据
				pp++;
				map=new HashMap<String,Object>();
				for(String colName:colNames){ //循环着一行中的每个列,通过每个列的列名获取这个列的值
					obj=rs.getObject(colName);
					if(obj!=null){
						typeName=obj.getClass().getSimpleName();
						if("BLOB".equals(typeName)){
							try {
								blob=(Blob)obj;
								bt=new byte[ (int) blob.length() ];
								is=blob.getBinaryStream();
								is.read(bt);
							} catch (IOException e) {
								e.printStackTrace();
							} finally{
								if(is!=null){
									try {
										is.close();
									} catch (IOException e) {
										e.printStackTrace();
									}
								}
							}
							map.put(colName,bt); //以列名为键,以对应列的值为值
						}else{
							map.put(colName,obj); //以列名为键,以对应列的值为值
						}
					}else{
						map.put(colName,obj); //以列名为键,以对应列的值为值
					}
				}
				list.add(map);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally{
			
			this.closeAll(rs, pstmt, con);
		}
		return list;
	}
	
	public List<String> getAllColnumsName(ResultSet rs) throws Exception{
		List<String> list = new ArrayList<String>();
		ResultSetMetaData rsmd = rs.getMetaData(); //获取结果集中列的信息
		int colCount=rsmd.getColumnCount();  //获取结果集中列的数量
		
		for(int i=0;i<colCount;i++){ //通过列的索引循环获取每个列的列名
			String x = rsmd.getColumnName(i+1).toLowerCase();
			list.add(x);
		}
		return list;
	}
	
	/**
	 * 获取多行值
	 * @param sql
	 * @param params
	 * @param c
	 * @return
	 */
	public <T> List<T> findAll(String sql,List<Object> params,Class c){
		List<T> list = new ArrayList<T>();
		
		Connection con=null;
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		try{
			
			con = this.getConnection();
		
			pstmt = con.prepareStatement(sql);
			//设置参数
			this.setParams(pstmt, params);
			//执行
			rs = pstmt.executeQuery();
			
			//获取所有的列名
			List<String> columnNames = this.getAllColnumsName(rs);
		
			//获取class的所有的方法
			Method[] methods = c.getDeclaredMethods();
		
			
			T t;//实例化对象
			String methodName = null;//方法名
			String columnName = null;//列名
			String typeName = null;//参数类型名
			Object val = null;//列对应的值
			
			
			while(rs.next()){
				
				t = (T)c.newInstance();//实例化一个对象
				//获取所有的列
				for(int i = 0;i<columnNames.size();i++){
					columnName = columnNames.get(i);
					val =  rs.getObject(columnName);
					
					for(Method m:methods){
						
						methodName = m.getName();
						
						if(("set"+columnName).equalsIgnoreCase(methodName)){
							typeName  = val.getClass().getName();
							
	if("java.math.BigDecimal".equals(typeName)){
								
								m.invoke(t, rs.getInt(columnName));
								
							}else if("java.lang.String".equals(typeName)){
								
								m.invoke(t, rs.getString(columnName));
								
							}else if("java.lang.Integer".equals(typeName)){
							
								m.invoke(t, rs.getInt(columnName));
								
							}else if("java.sql.Timestamp".equals(typeName)){
								m.invoke(t, rs.getTimestamp(columnName));
							}
							
						}
						
					}
					
					
				}
			
				list.add(t);
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally {
			
			this.closeAll(rs, pstmt, con);
		}
		
		return list;
	}
	
	

	/**
	 * 获取单行值
	 * @param <T>
	 * @param sql
	 * @param params
	 * @param c
	 * @return
	 */
	public  <T> T  findOne(String sql,List<Object> params,Class c){
		
		Connection con=null;
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		try{
			
			con = this.getConnection();
			pstmt = con.prepareStatement(sql);
			//设置参数
			this.setParams(pstmt, params);
			//执行
			rs = pstmt.executeQuery();
			
			//获取所有的列名
			List<String> columnNames = this.getAllColnumsName(rs);
		
			//获取class的所有的方法
			Method[] methods = c.getDeclaredMethods();
		
			
			T t;//实例化对象
			String methodName = null;//方法名
			String columnName = null;//列名
			String typeName = null;//参数类型名
			Object val = null;//列对应的值
			if(rs.next()){
				
				t = (T)c.newInstance();//实例化一个对象
				//获取所有的列
				for(int i = 0;i<columnNames.size();i++){
					columnName = columnNames.get(i);
					val =  rs.getObject(columnName);
					
					for(Method m:methods){
						
						methodName = m.getName();
						
						if(("set"+columnName).equalsIgnoreCase(methodName)){
							typeName  = val.getClass().getName();

							if("java.math.BigDecimal".equals(typeName)){
								
								m.invoke(t, rs.getInt(columnName));
								
							}else if("java.lang.String".equals(typeName)){
								
								m.invoke(t, rs.getString(columnName));
								
							}else{//其他数据类型
								
							}
							
						}
						
					}
					
					
				}
				return t;	
			}
			
		}catch(Exception e){
			e.printStackTrace();
		}finally {
			
			this.closeAll(rs, pstmt, con);
		}
		return null;
		
		
	}
	
	/**
	 * 使用聚合函数  
	 * @param sql 
	 * @param params
	 * @return
	 * @throws SQLException
	 */
	public int selectPloymer(String sql,List<Object> params) throws SQLException{
		
		Connection con=null;
		PreparedStatement pstmt=null;
		int result=0;
		
		try {
			con=this.getConnection(); //获取连接
			//创建预编译执行语句
			pstmt=con.prepareStatement(sql);
			this.setParams(pstmt, params);
			
			//执行预编译语句,获取结果
			result=pstmt.executeUpdate();
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 查询单行数据
	 * @param sql 要执行的查询语句
	 * @param params 查询语句中占位符?对应值
	 * @return 返回满足条件的所有数据
	 */
	public Map<String,Object> find(String sql,Object ... params){
		Connection con=null;
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		
		Map<String,Object> map=null; //每一个map中存放一行数据
		try {
			con=this.getConnection(); //获取连接
			pstmt=con.prepareStatement(sql); //创建预编译执行语句
			this.setParams(pstmt, params); //给预编译执行语句中的占位符赋值
			rs=pstmt.executeQuery(); //执行预编译语句获取结果集
			ResultSetMetaData rsmd=rs.getMetaData(); //获取结果集中列的信息
			int colCount=rsmd.getColumnCount();  //获取结果集中列的数量
			String[] colNames=new String[colCount];
			for(int i=0;i<colCount;i++){ //通过列的索引循环获取每个列的列名
				colNames[i]=rsmd.getColumnName(i+1).toLowerCase();
			}
	
			//通过列名循环获取每个列的值
			Blob blob;
			Object obj=null;
			String typeName=null;
			byte[] bt=null;
			InputStream is=null;
			if(rs.next()){ //每循环一次就是一行数据
				map=new HashMap<String,Object>();
				for(String colName:colNames){ //循环着一行中的每个列,通过每个列的列名获取这个列的值
					obj=rs.getObject(colName);
					if(obj!=null){
						typeName=obj.getClass().getSimpleName();
						if("BLOB".equals(typeName)){
							try {
								blob=(Blob)obj;
								bt=new byte[ (int) blob.length() ];
								is=blob.getBinaryStream();
								is.read(bt);
							} catch (IOException e) {
								e.printStackTrace();
							} finally{
								if(is!=null){
									try {
										is.close();
									} catch (IOException e) {
										e.printStackTrace();
									}
								}
							}
							map.put(colName,bt); //以列名为键,以对应列的值为值
						}else{
							map.put(colName,obj); //以列名为键,以对应列的值为值
						}
					}else{
						map.put(colName,obj); //以列名为键,以对应列的值为值
					}
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally{
			this.closeAll(rs, pstmt, con);
		}
		return map;
	}
	
	/**
	 * 针对聚合查询
	 * @param sql 要执行的查询语句
	 * @param params 查询语句中占位符?对应值
	 * @return 返回满足条件的所有数据
	 */
	public Map<String,String> get(String sql,Object ... params){
		Connection con=null;
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		
		Map<String,String>  map=null; //每一个map中存放一行数据
		try {
			con=this.getConnection(); //获取连接
			pstmt=con.prepareStatement(sql); //创建预编译执行语句
			this.setParams(pstmt, params); //给预编译执行语句中的占位符赋值
			rs=pstmt.executeQuery(); //执行预编译语句获取结果集
			ResultSetMetaData rsmd=rs.getMetaData(); //获取结果集中列的信息
			int colCount=rsmd.getColumnCount();  //获取结果集中列的数量
			String[] colNames=new String[colCount];
			for(int i=0;i<colCount;i++){ //通过列的索引循环获取每个列的列名
				colNames[i]=rsmd.getColumnName(i+1).toLowerCase();
			}
			
			//通过列名循环获取每个列的值
			if(rs.next()){ //每循环一次就是一行数据
				map=new HashMap<String,String>();
				for(String colName:colNames){ //循环着一行中的每个列,通过每个列的列名获取这个列的值
					map.put(colName,rs.getString(colName)); //以列名为键,以对应列的值为值
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally{
			this.closeAll(rs, pstmt, con);
		}
		return map;
	}
	/**
	 * 针对聚合查询
	 * @param sql 要执行的查询语句
	 * @param params 查询语句中占位符?对应值
	 * @return 返回满足条件的所有数据
	 */
	public Map<String,String> getx(String sql,String ... params){
		Connection con=null;
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		
		Map<String,String> map=null; //每一个map中存放一行数据
		try {
			con=this.getConnection(); //获取连接
			pstmt=con.prepareStatement(sql); //创建预编译执行语句
			this.setParams(pstmt, params); //给预编译执行语句中的占位符赋值
			rs=pstmt.executeQuery(); //执行预编译语句获取结果集
			ResultSetMetaData rsmd=rs.getMetaData(); //获取结果集中列的信息
			int colCount=rsmd.getColumnCount();  //获取结果集中列的数量
			String[] colNames=new String[colCount];
			for(int i=0;i<colCount;i++){ //通过列的索引循环获取每个列的列名
				colNames[i]=rsmd.getColumnName(i+1).toLowerCase();
			}
			
			//通过列名循环获取每个列的值
			if(rs.next()){ //每循环一次就是一行数据
				map=new HashMap<String,String>();
				for(String colName:colNames){ //循环着一行中的每个列,通过每个列的列名获取这个列的值
					map.put(colName,rs.getString(colName)); //以列名为键,以对应列的值为值
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally{
			this.closeAll(rs, pstmt, con);
		}
		return map;
	}
	
}

MapperInfo.java

package cn.itcast.mybatis;
/**
 * 存储XXMapper.xml  文件 信息
 * @author wjc
 *
 */
public class MapperInfo {
	private String sql;
	private String resultType;
	private String parameterType;
	private boolean isUpdate = true;
	@Override
	public String toString() {
		return "MapperInfo [sql=" + sql + ", resultType=" + resultType + ", parameterType=" + parameterType
				+ ", isUpdate=" + isUpdate + "]";
	}
	public String getSql() {
		return sql;
	}
	public void setSql(String sql) {
		this.sql = sql;
	}
	public String getResultType() {
		return resultType;
	}
	public void setResultType(String resultType) {
		this.resultType = resultType;
	}
	public String getParameterType() {
		return parameterType;
	}
	public void setParameterType(String parameterType) {
		this.parameterType = parameterType;
	}
	public boolean isUpdate() {
		return isUpdate;
	}
	public void setUpdate(boolean isUpdate) {
		this.isUpdate = isUpdate;
	}
	
	
	
	
}

MybatisConfig.java

package cn.itcast.mybatis;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;

/**
 * 解析mybatis-config.xml
 * @author wjc
 * 
 */

public class MybatisConfig {
	private DataSource data;//数据源信息  driver url username password
	private List<String> mappers = new ArrayList<String>();//存储映射文件  mappers
	

	//mybatis-config.xml
	public MybatisConfig(String config) throws DocumentException{
		this.parseXml(config);
	}
	
	/**
	 * 解析mybatis-config.xml文件
	 * @param config xml文件路径
	 * @throws DocumentException 
	 */
	private void parseXml(String config) throws DocumentException{
		SAXReader saxReader = new SAXReader();//SAXReader() 
		/**
		 *  void	removeHandler(String path) 
          Removes the ElementHandler from the event based processor, for the specified path.
		 */
		Document document = saxReader.read(config);//获取mybatis-config.xml文件的路径
		
		/**
		 * nodeName
		 *	/从根元素结点
		 *	//从匹配当前元素选择文档中的节点,需要考虑位置
		 *	//data/property 获取data下的所有的property元素
		 */
		/**
		 *  List	selectNodes(Object context) 
           selectNodes performs this XPath expression on the given Nodeor Listof Nodes instances appending all the results together into a single list.
		 */
		XPath xpath = document.createXPath("//dataSource/property");//定位到mybatis-config.xml下的dataSource标签下的property
		List<Element> list = xpath.selectNodes(document);//获取所有的property结点
		data = new DataSource();//创建数据源对象
		String qname;
		for(Element e:list){
				qname = e.attributeValue("name");
				/**
				 * 将标签的属性值放入到数据源对象中
				 */
				if("driver".equals(qname)){
					data.setDriverClassName(e.attributeValue("value"));
				}else if("url".equals(qname)){
					data.setUrl(e.attributeValue("value"));	
				}else if("username".equals(qname)){
					data.setUser(e.attributeValue("value"));
				}else if("password".equals(qname)){
					data.setPassword(e.attributeValue("value"));
				}
			}
			xpath = document.createXPath("//mappers/mapper");//定位到定位到mybatis-config.xml下的mappers标签下的mapper
			List<Element> list2 = xpath.selectNodes(document);//获取所有的mapper结点
			String pname;
			for(Element mapper:list2){
				pname = mapper.attributeValue("resource");//获取mapper标签的resource属性值
				mappers.add(pname);//循环所有的mapper映射文件添加到List集合中
			
		}
	}
	
	public DataSource getData() {
		return data;
	}
	public List<String> getMappers() {
		return mappers;
	}
	
	
}

SqlSession.java

package cn.itcast.mybatis;

import java.util.List;
/**
 * 创建SqlSession
 * @author wjc
 *
 */
public class SqlSession {
	private SqlSessionFactory factory;
	private DBHelper db;
	
	public SqlSession(SqlSessionFactory factory){
		//得到相应的SqlSessionFactory对象
		this.factory = factory;
		//获取相应连接
		this.db = new DBHelper(factory.getConfig().getData());
	}
	
	public <T> List<T> selectList(String sqlId,List<Object> params){
		//根据输入的sqlId 获取相应的sql语句配置信息
		MapperInfo mapperinfo = factory.getMapperInfos().get(sqlId);
		//非空
		if(null != mapperinfo){
			try{
				//获取sql语句
				String sql = mapperinfo.getSql();
				//若是跟新操作返回null
				if(mapperinfo.isUpdate()){
					return null;
				}
				//获取返回值
				String className = mapperinfo.getResultType();
				//得到返回值对象的类  比如 String  --> java.lang.String
				Class<?> c = Class.forName(className);
				//获取结果
				return db.findAll(sql, params, c);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		return null;
	}
	
	
}

 SqlSessionFactory.java

package cn.itcast.mybatis;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;

/**
 * 创建SqlSessionFactory
 * @author wjc
 *	解析Deptment.xml
 */
public class SqlSessionFactory {
	private MybatisConfig config;
	
	private Map<String,MapperInfo> mapperInfos = new HashMap<String,MapperInfo>();
	
	public SqlSessionFactory(MybatisConfig config) throws DocumentException{
		this.config = config;
		this.parseXml();
	}
	
	private void parseXml() throws DocumentException{
		List<String> mappers = config.getMappers();//获取mybatis-config.xml下所有的mapper标签
		if(mappers != null && mappers.size()>0){//若mapers非空
			SAXReader saxReader = new SAXReader();
			for(String mapper:mappers){
				
				//开始解析Deptment.xml
				File file = new File("src/main/resources/"+mapper);
				Document document = saxReader.read(file);
				//获取Deptment.xml下的mapper的所有标签
				XPath xpath = document.createXPath("//mapper/*");
				List<Element> list = xpath.selectNodes(document);
				MapperInfo info = null;
				String qname = null;
				for(Element e :list){
					info = new MapperInfo();//创建MapperInfo对象
					qname = e.getName();
					if("select".equals(qname)){
						info.setUpdate(false);
					}
					info.setParameterType(e.attributeValue("parameterType"));
					info.setResultType(e.attributeValue("resultType"));
					info.setSql(e.getTextTrim());
					mapperInfos.put(e.attributeValue("id"), info);//将id与sql语句的相关配置向关联
				}
			}
		}
	}

	public MybatisConfig getConfig() {
		return config;
	}

	public Map<String, MapperInfo> getMapperInfos() {
		return mapperInfos;
	}
	
	
}

MyTest.java

package hello4;


import java.util.List;

import org.dom4j.DocumentException;
import org.junit.Test;

import cn.itcast.bean.DeptmentBean;
import cn.itcast.mybatis.MybatisConfig;
import cn.itcast.mybatis.SqlSession;
import cn.itcast.mybatis.SqlSessionFactory;

public class MyTest {
	
	@Test
	public void show() throws DocumentException{
		String name = "src/main/resources/mybatis-config.xml";
		SqlSessionFactory fact =new SqlSessionFactory(new MybatisConfig(name));
		SqlSession session = new SqlSession(fact);
		List<DeptmentBean> list = session.selectList("get", null);
		System.out.println(list);
	}

	
}

运行结果

DeptmentBean [deptId=1, deptName=技术部, discrbe=湖南]
DeptmentBean [deptId=3, deptName=行政部, discrbe=湖南衡阳]
DeptmentBean [deptId=4, deptName=市场部, discrbe=湖南]
DeptmentBean [deptId=5, deptName=xx, discrbe=sss]
DeptmentBean [deptId=6, deptName=xx, discrbe=sss]
DeptmentBean [deptId=7, deptName=xx, discrbe=sss]
DeptmentBean [deptId=8, deptName=xx, discrbe=sss]

猜你喜欢

转载自blog.csdn.net/qq_35654259/article/details/81837058
今日推荐