Mybatis手写Mybatis框架实现Mybatis封装的JDBC功能-----Mybatis框架

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.god.ibatis</groupId>
    <artifactId>godbatis</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>org.dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>2.1.3</version>
        </dependency>
        <dependency>
            <groupId>jaxen</groupId>
            <artifactId>jaxen</artifactId>
            <version>1.2.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>
    </dependencies>
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.god.ibatis</groupId>
    <artifactId>godbatis</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>org.dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>2.1.3</version>
        </dependency>
        <dependency>
            <groupId>jaxen</groupId>
            <artifactId>jaxen</artifactId>
            <version>1.2.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>
    </dependencies>
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

</project>
package org.god.ibatis.core;

public class Const
{
    private Const(){}
    //整个框架的常量类
    public static final String UN_POOLED_DATASOURCE = "UNPOOLED";
    public static final String POOLED_DATASOURCE = "POOLED";
    public static final String JNDI_DATASOURCE = "JNDI";
    public static final String JDBC_TRANSACTION = "JDBC";
    public static final String MANAGED_TRANSACTION = "MANAGED";
}
package org.god.ibatis.core;

public class Const
{
    private Const(){}
    //整个框架的常量类
    public static final String UN_POOLED_DATASOURCE = "UNPOOLED";
    public static final String POOLED_DATASOURCE = "POOLED";
    public static final String JNDI_DATASOURCE = "JNDI";
    public static final String JDBC_TRANSACTION = "JDBC";
    public static final String MANAGED_TRANSACTION = "MANAGED";
}
package org.god.ibatis.core;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class JdbcTransaction implements Transaction
{
    //Jdbc事务管理器
    //godBatis只实现这个
    //我们控制事务需要调用connection的方法实现
    //需要调用连接对象的方法
    //我们的连接对象是从数据源来的
    //数据源属性必须要有,不然无法做事务的操作
    private DataSource dataSource = null;
    //数据源属性,是获取Connection对象的,所以这个数据源要实现DataSource
    //我们只需要三个实现即可,POOLED,UNPOOLED,JNDI
    public JdbcTransaction(DataSource dataSource, boolean autoCommit) {
        //创建事务管理器对象
        this.dataSource = dataSource;
        this.autoCommit = autoCommit;
    }
    //将connection对外暴露,可以执行SQL语句,必须在同一个事务管理器下,是同一个连接
    @Override
    public Connection getConnection()
    {
        return connection;
    }

    //因为openConnection已经创建对象了,就不会再生成新的连接,就能保证是同一个连接对象了
    private Connection connection;
    @Override
    public void openConnection()
    {
        try
        {
            connection = dataSource.getConnection();
            connection.setAutoCommit(autoCommit);
        }
        catch (SQLException e)
        {
            throw new RuntimeException(e);
        }
    }
    private boolean autoCommit;
    //自动提交的标记,
    @Override
    public void commit()
    {
        try
        {
            connection.commit();
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
    }

    @Override
    public void rollback()
    {
        try {
            connection.rollback();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void close()
    {
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
package org.god.ibatis.core;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class JdbcTransaction implements Transaction
{
    //Jdbc事务管理器
    //godBatis只实现这个
    //我们控制事务需要调用connection的方法实现
    //需要调用连接对象的方法
    //我们的连接对象是从数据源来的
    //数据源属性必须要有,不然无法做事务的操作
    private DataSource dataSource = null;
    //数据源属性,是获取Connection对象的,所以这个数据源要实现DataSource
    //我们只需要三个实现即可,POOLED,UNPOOLED,JNDI
    public JdbcTransaction(DataSource dataSource, boolean autoCommit) {
        //创建事务管理器对象
        this.dataSource = dataSource;
        this.autoCommit = autoCommit;
    }
    //将connection对外暴露,可以执行SQL语句,必须在同一个事务管理器下,是同一个连接
    @Override
    public Connection getConnection()
    {
        return connection;
    }

    //因为openConnection已经创建对象了,就不会再生成新的连接,就能保证是同一个连接对象了
    private Connection connection;
    @Override
    public void openConnection()
    {
        try
        {
            connection = dataSource.getConnection();
            connection.setAutoCommit(autoCommit);
        }
        catch (SQLException e)
        {
            throw new RuntimeException(e);
        }
    }
    private boolean autoCommit;
    //自动提交的标记,
    @Override
    public void commit()
    {
        try
        {
            connection.commit();
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
    }

    @Override
    public void rollback()
    {
        try {
            connection.rollback();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void close()
    {
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

package org.god.ibatis.core;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

//数据源的实现类JNDI
//使用第三方的数据库连接池获取Connection对象
public class JndiDataSource implements DataSource
{
    @Override
    public Connection getConnection() throws SQLException {
        return null;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
}
package org.god.ibatis.core;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

//数据源的实现类JNDI
//使用第三方的数据库连接池获取Connection对象
public class JndiDataSource implements DataSource
{
    @Override
    public Connection getConnection() throws SQLException {
        return null;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
}
package org.god.ibatis.core;

import javax.sql.DataSource;
import java.sql.Connection;

public class ManagedTransaction implements Transaction
{
    //godBatis对这个类就不实现了
    private DataSource dataSource;

    @Override
    public void openConnection() {

    }

    @Override
    public void commit() {

    }

    @Override
    public Connection getConnection() {
        return null;
    }

    @Override
    public void rollback() {

    }

    @Override
    public void close() {

    }
}
package org.god.ibatis.core;

import javax.sql.DataSource;
import java.sql.Connection;

public class ManagedTransaction implements Transaction
{
    //godBatis对这个类就不实现了
    private DataSource dataSource;

    @Override
    public void openConnection() {

    }

    @Override
    public void commit() {

    }

    @Override
    public Connection getConnection() {
        return null;
    }

    @Override
    public void rollback() {

    }

    @Override
    public void close() {

    }
}
package org.god.ibatis.core;

public class MappedStatement
{
    //这是一个普通的java类,封装了一个SQL标签
    //一个MappedStatement对象对应一个SQL标签
    //一个sql标签中所有的信息封装到该对象中
    //体现了面向对象编程实现
    //要封装的结果集类型
    //当select语句的时候,会对应一个resultType的值
    public MappedStatement(){}
    private String sql;
    private String resultType;

    @Override
    public String toString() {
        return "MappedStatement{" +
                "sql='" + sql + '\'' +
                ", resultType='" + resultType + '\'' +
                '}';
    }

    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 MappedStatement(String sql, String resultType)
    {
        this.sql = sql;
        this.resultType = resultType;
    }
}
package org.god.ibatis.core;

public class MappedStatement
{
    //这是一个普通的java类,封装了一个SQL标签
    //一个MappedStatement对象对应一个SQL标签
    //一个sql标签中所有的信息封装到该对象中
    //体现了面向对象编程实现
    //要封装的结果集类型
    //当select语句的时候,会对应一个resultType的值
    public MappedStatement(){}
    private String sql;
    private String resultType;

    @Override
    public String toString() {
        return "MappedStatement{" +
                "sql='" + sql + '\'' +
                ", resultType='" + resultType + '\'' +
                '}';
    }

    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 MappedStatement(String sql, String resultType)
    {
        this.sql = sql;
        this.resultType = resultType;
    }
}

package org.god.ibatis.core;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

//数据源的实现类POOLED
//使用GodBatis内置的数据库连接池获取对象
public class PooledDataSource implements DataSource {
    @Override
    public Connection getConnection() throws SQLException {
        //从数据库连接池中获取connection对象
        //需要自己写一个连接池(自己封装)
        return null;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
}
package org.god.ibatis.core;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

//数据源的实现类POOLED
//使用GodBatis内置的数据库连接池获取对象
public class PooledDataSource implements DataSource {
    @Override
    public Connection getConnection() throws SQLException {
        //从数据库连接池中获取connection对象
        //需要自己写一个连接池(自己封装)
        return null;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
}
package org.god.ibatis.core;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class SqlSession
{
    protected SqlSession(SqlSessionFactory sqlSessionFactory)
    {
        this.sqlSessionFactory = sqlSessionFactory;
    }
    private SqlSessionFactory sqlSessionFactory;
    //insert
    public int insert(String sqlId,Object obj)
    {
        PreparedStatement statement = null;
        Connection connection = sqlSessionFactory.getTransaction().getConnection();
        int count = 0;
        try
        {
            //JDBC代码,执行insert语句,完成插入操作
            String oldSql = sqlSessionFactory.getMappedStatements().get(sqlId).getSql();
            String newSql = oldSql.replaceAll("#\\{[a-zA-Z0-9_$]*}","?");
            statement = connection.prepareStatement(newSql);
            //给?传值
            Map transfer = Transfer(oldSql);
            Iterator iterator = transfer.entrySet().iterator();
            while(iterator.hasNext())
            {
                Map.Entry entry = (Map.Entry)iterator.next();
                Integer index = (Integer)entry.getKey();
                String value = (String)entry.getValue();
                String methodName = "get" + value.toUpperCase().charAt(0) + value.substring(1);
                Method declaredMethod = obj.getClass().getDeclaredMethod(methodName);
                Object invoke = declaredMethod.invoke(obj);
                statement.setString(index,invoke.toString());
            }
            //执行SQL
            count = statement.executeUpdate();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (statement != null)
            {
                try
                {
                    statement.close();
                }
                catch (SQLException e)
                {
                    throw new RuntimeException(e);
                }
            }
        }
        return count;
    }
    public Object SelectOne(String sqlId,Object obj)
    {
        Object o = null;
        if(sqlSessionFactory.getMappedStatements().get(sqlId) != null)
        {
            Connection connection = null;
            PreparedStatement statement = null;
            ResultSet resultSet = null;
            try
            {
                connection = sqlSessionFactory.getTransaction().getConnection();
                MappedStatement mappedStatement = sqlSessionFactory.getMappedStatements().get(sqlId);
                String oldSql = mappedStatement.getSql();
                String newSql = oldSql.replaceAll("#\\{[a-zA-Z0-9_$]*}","?");
                statement = connection.prepareStatement(newSql);
                //给占位符传值
                Map map = Transfer(oldSql);
                Iterator iterator = map.entrySet().iterator();
                while(iterator.hasNext())
                {
                    Map.Entry entry = (Map.Entry) iterator.next();
                    Integer integer = (Integer)entry.getKey();
                    statement.setString(integer,obj.toString());
                }
                //查询返回结果集
                resultSet = statement.executeQuery();
                if(resultSet.next())
                {
                    String resultType = mappedStatement.getResultType();
                    Class<?> aClass = Class.forName(resultType);
                    Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();
                    o = declaredConstructor.newInstance();
                    //赋值
                    ResultSetMetaData metaData = resultSet.getMetaData();
                    int columnCount = metaData.getColumnCount();
                    for (int i = 1; i < columnCount + 1; i++)
                    {
                        String columnName = metaData.getColumnName(i);
                        String value = resultSet.getString(columnName);
                        //直接赋值法
//                        Field declaredField = aClass.getDeclaredField(columnName);
//                        declaredField.setAccessible(true);
//                        declaredField.set(o,value);
                        String MethodName = "set" + columnName.toUpperCase().charAt(0) + columnName.substring(1);
                        Method declaredMethod = aClass.getDeclaredMethod(MethodName,String.class);
                        declaredMethod.invoke(o,value);
                    }
                }
            }
            catch (Exception e)
            {
                throw new RuntimeException(e);
            }
            finally
            {
                if (statement != null)
                {
                    try
                    {
                        statement.close();
                    }
                    catch (SQLException e)
                    {
                        throw new RuntimeException(e);
                    }
                }
                if (resultSet != null)
                {
                    try
                    {
                        resultSet.close();
                    }
                    catch(SQLException e)
                    {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
        return o;
    }
    public Map Transfer(String oldSql) throws Exception
    {
        Map<Integer,String> map = new HashMap<>();
        int fromIndex = 0;
        int index = 1;
        while(true)
        {
            int starIndex = oldSql.indexOf("#",fromIndex);
            if(starIndex < 0)
            {
                break;
            }
            int endIndex = oldSql.indexOf("}",fromIndex);
            String value = oldSql.substring(starIndex + 2,endIndex).trim();
            map.put(index,value);
            fromIndex = endIndex + 1;
            index++;
        }
        return map;
    }
    public void commit()
    {
        sqlSessionFactory.getTransaction().commit();
    }
    public void rollback()
    {
        sqlSessionFactory.getTransaction().rollback();
    }
    public void close()
    {
        sqlSessionFactory.getTransaction().close();
    }
}
package org.god.ibatis.core;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class SqlSession
{
    protected SqlSession(SqlSessionFactory sqlSessionFactory)
    {
        this.sqlSessionFactory = sqlSessionFactory;
    }
    private SqlSessionFactory sqlSessionFactory;
    //insert
    public int insert(String sqlId,Object obj)
    {
        PreparedStatement statement = null;
        Connection connection = sqlSessionFactory.getTransaction().getConnection();
        int count = 0;
        try
        {
            //JDBC代码,执行insert语句,完成插入操作
            String oldSql = sqlSessionFactory.getMappedStatements().get(sqlId).getSql();
            String newSql = oldSql.replaceAll("#\\{[a-zA-Z0-9_$]*}","?");
            statement = connection.prepareStatement(newSql);
            //给?传值
            Map transfer = Transfer(oldSql);
            Iterator iterator = transfer.entrySet().iterator();
            while(iterator.hasNext())
            {
                Map.Entry entry = (Map.Entry)iterator.next();
                Integer index = (Integer)entry.getKey();
                String value = (String)entry.getValue();
                String methodName = "get" + value.toUpperCase().charAt(0) + value.substring(1);
                Method declaredMethod = obj.getClass().getDeclaredMethod(methodName);
                Object invoke = declaredMethod.invoke(obj);
                statement.setString(index,invoke.toString());
            }
            //执行SQL
            count = statement.executeUpdate();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (statement != null)
            {
                try
                {
                    statement.close();
                }
                catch (SQLException e)
                {
                    throw new RuntimeException(e);
                }
            }
        }
        return count;
    }
    public Object SelectOne(String sqlId,Object obj)
    {
        Object o = null;
        if(sqlSessionFactory.getMappedStatements().get(sqlId) != null)
        {
            Connection connection = null;
            PreparedStatement statement = null;
            ResultSet resultSet = null;
            try
            {
                connection = sqlSessionFactory.getTransaction().getConnection();
                MappedStatement mappedStatement = sqlSessionFactory.getMappedStatements().get(sqlId);
                String oldSql = mappedStatement.getSql();
                String newSql = oldSql.replaceAll("#\\{[a-zA-Z0-9_$]*}","?");
                statement = connection.prepareStatement(newSql);
                //给占位符传值
                Map map = Transfer(oldSql);
                Iterator iterator = map.entrySet().iterator();
                while(iterator.hasNext())
                {
                    Map.Entry entry = (Map.Entry) iterator.next();
                    Integer integer = (Integer)entry.getKey();
                    statement.setString(integer,obj.toString());
                }
                //查询返回结果集
                resultSet = statement.executeQuery();
                if(resultSet.next())
                {
                    String resultType = mappedStatement.getResultType();
                    Class<?> aClass = Class.forName(resultType);
                    Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();
                    o = declaredConstructor.newInstance();
                    //赋值
                    ResultSetMetaData metaData = resultSet.getMetaData();
                    int columnCount = metaData.getColumnCount();
                    for (int i = 1; i < columnCount + 1; i++)
                    {
                        String columnName = metaData.getColumnName(i);
                        String value = resultSet.getString(columnName);
                        //直接赋值法
//                        Field declaredField = aClass.getDeclaredField(columnName);
//                        declaredField.setAccessible(true);
//                        declaredField.set(o,value);
                        String MethodName = "set" + columnName.toUpperCase().charAt(0) + columnName.substring(1);
                        Method declaredMethod = aClass.getDeclaredMethod(MethodName,String.class);
                        declaredMethod.invoke(o,value);
                    }
                }
            }
            catch (Exception e)
            {
                throw new RuntimeException(e);
            }
            finally
            {
                if (statement != null)
                {
                    try
                    {
                        statement.close();
                    }
                    catch (SQLException e)
                    {
                        throw new RuntimeException(e);
                    }
                }
                if (resultSet != null)
                {
                    try
                    {
                        resultSet.close();
                    }
                    catch(SQLException e)
                    {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
        return o;
    }
    public Map Transfer(String oldSql) throws Exception
    {
        Map<Integer,String> map = new HashMap<>();
        int fromIndex = 0;
        int index = 1;
        while(true)
        {
            int starIndex = oldSql.indexOf("#",fromIndex);
            if(starIndex < 0)
            {
                break;
            }
            int endIndex = oldSql.indexOf("}",fromIndex);
            String value = oldSql.substring(starIndex + 2,endIndex).trim();
            map.put(index,value);
            fromIndex = endIndex + 1;
            index++;
        }
        return map;
    }
    public void commit()
    {
        sqlSessionFactory.getTransaction().commit();
    }
    public void rollback()
    {
        sqlSessionFactory.getTransaction().rollback();
    }
    public void close()
    {
        sqlSessionFactory.getTransaction().close();
    }
}
package org.god.ibatis.core;

import java.util.Map;

public class SqlSessionFactory
{
    //一个数据库对应一个SqlSessionFactory对象
    //通过这个对象可以开启会话,建立与数据库的连接
    //一个SqlSessionFactory对象可以开启多个SqlSession会话
    //所以这个事务管理器应该是一个接口,面向接口编程
    protected SqlSessionFactory(){}
    public SqlSession openSession()
    {
        //开启会话的前提就是开启连接
        transaction.openConnection();
        //创建SqlSession对象
        SqlSession sqlSession = new SqlSession(this);
        return sqlSession;
    }

    protected SqlSessionFactory(Transaction transaction, Map<String, MappedStatement> mappedStatements) {
        this.transaction = transaction;
        this.mappedStatements = mappedStatements;
    }

    public Transaction getTransaction() {
        return transaction;
    }

    public void setTransaction(Transaction transaction) {
        this.transaction = transaction;
    }

    public Map<String, MappedStatement> getMappedStatements() {
        return mappedStatements;
    }

    public void setMappedStatements(Map<String, MappedStatement> mappedStatements) {
        this.mappedStatements = mappedStatements;
    }

    //事务管理器属性
    private Transaction transaction;
    //存放sql对象的map集合,key是SqlId,Value是对应的SQL标签对象
    private Map<String,MappedStatement> mappedStatements;
}
package org.god.ibatis.core;

import java.util.Map;

public class SqlSessionFactory
{
    //一个数据库对应一个SqlSessionFactory对象
    //通过这个对象可以开启会话,建立与数据库的连接
    //一个SqlSessionFactory对象可以开启多个SqlSession会话
    //所以这个事务管理器应该是一个接口,面向接口编程
    protected SqlSessionFactory(){}
    public SqlSession openSession()
    {
        //开启会话的前提就是开启连接
        transaction.openConnection();
        //创建SqlSession对象
        SqlSession sqlSession = new SqlSession(this);
        return sqlSession;
    }

    protected SqlSessionFactory(Transaction transaction, Map<String, MappedStatement> mappedStatements) {
        this.transaction = transaction;
        this.mappedStatements = mappedStatements;
    }

    public Transaction getTransaction() {
        return transaction;
    }

    public void setTransaction(Transaction transaction) {
        this.transaction = transaction;
    }

    public Map<String, MappedStatement> getMappedStatements() {
        return mappedStatements;
    }

    public void setMappedStatements(Map<String, MappedStatement> mappedStatements) {
        this.mappedStatements = mappedStatements;
    }

    //事务管理器属性
    private Transaction transaction;
    //存放sql对象的map集合,key是SqlId,Value是对应的SQL标签对象
    private Map<String,MappedStatement> mappedStatements;
}
package org.god.ibatis.core;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.god.ibatis.utils.Resources;

import javax.sql.DataSource;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SqlSessionFactoryBuilder
{
    //通过godBatis-config文件,创建SqlSessionFactory对象
    public SqlSessionFactoryBuilder(){}
    public SqlSessionFactory build(InputStream is)
    {
        //解析godBatis-config文件创建SqlSessionFactory对象
        //build操作的核心就是要解析XML文件
        //解析完成要构建SqlSessionFactory对象
        //解析GodBatis-config文件
        SAXReader reader = new SAXReader();
        Document document = null;
        SqlSessionFactory sqlSessionFactory = null;
        try
        {
            document = reader.read(is);
            Element rootElement = (Element)document.selectSingleNode("/configuration/environments");
            String defaultId = rootElement.attributeValue("default");
            Element environment = (Element) document.selectSingleNode("/configuration/environments/environment[@id='" + defaultId +"']");
            Element transactionManagerEle = environment.element("transactionManager");
            Element dataSourceEle = environment.element("dataSource");
            DataSource dataSource = getDataSource(dataSourceEle);
            //获取事务管理器
            Transaction transaction = getTransaction(transactionManagerEle,dataSource);
            //获取MappedStatements
            List<Node> mappers = document.selectNodes("//mapper");
            List<String> mapperList = new ArrayList<>();
            mappers.forEach(node ->
            {
                Element mapper = (Element)node;
                String resource = mapper.attributeValue("resource");
                mapperList.add(resource);
            });
            //获取整个文件中所有的mapper标签
            Map<String,MappedStatement> mappedStatements = getMappedStatements(mapperList);
            sqlSessionFactory = new SqlSessionFactory(transaction,mappedStatements);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return sqlSessionFactory;
    }

    private Map<String, MappedStatement> getMappedStatements(List<String> mapperList)
    {
        Map<String,MappedStatement> map = new HashMap<>();
        mapperList.forEach(resource ->
        {
            SAXReader reader = new SAXReader();
            InputStream ip = Resources.getResourceAsStream(resource);
            Document document = null;
            try
            {
                document = reader.read(ip);
            }
            catch (DocumentException e)
            {
                throw new RuntimeException(e);
            }
            Element mapper = document.getRootElement();
            String namespace = mapper.attributeValue("namespace");
            List<Element> elements = mapper.elements();
            elements.forEach(element ->
            {
                MappedStatement mappedStatement = new MappedStatement();
                String resultType = element.attributeValue("resultType");
                String id = element.attributeValue("id");
                if(resultType != null)
                {
                    mappedStatement.setResultType(resultType);
                }
                else
                {
                    mappedStatement.setResultType("null");
                }
                String sql = element.getTextTrim();
                mappedStatement.setSql(sql);
                String sqlId = namespace + "." + id;
                map.put(sqlId,mappedStatement);
            });
        });
        return map;
    }

    private Transaction getTransaction(Element transactionManagerEle,DataSource dataSource)
    {
        //获取事务管理器对象
        String type = transactionManagerEle.attributeValue("type").trim().toUpperCase();
        Transaction transaction = null;
        if(Const.JDBC_TRANSACTION.equals(type))
        {
            //默认是开启事务的,将来需要手动提交的
            transaction = new JdbcTransaction(dataSource,false);
        }
        if(Const.MANAGED_TRANSACTION.equals(type))
        {
            transaction = new ManagedTransaction();
        }
        return transaction;
    }

    private DataSource getDataSource(Element dataSourceEle) 
    {
        //获取数据源对象
        String type = dataSourceEle.attributeValue("type").trim().toUpperCase();
        DataSource dataSource = null;
        List<Element> elements = dataSourceEle.elements();
        Map<String,String> map = new HashMap<>();
        elements.forEach(element -> 
        {
            String name = element.attributeValue("name");
            String value = element.attributeValue("value");
            map.put(name,value);
        });
        String driver = map.get("driver");
        String url = map.get("url");
        String username = map.get("username");
        String password = map.get("password");
        if(Const.UN_POOLED_DATASOURCE.equals(type))
        {
            dataSource = new UnPooledDataSource(driver,url,username,password);
        }
        else if(Const.POOLED_DATASOURCE.equals(type))
        {
            dataSource = new PooledDataSource();
        }
        else if(Const.JNDI_DATASOURCE.equals(type))
        {
            dataSource = new JndiDataSource();
        }
        return dataSource;
    }
}
package org.god.ibatis.core;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.god.ibatis.utils.Resources;

import javax.sql.DataSource;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SqlSessionFactoryBuilder
{
    //通过godBatis-config文件,创建SqlSessionFactory对象
    public SqlSessionFactoryBuilder(){}
    public SqlSessionFactory build(InputStream is)
    {
        //解析godBatis-config文件创建SqlSessionFactory对象
        //build操作的核心就是要解析XML文件
        //解析完成要构建SqlSessionFactory对象
        //解析GodBatis-config文件
        SAXReader reader = new SAXReader();
        Document document = null;
        SqlSessionFactory sqlSessionFactory = null;
        try
        {
            document = reader.read(is);
            Element rootElement = (Element)document.selectSingleNode("/configuration/environments");
            String defaultId = rootElement.attributeValue("default");
            Element environment = (Element) document.selectSingleNode("/configuration/environments/environment[@id='" + defaultId +"']");
            Element transactionManagerEle = environment.element("transactionManager");
            Element dataSourceEle = environment.element("dataSource");
            DataSource dataSource = getDataSource(dataSourceEle);
            //获取事务管理器
            Transaction transaction = getTransaction(transactionManagerEle,dataSource);
            //获取MappedStatements
            List<Node> mappers = document.selectNodes("//mapper");
            List<String> mapperList = new ArrayList<>();
            mappers.forEach(node ->
            {
                Element mapper = (Element)node;
                String resource = mapper.attributeValue("resource");
                mapperList.add(resource);
            });
            //获取整个文件中所有的mapper标签
            Map<String,MappedStatement> mappedStatements = getMappedStatements(mapperList);
            sqlSessionFactory = new SqlSessionFactory(transaction,mappedStatements);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return sqlSessionFactory;
    }

    private Map<String, MappedStatement> getMappedStatements(List<String> mapperList)
    {
        Map<String,MappedStatement> map = new HashMap<>();
        mapperList.forEach(resource ->
        {
            SAXReader reader = new SAXReader();
            InputStream ip = Resources.getResourceAsStream(resource);
            Document document = null;
            try
            {
                document = reader.read(ip);
            }
            catch (DocumentException e)
            {
                throw new RuntimeException(e);
            }
            Element mapper = document.getRootElement();
            String namespace = mapper.attributeValue("namespace");
            List<Element> elements = mapper.elements();
            elements.forEach(element ->
            {
                MappedStatement mappedStatement = new MappedStatement();
                String resultType = element.attributeValue("resultType");
                String id = element.attributeValue("id");
                if(resultType != null)
                {
                    mappedStatement.setResultType(resultType);
                }
                else
                {
                    mappedStatement.setResultType("null");
                }
                String sql = element.getTextTrim();
                mappedStatement.setSql(sql);
                String sqlId = namespace + "." + id;
                map.put(sqlId,mappedStatement);
            });
        });
        return map;
    }

    private Transaction getTransaction(Element transactionManagerEle,DataSource dataSource)
    {
        //获取事务管理器对象
        String type = transactionManagerEle.attributeValue("type").trim().toUpperCase();
        Transaction transaction = null;
        if(Const.JDBC_TRANSACTION.equals(type))
        {
            //默认是开启事务的,将来需要手动提交的
            transaction = new JdbcTransaction(dataSource,false);
        }
        if(Const.MANAGED_TRANSACTION.equals(type))
        {
            transaction = new ManagedTransaction();
        }
        return transaction;
    }

    private DataSource getDataSource(Element dataSourceEle) 
    {
        //获取数据源对象
        String type = dataSourceEle.attributeValue("type").trim().toUpperCase();
        DataSource dataSource = null;
        List<Element> elements = dataSourceEle.elements();
        Map<String,String> map = new HashMap<>();
        elements.forEach(element -> 
        {
            String name = element.attributeValue("name");
            String value = element.attributeValue("value");
            map.put(name,value);
        });
        String driver = map.get("driver");
        String url = map.get("url");
        String username = map.get("username");
        String password = map.get("password");
        if(Const.UN_POOLED_DATASOURCE.equals(type))
        {
            dataSource = new UnPooledDataSource(driver,url,username,password);
        }
        else if(Const.POOLED_DATASOURCE.equals(type))
        {
            dataSource = new PooledDataSource();
        }
        else if(Const.JNDI_DATASOURCE.equals(type))
        {
            dataSource = new JndiDataSource();
        }
        return dataSource;
    }
package org.god.ibatis.core;

import java.sql.Connection;

public interface Transaction
{
    //事务管理器接口
    //所有的事务管理都应该遵循此规范
    //JDBC和MANAGED事务管理器都应该实现这个接口
    //Transaction事务管理器通过事务方法
    //提交事务,回滚事务,关闭事务
    void openConnection();
    //真正的开启数据库连接
    void commit();
    //获取数据库连接对象的方法
    Connection getConnection();
    void rollback();
    void close();
}
package org.god.ibatis.core;

import java.sql.Connection;

public interface Transaction
{
    //事务管理器接口
    //所有的事务管理都应该遵循此规范
    //JDBC和MANAGED事务管理器都应该实现这个接口
    //Transaction事务管理器通过事务方法
    //提交事务,回滚事务,关闭事务
    void openConnection();
    //真正的开启数据库连接
    void commit();
    //获取数据库连接对象的方法
    Connection getConnection();
    void rollback();
    void close();
}

package org.god.ibatis.core;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

//数据源的实现类UNPOOLED
//不使用连接池,每一次都新建Connection对象
public class UnPooledDataSource implements DataSource {
    //数据库驱动,值从配置文件中来
    private String url;
    private String username;
    private String password;
    public UnPooledDataSource() {}
    public UnPooledDataSource(String driver, String url, String username, String password) {
        //直接注册驱动
        try
        {
            Class.forName(driver);
        }
        catch (ClassNotFoundException e)
        {
            throw new RuntimeException(e);
        }
        //创建一个数据源对象
        this.url = url;
        this.username = username;
        this.password = password;
    }

    @Override
    public Connection getConnection() throws SQLException
    {
        Connection connection = DriverManager.getConnection(url, username, password);
        return connection;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException
    {
        Connection connection = DriverManager.getConnection(url, username, password);
        return null;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
}
package org.god.ibatis.core;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

//数据源的实现类UNPOOLED
//不使用连接池,每一次都新建Connection对象
public class UnPooledDataSource implements DataSource {
    //数据库驱动,值从配置文件中来
    private String url;
    private String username;
    private String password;
    public UnPooledDataSource() {}
    public UnPooledDataSource(String driver, String url, String username, String password) {
        //直接注册驱动
        try
        {
            Class.forName(driver);
        }
        catch (ClassNotFoundException e)
        {
            throw new RuntimeException(e);
        }
        //创建一个数据源对象
        this.url = url;
        this.username = username;
        this.password = password;
    }

    @Override
    public Connection getConnection() throws SQLException
    {
        Connection connection = DriverManager.getConnection(url, username, password);
        return connection;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException
    {
        Connection connection = DriverManager.getConnection(url, username, password);
        return null;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
}
package org.god.ibatis.utils;

import java.io.InputStream;

public class Resources
{
    //godBatis提供的资源工具类,完成类路径中资源的加载
    private Resources(){}
    //工具类的构造方法都是私有化的,因为方法都是静态的
    //为了避免new对象,所以构造方法私有化
    public static InputStream getResourceAsStream(String resource)
    {
        //从类路径下加载资源
        //从类路径中获取资源作为一个输入流
        return ClassLoader.getSystemClassLoader().getResourceAsStream(resource);
    }
}
package org.god.ibatis.utils;

import java.io.InputStream;

public class Resources
{
    //godBatis提供的资源工具类,完成类路径中资源的加载
    private Resources(){}
    //工具类的构造方法都是私有化的,因为方法都是静态的
    //为了避免new对象,所以构造方法私有化
    public static InputStream getResourceAsStream(String resource)
    {
        //从类路径下加载资源
        //从类路径中获取资源作为一个输入流
        return ClassLoader.getSystemClassLoader().getResourceAsStream(resource);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旧约Alatus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值