简单自定义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);
}
}
}
输出测试数据如下:

 

猜你喜欢

转载自www.cnblogs.com/flzidea/p/10857486.html