zoukankan      html  css  js  c++  java
  • 基于Mybatis原理实现的自定义持久框架

    本次演示主基于mybatis原理实现,用Java+jdbc进行封装的一个持久类框架;
    
    
    pom.xml
    
    
    <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>ipersistent</groupId>
        <artifactId>Ipersistence</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <properties>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
            <maven.compiler.release>1.8</maven.compiler.release>
        </properties>
        <dependencies>
            <dependency>
                <groupId>javax.xml.bind</groupId>
                <artifactId>jaxb-api</artifactId>
                <version>2.3.0</version>
            </dependency>
            <dependency>
                <groupId>com.sun.xml.bind</groupId>
                <artifactId>jaxb-core</artifactId>
                <version>2.3.0</version>
            </dependency>
    
            <dependency>
    
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.17</version>
            </dependency>
            <dependency>
                <groupId>c3p0</groupId>
                <artifactId>c3p0</artifactId>
                <version>0.9.1.2</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.12</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.10</version>
            </dependency>
            <dependency>
                <groupId>dom4j</groupId>
                <artifactId>dom4j</artifactId>
                <version>1.6.1</version>
            </dependency>
            <dependency>
                <groupId>jaxen</groupId>
                <artifactId>jaxen</artifactId>
                <version>1.1.6</version>
            </dependency>
        </dependencies>
    
        <build>
            <pluginManagement>
                <plugins>
                    <!--This plugin's configuration is used to store Eclipse m2e settings 
                        only. It has no influence on the Maven build itself. -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-toolchains-plugin</artifactId>
                        <configuration>
                            <toolchains>
                                <jdk>
                                    <version>1.8</version>
                                    <vendor>mysql</vendor>
                                </jdk>
                            </toolchains>
                        </configuration>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>toolchain</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
    
                </plugins>
            </pluginManagement>
        </build>
    </project>
    
    
    SqpMapConfig.xml(相当于mybatis.xml)
    
    <?xml version="1.0" encoding="UTF-8" ?>
    <configuration>
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/lin_xu_db"></property>
        <property name="user" value="root"></property>
        <property name="password" value="root"></property>
        <mapper resource="UserMapper.xml"></mapper>
    </configuration>
    
    
    UserMapper.xml(相当于mybatis的mapper)
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <mapper namespace="com.test.UserDao">
        <select id="selectUser" paramterType="com.test.User" resultType="com.test.User" autocommit="false">
            select * from user_tb
        </select>
    </mapper>
    
    
    配置解析
    
    
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.sql.DataSource;
    /**
     * 
     * @author linxu
     *
     */
    public class Configuration {
        private DataSource dataSource;
    
        private Map<String, MappedStatement> mappedStatement = new HashMap<String, MappedStatement>();
    
        public DataSource getDataSource() {
            return dataSource;
        }
    
        public void setDataSource(DataSource dataSource) {
            this.dataSource = dataSource;
        }
    
        public Map<String, MappedStatement> getMappedStatement() {
            return mappedStatement;
        }
    
        public void setMappedStatement(Map<String, MappedStatement> mappedStatement) {
            this.mappedStatement = mappedStatement;
        }
    
    }
    
    
    
    
    package com.Ipersistence.configuration;
    /**
     * 
     * @author linxu
     *
     */
    public class MappedStatement {
        private String id;// id标识
        private Class<?> resultType;// 返回值类型
        private Class<?> paramterType;// 参数类型
        private String sql;// SQL
        private String dbAction;// updata/insert/select/delete标识
        private boolean autoCommit;//
    
        public MappedStatement(Builder builder) {
            this.id = builder.id;
            this.resultType = builder.resultType;
            this.paramterType = builder.paramterType;
            this.sql = builder.sql;
            this.dbAction = builder.dbAction;
            this.autoCommit=builder.autoCommit;
        }
    
        public boolean isAutoCommit() {
            return autoCommit;
        }
    
        public void setAutoCommit(boolean autoCommit) {
            this.autoCommit = autoCommit;
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
    
        public Class<?> getResultType() {
            return resultType;
        }
    
        public void setResultType(Class<?> resultType) {
            this.resultType = resultType;
        }
    
        public Class<?> getParamterType() {
            return paramterType;
        }
    
        public void setParamterType(Class<?> paramterType) {
            this.paramterType = paramterType;
        }
    
        public String getSql() {
            return sql;
        }
    
        public void setSql(String sql) {
            this.sql = sql;
        }
    
        public String getDbAction() {
            return dbAction;
        }
    
        public void setDbAction(String dbAction) {
            this.dbAction = dbAction;
        }
    
        public static class Builder {
            private String id;// id标识
            private Class<?> resultType;// 返回值类型
            private Class<?> paramterType;// 参数类型
            private String sql;// SQL
            private String dbAction;
            private boolean autoCommit;//
    
            public Builder putId(String id) {
                this.id = id;
                return this;
            }
    
            public Builder putResultType(Class<?> resultType) {
                this.resultType = resultType;
                return this;
            }
    
            public Builder putParamterType(Class<?> paramterType) {
    
                this.paramterType = paramterType;
                return this;
    
            }
    
            public Builder putSql(String sql) {
                this.sql = sql;
                return this;
            }
    
            public Builder putDbAction(String dbAction) {
                this.dbAction = dbAction;
                return this;
    
            }
    
            public MappedStatement builder() {
                return new MappedStatement(this);
            }
    
            public Builder putAutoCommit(boolean autoCommit) {
                this.autoCommit=autoCommit;
                return this;
                
            }
        }
    
    }
    
    
    
    package com.Ipersistence.configuration;
    
    import java.beans.PropertyVetoException;
    import java.io.InputStream;
    import java.util.List;
    import java.util.Properties;
    
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    import com.Ipersistence.io.Resources;
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    /**
     * 
     * @author linxu
     *
     */
    public class XMLConfigerBuilder {
        private Configuration configuration;
    
        public XMLConfigerBuilder() {
            this.configuration = new Configuration();
        }
    
        public Configuration getConfiguration() {
            return configuration;
        }
    
        public void setConfiguration(Configuration configuration) {
            this.configuration = configuration;
        }
    
        @SuppressWarnings("unchecked")
        public Configuration parseConfig(InputStream inputStream) throws DocumentException, PropertyVetoException {
            Document document = new SAXReader().read(inputStream);
            Element rootElement = document.getRootElement();
            List<Element> configElement = rootElement.selectNodes("property");
            Properties properties = new Properties();
            for (Element element : configElement) {
                String nameproperty = element.attributeValue("name");
                String valueProperty = element.attributeValue("value");
                properties.setProperty(nameproperty, valueProperty);
            }
            ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
            comboPooledDataSource.setUser(properties.getProperty("user"));
            comboPooledDataSource.setJdbcUrl(properties.getProperty("jdbcUrl"));
            comboPooledDataSource.setPassword(properties.getProperty("password"));
            comboPooledDataSource.setDriverClass(properties.getProperty("driverClass"));
            configuration.setDataSource(comboPooledDataSource);
    
            // 解析mapper.xml文件
            List<Element> mapperElement = rootElement.selectNodes("//mapper");
            XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(configuration);
            for (Element element : mapperElement) {
                String mapperResource = element.attributeValue("resource");
                InputStream mapperInputStream = Resources.getResourceAsStream(mapperResource);
                xmlMapperBuilder.parseMapper(mapperInputStream);
            }
            return configuration;
    
        }
    
    }
    
    
    
    
    package com.Ipersistence.configuration;
    
    import java.io.InputStream;
    import java.util.List;
    
    import org.dom4j.DocumentException;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    /**
     * 
     * @author linxu
     *
     */
    public class XMLMapperBuilder {
        Configuration configuration;
    
        public XMLMapperBuilder(Configuration configuration) {
            this.configuration = configuration;
        }
    
        public void parseMapper(InputStream inputStream) throws DocumentException {
            parseXml(new SAXReader().read(inputStream).getRootElement(), "select", "insert", "delete", "update");
        }
    
        @SuppressWarnings("unchecked")
        public void parseXml(Element rootElement, String... dbActions) {
            String namespace = rootElement.attributeValue("namespace");
            for (int i = 0; i < dbActions.length; i++) {
                List<Element> elements = rootElement.selectNodes(dbActions[i]);
                if (elements != null && !elements.isEmpty()) {
                    for (Element element : elements) {
                        String id = element.attributeValue("id");
                        String paramterType = element.attributeValue("paramterType");
                        String resultType = element.attributeValue("resultType");
                        String sqlText = element.getTextTrim();
                        String autoVommit = element.attributeValue("autocommit").trim();
                        configuration.getMappedStatement().put(namespace + "." + id,
                                new MappedStatement.Builder().putId(id).putParamterType(getClassType(paramterType))
                                        .putResultType(getClassType(resultType)).putSql(sqlText).putDbAction(dbActions[i])
                                        .putAutoCommit(autoVommit.isEmpty() ? true : autoVommit.equals("true")).builder());
                    }
                }
            }
        }
    
        private Class<?> getClassType(String className) {
            if (!className.isEmpty()) {
                try {
                    return Class.forName(className);
                } catch (ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return null;
    
        }
    
    }
    
    
    
    Session工厂(实现类似mybatis的session访问,利用动态代理实现类似mybatis的接口式开发)
    
    
    package com.Ipersistence.session;
    
    import java.sql.SQLException;
    import java.util.List;
    /**
     * 
     * @author linxu
     *
     */
    public interface SqlSession {
        public <E> List<E> selectList(String statementId, Object... params)throws SecurityException, SQLException, Exception;
    
        public <E> E selectOne(String statementId, Object... params) throws SecurityException, SQLException, Exception;
    
        public int executeUpdate(String statementId, Object... params) throws SecurityException, SQLException, Exception;
    
        public int update(String statementId, Object... params) throws SecurityException, SQLException, Exception;
    
        public int insert(String statementId, Object... params) throws SecurityException, SQLException, Exception;
    
        public int delete(String statementId, Object... params) throws SecurityException, SQLException, Exception;
    
        public void close();
    
        public <T> T getMapper(Class<?> mapperClass);
    
        public void commit();
    }
    
    
    
    
    package com.Ipersistence.session;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Proxy;
    import java.sql.SQLException;
    import java.util.List;
    
    import com.Ipersistence.configuration.Configuration;
    import com.Ipersistence.configuration.MappedStatement;
    import com.Ipersistence.executor.BaseExecutor;
    import com.Ipersistence.executor.Executor;
    
    /**
     * 
     * @author ;linxu
     *
     */
    public class DefaultSession implements SqlSession {
        private Configuration configuration;
    
        public DefaultSession(Configuration configuration) {
            this.configuration = configuration;
        }
    
        Executor baseExecutor = new BaseExecutor();
    
        @Override
        public <E> List<E> selectList(String statementId, Object... params)
                throws SecurityException, SQLException, Exception {
            final MappedStatement mappedStatement = configuration.getMappedStatement().get(statementId);
            if (mappedStatement != null) {
                return baseExecutor.query(configuration, mappedStatement, params);
            }
            return null;
        }
    
        @Override
        public <E> E selectOne(String statementId, Object... params) throws SecurityException, SQLException, Exception {
            List<E> list = selectList(statementId, params);
            if (list != null && list.size() == 1) {
                return list.get(0);
            } else {
                throw new RuntimeException("查询数据为Null或则查询数据过多:");
            }
        }
    
        @Override
        public int executeUpdate(String statementId, Object... params) throws SecurityException, SQLException, Exception {
            final MappedStatement mappedStatement = configuration.getMappedStatement().get(statementId);
            if (mappedStatement == null) {
                return this.baseExecutor.executeUpdate(configuration, mappedStatement, params);
            }
            return 0;
        }
    
        @Override
        public int update(String statementId, Object... params) throws SecurityException, SQLException, Exception {
            // TODO Auto-generated method stub
            return this.executeUpdate(statementId, params);
        }
    
        @Override
        public int insert(String statementId, Object... params) throws SecurityException, SQLException, Exception {
            // TODO Auto-generated method stub
            return this.executeUpdate(statementId, params);
        }
    
        @Override
        public int delete(String statementId, Object... params) throws SecurityException, SQLException, Exception {
            // TODO Auto-generated method stub
            return this.executeUpdate(statementId, params);
        }
    
        @SuppressWarnings("unchecked")
        @Override
        public <T> T getMapper(Class<?> mapperClass) {
            Object proxy = Proxy.newProxyInstance(DefaultSession.class.getClassLoader(), new Class[] { mapperClass },
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
                            // 方法名字
                            String methodname = method.getName();
                            // 获取接口类
                            String className = method.getDeclaringClass().getName();
                            String statementId = className + "." + methodname;
                            java.lang.reflect.Type resultType = method.getGenericReturnType();
                            MappedStatement mappedStatement = configuration.getMappedStatement().get(statementId);
                            if (mappedStatement == null) {
                                throw new RuntimeException("sql配置不存在:" + DefaultSession.class.getName());
                            }
                            if (mappedStatement.getDbAction().equals("select")) {
                                // 如果返回值类型是泛型,调用selectList,否则selectOne
                                if (resultType instanceof ParameterizedType) {
                                    return selectList(statementId, params);
                                } else {
                                    return selectOne(statementId, params);
                                }
                            } else if (mappedStatement.getDbAction().equals("insert")
                                    || mappedStatement.getDbAction().equals("delete")
                                    || mappedStatement.getDbAction().equals("update")) {
                                return executeUpdate(statementId, params);
                            } else {
                                throw new RuntimeException("mapper配置文件错误:");
                            }
                        }
                    });
            return (T) proxy;
        }
    
        @Override
        public void close() {
            try {
                baseExecutor.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        @Override
        public void commit() {
            try {
                baseExecutor.commit();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
    }
    
    
    
    package com.Ipersistence.session;
    
    /**
     * SqlSessionFactory工厂类:生产SqlSession
     * @author linxu
     *
     */
    public interface SqlSessionFactory{
        public SqlSession openSession();
    }
    
    
    
    package com.Ipersistence.session;
    
    import com.Ipersistence.configuration.Configuration;
    /**
     * 
     * @author linxu
     *
     */
    public class DefaultSqlSessionFactory implements SqlSessionFactory {
        private Configuration configuration;
    
    
        public DefaultSqlSessionFactory(Configuration configuration) {
            this.configuration = configuration;
        }
    
        @Override
        public SqlSession openSession() {
            // TODO Auto-generated method stub
            return new DefaultSession(configuration);
        }
    
    }
    
    
    
    
    package com.Ipersistence.session;
    
    import java.beans.PropertyVetoException;
    import java.io.InputStream;
    
    import org.dom4j.DocumentException;
    
    import com.Ipersistence.configuration.Configuration;
    import com.Ipersistence.configuration.XMLConfigerBuilder;
    
    /**
     * SqlSessionFactoryBuilder,利用配置构建个SqlSessionFactory工厂
     * 
     * @author linxu
     * 
     */
    public class SqlSessionFactoryBuilder {
        private Configuration configuration;
    
        /**
         * 
         * @param inputStream
         * @return
         * @throws PropertyVetoException
         * @throws DocumentException
         */
        public SqlSessionFactory builder(InputStream inputStream) throws DocumentException, PropertyVetoException {
            XMLConfigerBuilder xMLConfigerBuilder = new XMLConfigerBuilder();
            this.configuration = xMLConfigerBuilder.parseConfig(inputStream);
            DefaultSqlSessionFactory defaultSqlSessionFactory = new DefaultSqlSessionFactory(configuration);
            return defaultSqlSessionFactory;
        }
    }
    
    
    Io读取
    
    package com.Ipersistence.io;
    
    import java.io.InputStream;
    /**
     * 
     * @author linxu
     *
     */
    public class Resources {
         /**
          * 
          * @param path
          * @return
          */
        public static InputStream getResourceAsStream(String path) {
            return Resources.class.getClassLoader().getResourceAsStream(path);
        }
    }
    
    
    
    Executor实现(主要封装了jdbc对数据库的操作)
    
    package com.Ipersistence.executor;
    
    import java.sql.SQLException;
    import java.util.List;
    
    import com.Ipersistence.boundsql.BoundSql;
    import com.Ipersistence.configuration.Configuration;
    import com.Ipersistence.configuration.MappedStatement;
    /**
     * 
     * @author linxu
     *
     */
    public interface Executor {
        public <E> List<E> query(Configuration configuration, MappedStatement mappedStatement, Object... params)
                throws SQLException, Exception, SecurityException;
    
        public int executeUpdate(Configuration configuration, MappedStatement mappedStatement, Object... params)
                throws SQLException, Exception, SecurityException;
    
        // 关闭连接操作
        public void close() throws SQLException;
    
        public BoundSql getBoundSql(String sql);
        
        public void commit() throws SQLException;
    
    }
    
    
    
    package com.Ipersistence.executor;
    
    import java.beans.PropertyDescriptor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.ResultSetMetaData;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;
    
    import com.Ipersistence.boundsql.BoundSql;
    import com.Ipersistence.configuration.Configuration;
    import com.Ipersistence.configuration.MappedStatement;
    import com.Ipersistence.utils.GenericTokenParser;
    import com.Ipersistence.utils.ParameterMapping;
    import com.Ipersistence.utils.ParameterMappingTokenHandler;
    /**
     * 
     * @author linxu
     *
     */
    public class BaseExecutor implements Executor {
        private Connection connection;
    
        @SuppressWarnings("unchecked")
        @Override
        public <E> List<E> query(Configuration configuration, MappedStatement mappedStatement, Object... params)
                throws SQLException, Exception, SecurityException {
            this.connection = configuration.getDataSource().getConnection();
            String sql = mappedStatement.getSql();
            BoundSql boundSql = getBoundSql(sql);
            PreparedStatement preparedStatement = connection.prepareStatement(boundSql.getSqlText());
            List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
            if(parameterMappings!=null&&!parameterMappings.isEmpty()) {
            for (int i = 0; i < parameterMappings.size(); i++) {
                ParameterMapping parameterMapping = parameterMappings.get(i);
                String valuename = parameterMapping.getContent();
                // 鎷垮埌杩欎釜瀛楁�瀵硅薄
                Field field = mappedStatement.getParamterType().getDeclaredField(valuename);
                // 璁剧疆鏉冮檺
                field.setAccessible(true);
                Object o = field.get(params[0]);
                preparedStatement.setObject(i + 1, o);
            }
            }
            // 鎵ц�鏁版嵁鏌ヨ�
            ResultSet resultSet = preparedStatement.executeQuery();
            // 瑙f瀽鏁版嵁
            List<E> result_list = new ArrayList<>();
            while (resultSet.next()) {
                ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
                E e = (E) mappedStatement.getResultType().newInstance();
                for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
                    String columnname = resultSetMetaData.getColumnName(i);
                    Object value = resultSet.getObject(columnname);
                    PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnname,
                            mappedStatement.getResultType());
                    Method method = propertyDescriptor.getWriteMethod();
                    method.invoke(e, value);
                }
                result_list.add(e);
            }
            return result_list;
        }
    
        @Override
        public int executeUpdate(Configuration configuration, MappedStatement mappedStatement, Object... params)
                throws SQLException, Exception, SecurityException {
            // 瀹屾垚瀵规暟鎹�簱鑳¤�闂�
            // 1鑾峰彇杩炴帴
            connection = configuration.getDataSource().getConnection();
            // 鍒ゆ柇鏄�惁鏄��缃�嚜鍔ㄦ彁浜�
            if (mappedStatement.isAutoCommit())
                connection.setAutoCommit(true);
            // 鍏抽棴鑷�姩鎻愪氦
            connection.setAutoCommit(false);
            // 2鑾峰彇Sql
            String sql = mappedStatement.getSql();
            // 3杞�崲sql,灏嗚В鏋�
            BoundSql boundSql = getBoundSql(sql);
            // 4鑾峰彇棰勫�鐞嗗�璞�reparedStatement
            PreparedStatement preparedStatement = connection.prepareStatement(boundSql.getSqlText());
            // 鑾峰彇鍙傛暟瀵硅薄绫诲瀷
            Class<?> parameterClass = mappedStatement.getParamterType();
            // 鏁版嵁鍙傛暟璁剧疆
            List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
            for (int i = 0; i < parameterMappings.size(); i++) {
                ParameterMapping parameterMapping = parameterMappings.get(i);
                String content = parameterMapping.getContent();
                // 鑾峰彇灞炴�у�璞�
                Field field = parameterClass.getDeclaredField(content);
                // 璁剧疆鏉冮檺
                field.setAccessible(true);
                // 鑾峰彇灞炴�у�璞″��
                Object o = field.get(params[0]);
                // 瑷�疆鍙傛暟
                preparedStatement.setObject(i + 1, o);
            }
    
            // 鎵ц�sql
            return preparedStatement.executeUpdate();
        }
    
        @Override
        public void close() throws SQLException {
            if (connection != null) {
                this.connection.close();
            }
    
        }
    
        @Override
        public BoundSql getBoundSql(String sql) {
            final ParameterMappingTokenHandler parameterMappingTokenHandler = new ParameterMappingTokenHandler();
            final GenericTokenParser genericTokenParser = new GenericTokenParser("#{", "}", parameterMappingTokenHandler);
            String sqlText = genericTokenParser.parse(sql);
            List<ParameterMapping> parameterMappings = parameterMappingTokenHandler.getParameterMappings();
            return new BoundSql.Builder().putSqlText(sqlText).putParameterMappings(parameterMappings).builder();
        }
    
        @Override
        public void commit() throws SQLException {
            // 濡傛灉宸茬粡璁剧疆涓鸿嚜鍔ㄦ彁浜や簡锛屽氨娌″繀瑕佸啀閲嶅�鎻愪氦
            if (connection != null) {
                if (connection.getAutoCommit() == true) {
                    return;
                }
                try {
                    connection.commit();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    
    }
    
    
    sql转换(和mybatis原理一致)
    
    package com.Ipersistence.boundsql;
    
    import java.util.List;
    
    import com.Ipersistence.utils.ParameterMapping;
    
    /**
     * 转换sql
     * @author linxu
     *
     */
    public class BoundSql {
        private String sqlText;
        private List<ParameterMapping> parameterMappings;
    
        public String getSqlText() {
            return sqlText;
        }
    
        public void setSqlText(String sqlText) {
            this.sqlText = sqlText;
        }
    
        public List<ParameterMapping> getParameterMappings() {
            return parameterMappings;
        }
    
        public void setParameterMappings(List<ParameterMapping> parameterMappings) {
            this.parameterMappings = parameterMappings;
        }
    
        public BoundSql(Builder builder) {
            this.sqlText = builder.sqlText;
            this.parameterMappings = builder.parameterMappings;
        }
    
        public static class Builder {
            private String sqlText;
            private List<ParameterMapping> parameterMappings;
    
            public Builder putSqlText(String sql) {
                this.sqlText = sql;
                return this;
            }
    
            public Builder putParameterMappings(List<ParameterMapping> parameterMappings) {
                this.parameterMappings = parameterMappings;
                return this;
            }
    
            public BoundSql builder() {
                return new BoundSql(this);
            }
    
        }
    
    }
    
    
    以下工具类是我从mybatis拷贝而来的,也贴上
    
    /**
     *    Copyright 2009-2017 the original author or authors.
     *
     *    Licensed under the Apache License, Version 2.0 (the "License");
     *    you may not use this file except in compliance with the License.
     *    You may obtain a copy of the License at
     *
     *       http://www.apache.org/licenses/LICENSE-2.0
     *
     *    Unless required by applicable law or agreed to in writing, software
     *    distributed under the License is distributed on an "AS IS" BASIS,
     *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     *    See the License for the specific language governing permissions and
     *    limitations under the License.
     */
    package com.Ipersistence.utils;
    
    /**
     * @author Clinton Begin
     */
    public class GenericTokenParser {
    
      private final String openToken; //�?始标�?
      private final String closeToken; //结束标记
      private final TokenHandler handler; //标记处理�?
    
      public GenericTokenParser(String openToken, String closeToken, TokenHandler handler) {
        this.openToken = openToken;
        this.closeToken = closeToken;
        this.handler = handler;
      }
    
      /**
       * 解析${}�?#{}
       * @param text
       * @return
       * 该方法主要实现了配置文件、脚本等片段中占位符的解析�?�处理工作,并返回最终需要的数据�?
       * 其中,解析工作由该方法完成,处理工作是由处理器handler的handleToken()方法来实�?
       */
      public String parse(String text) {
        // 验证参数问题,如果是null,就返回空字符串�?
        if (text == null || text.isEmpty()) {
          return "";
        }
    
        // 下面继续验证是否包含�?始标签,如果不包含,默认不是占位符,直接原样返回即可,否则继续执行�??
        int start = text.indexOf(openToken, 0);
        if (start == -1) {
          return text;
        }
    
       // 把text转成字符数组src,并且定义默认偏移量offset=0、存储最终需要返回字符串的变量builder�?
        // text变量中占位符对应的变量名expression。判断start是否大于-1(即text中是否存在openToken),如果存在就执行下面代码
        char[] src = text.toCharArray();
        int offset = 0;
        final StringBuilder builder = new StringBuilder();
        StringBuilder expression = null;
        while (start > -1) {
         // 判断如果�?始标记前如果有转义字符,就不作为openToken进行处理,否则继续处�?
          if (start > 0 && src[start - 1] == '\') {
            builder.append(src, offset, start - offset - 1).append(openToken);
            offset = start + openToken.length();
          } else {
            //重置expression变量,避免空指针或�?��?�数据干扰�??
            if (expression == null) {
              expression = new StringBuilder();
            } else {
              expression.setLength(0);
            }
            builder.append(src, offset, start - offset);
            offset = start + openToken.length();
            int end = text.indexOf(closeToken, offset);
            while (end > -1) {////存在结束标记�?
              if (end > offset && src[end - 1] == '\') {//如果结束标记前面有转义字符时
                // this close token is escaped. remove the backslash and continue.
                expression.append(src, offset, end - offset - 1).append(closeToken);
                offset = end + closeToken.length();
                end = text.indexOf(closeToken, offset);
              } else {//不存在转义字符,即需要作为参数进行处�?
                expression.append(src, offset, end - offset);
                offset = end + closeToken.length();
                break;
              }
            }
            if (end == -1) {
              // close token was not found.
              builder.append(src, start, src.length - start);
              offset = src.length;
            } else {
              //首先根据参数的key(即expression)进行参数处理,返回?作为占位�?
              builder.append(handler.handleToken(expression.toString()));
              offset = end + closeToken.length();
            }
          }
          start = text.indexOf(openToken, offset);
        }
        if (offset < src.length) {
          builder.append(src, offset, src.length - offset);
        }
        return builder.toString();
      }
    }
    
    
    
    package com.Ipersistence.utils;
    
    public class ParameterMapping {
    
        private String content;
    
        public ParameterMapping(String content) {
            this.content = content;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    }
    
    
    package com.Ipersistence.utils;
    
    import java.util.ArrayList;
    import java.util.List;
    
    
    
    
    public class ParameterMappingTokenHandler implements TokenHandler {
        private List<ParameterMapping> parameterMappings = new ArrayList<ParameterMapping>();
    
        // context是参数名�? #{id} #{username}
    
        public String handleToken(String content) {
            parameterMappings.add(buildParameterMapping(content));
            return "?";
        }
    
        private ParameterMapping buildParameterMapping(String content) {
            ParameterMapping parameterMapping = new ParameterMapping(content);
            return parameterMapping;
        }
    
        public List<ParameterMapping> getParameterMappings() {
            return parameterMappings;
        }
    
        public void setParameterMappings(List<ParameterMapping> parameterMappings) {
            this.parameterMappings = parameterMappings;
        }
    
    }
    
    
    
    /**
     *    Copyright 2009-2015 the original author or authors.
     *
     *    Licensed under the Apache License, Version 2.0 (the "License");
     *    you may not use this file except in compliance with the License.
     *    You may obtain a copy of the License at
     *
     *       http://www.apache.org/licenses/LICENSE-2.0
     *
     *    Unless required by applicable law or agreed to in writing, software
     *    distributed under the License is distributed on an "AS IS" BASIS,
     *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     *    See the License for the specific language governing permissions and
     *    limitations under the License.
     */
    package com.Ipersistence.utils;
    
    /**
     * @author Clinton Begin
     */
    public interface TokenHandler {
      String handleToken(String content);
    }
    
    
    
    
    测试:
    
    
    package com.test;
    
    public class User {
    
        private int id;
        private String username;
        private String userid;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getUserid() {
            return userid;
        }
        public void setUserid(String userid) {
            this.userid = userid;
        }
        @Override
        public String toString() {
            return "User [id=" + id + ", username=" + username + ", userid=" + userid + ", getId()=" + getId()
                    + ", getUsername()=" + getUsername() + ", getUserid()=" + getUserid() + ", getClass()=" + getClass()
                    + ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]";
        }
        
    }
    
    
    //dao接口
    package com.test;
    
    import java.util.List;
    
    public interface UserDao {
    public List<User>selectUser(User user);
    }
    
    
    
    package com.test;
    
    import java.beans.PropertyVetoException;
    
    import org.dom4j.DocumentException;
    
    import com.Ipersistence.io.Resources;
    import com.Ipersistence.session.SqlSession;
    import com.Ipersistence.session.SqlSessionFactory;
    import com.Ipersistence.session.SqlSessionFactoryBuilder;
    
    public class UserTest {
    public static void main(String[] args) throws DocumentException, PropertyVetoException {
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
                .builder(Resources.getResourceAsStream("SqlMapConfig.xml"));
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        User user=new User();
        
        
        System.err.println(userDao.selectUser(user).toString());
        sqlSession.close();
    }
    
    }

    ------------恢复内容开始------------

    本次演示主基于mybatis原理实现,用Java+jdbc进行封装的一个持久类框架;
    
    
    pom.xml
    
    
    <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>ipersistent</groupId>
        <artifactId>Ipersistence</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <properties>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
            <maven.compiler.release>1.8</maven.compiler.release>
        </properties>
        <dependencies>
            <dependency>
                <groupId>javax.xml.bind</groupId>
                <artifactId>jaxb-api</artifactId>
                <version>2.3.0</version>
            </dependency>
            <dependency>
                <groupId>com.sun.xml.bind</groupId>
                <artifactId>jaxb-core</artifactId>
                <version>2.3.0</version>
            </dependency>
    
            <dependency>
    
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.17</version>
            </dependency>
            <dependency>
                <groupId>c3p0</groupId>
                <artifactId>c3p0</artifactId>
                <version>0.9.1.2</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.12</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.10</version>
            </dependency>
            <dependency>
                <groupId>dom4j</groupId>
                <artifactId>dom4j</artifactId>
                <version>1.6.1</version>
            </dependency>
            <dependency>
                <groupId>jaxen</groupId>
                <artifactId>jaxen</artifactId>
                <version>1.1.6</version>
            </dependency>
        </dependencies>
    
        <build>
            <pluginManagement>
                <plugins>
                    <!--This plugin's configuration is used to store Eclipse m2e settings 
                        only. It has no influence on the Maven build itself. -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-toolchains-plugin</artifactId>
                        <configuration>
                            <toolchains>
                                <jdk>
                                    <version>1.8</version>
                                    <vendor>mysql</vendor>
                                </jdk>
                            </toolchains>
                        </configuration>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>toolchain</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
    
                </plugins>
            </pluginManagement>
        </build>
    </project>
    
    
    SqpMapConfig.xml(相当于mybatis.xml)
    
    <?xml version="1.0" encoding="UTF-8" ?>
    <configuration>
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/lin_xu_db"></property>
        <property name="user" value="root"></property>
        <property name="password" value="root"></property>
        <mapper resource="UserMapper.xml"></mapper>
    </configuration>
    
    
    UserMapper.xml(相当于mybatis的mapper)
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <mapper namespace="com.test.UserDao">
        <select id="selectUser" paramterType="com.test.User" resultType="com.test.User" autocommit="false">
            select * from user_tb
        </select>
    </mapper>
    
    
    配置解析
    
    
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.sql.DataSource;
    /**
     * 
     * @author linxu
     *
     */
    public class Configuration {
        private DataSource dataSource;
    
        private Map<String, MappedStatement> mappedStatement = new HashMap<String, MappedStatement>();
    
        public DataSource getDataSource() {
            return dataSource;
        }
    
        public void setDataSource(DataSource dataSource) {
            this.dataSource = dataSource;
        }
    
        public Map<String, MappedStatement> getMappedStatement() {
            return mappedStatement;
        }
    
        public void setMappedStatement(Map<String, MappedStatement> mappedStatement) {
            this.mappedStatement = mappedStatement;
        }
    
    }
    
    
    
    
    package com.Ipersistence.configuration;
    /**
     * 
     * @author linxu
     *
     */
    public class MappedStatement {
        private String id;// id标识
        private Class<?> resultType;// 返回值类型
        private Class<?> paramterType;// 参数类型
        private String sql;// SQL
        private String dbAction;// updata/insert/select/delete标识
        private boolean autoCommit;//
    
        public MappedStatement(Builder builder) {
            this.id = builder.id;
            this.resultType = builder.resultType;
            this.paramterType = builder.paramterType;
            this.sql = builder.sql;
            this.dbAction = builder.dbAction;
            this.autoCommit=builder.autoCommit;
        }
    
        public boolean isAutoCommit() {
            return autoCommit;
        }
    
        public void setAutoCommit(boolean autoCommit) {
            this.autoCommit = autoCommit;
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
    
        public Class<?> getResultType() {
            return resultType;
        }
    
        public void setResultType(Class<?> resultType) {
            this.resultType = resultType;
        }
    
        public Class<?> getParamterType() {
            return paramterType;
        }
    
        public void setParamterType(Class<?> paramterType) {
            this.paramterType = paramterType;
        }
    
        public String getSql() {
            return sql;
        }
    
        public void setSql(String sql) {
            this.sql = sql;
        }
    
        public String getDbAction() {
            return dbAction;
        }
    
        public void setDbAction(String dbAction) {
            this.dbAction = dbAction;
        }
    
        public static class Builder {
            private String id;// id标识
            private Class<?> resultType;// 返回值类型
            private Class<?> paramterType;// 参数类型
            private String sql;// SQL
            private String dbAction;
            private boolean autoCommit;//
    
            public Builder putId(String id) {
                this.id = id;
                return this;
            }
    
            public Builder putResultType(Class<?> resultType) {
                this.resultType = resultType;
                return this;
            }
    
            public Builder putParamterType(Class<?> paramterType) {
    
                this.paramterType = paramterType;
                return this;
    
            }
    
            public Builder putSql(String sql) {
                this.sql = sql;
                return this;
            }
    
            public Builder putDbAction(String dbAction) {
                this.dbAction = dbAction;
                return this;
    
            }
    
            public MappedStatement builder() {
                return new MappedStatement(this);
            }
    
            public Builder putAutoCommit(boolean autoCommit) {
                this.autoCommit=autoCommit;
                return this;
                
            }
        }
    
    }
    
    
    
    package com.Ipersistence.configuration;
    
    import java.beans.PropertyVetoException;
    import java.io.InputStream;
    import java.util.List;
    import java.util.Properties;
    
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    import com.Ipersistence.io.Resources;
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    /**
     * 
     * @author linxu
     *
     */
    public class XMLConfigerBuilder {
        private Configuration configuration;
    
        public XMLConfigerBuilder() {
            this.configuration = new Configuration();
        }
    
        public Configuration getConfiguration() {
            return configuration;
        }
    
        public void setConfiguration(Configuration configuration) {
            this.configuration = configuration;
        }
    
        @SuppressWarnings("unchecked")
        public Configuration parseConfig(InputStream inputStream) throws DocumentException, PropertyVetoException {
            Document document = new SAXReader().read(inputStream);
            Element rootElement = document.getRootElement();
            List<Element> configElement = rootElement.selectNodes("property");
            Properties properties = new Properties();
            for (Element element : configElement) {
                String nameproperty = element.attributeValue("name");
                String valueProperty = element.attributeValue("value");
                properties.setProperty(nameproperty, valueProperty);
            }
            ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
            comboPooledDataSource.setUser(properties.getProperty("user"));
            comboPooledDataSource.setJdbcUrl(properties.getProperty("jdbcUrl"));
            comboPooledDataSource.setPassword(properties.getProperty("password"));
            comboPooledDataSource.setDriverClass(properties.getProperty("driverClass"));
            configuration.setDataSource(comboPooledDataSource);
    
            // 解析mapper.xml文件
            List<Element> mapperElement = rootElement.selectNodes("//mapper");
            XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(configuration);
            for (Element element : mapperElement) {
                String mapperResource = element.attributeValue("resource");
                InputStream mapperInputStream = Resources.getResourceAsStream(mapperResource);
                xmlMapperBuilder.parseMapper(mapperInputStream);
            }
            return configuration;
    
        }
    
    }
    
    
    
    
    package com.Ipersistence.configuration;
    
    import java.io.InputStream;
    import java.util.List;
    
    import org.dom4j.DocumentException;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    /**
     * 
     * @author linxu
     *
     */
    public class XMLMapperBuilder {
        Configuration configuration;
    
        public XMLMapperBuilder(Configuration configuration) {
            this.configuration = configuration;
        }
    
        public void parseMapper(InputStream inputStream) throws DocumentException {
            parseXml(new SAXReader().read(inputStream).getRootElement(), "select", "insert", "delete", "update");
        }
    
        @SuppressWarnings("unchecked")
        public void parseXml(Element rootElement, String... dbActions) {
            String namespace = rootElement.attributeValue("namespace");
            for (int i = 0; i < dbActions.length; i++) {
                List<Element> elements = rootElement.selectNodes(dbActions[i]);
                if (elements != null && !elements.isEmpty()) {
                    for (Element element : elements) {
                        String id = element.attributeValue("id");
                        String paramterType = element.attributeValue("paramterType");
                        String resultType = element.attributeValue("resultType");
                        String sqlText = element.getTextTrim();
                        String autoVommit = element.attributeValue("autocommit").trim();
                        configuration.getMappedStatement().put(namespace + "." + id,
                                new MappedStatement.Builder().putId(id).putParamterType(getClassType(paramterType))
                                        .putResultType(getClassType(resultType)).putSql(sqlText).putDbAction(dbActions[i])
                                        .putAutoCommit(autoVommit.isEmpty() ? true : autoVommit.equals("true")).builder());
                    }
                }
            }
        }
    
        private Class<?> getClassType(String className) {
            if (!className.isEmpty()) {
                try {
                    return Class.forName(className);
                } catch (ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return null;
    
        }
    
    }
    
    
    
    Session工厂(实现类似mybatis的session访问,利用动态代理实现类似mybatis的接口式开发)
    
    
    package com.Ipersistence.session;
    
    import java.sql.SQLException;
    import java.util.List;
    /**
     * 
     * @author linxu
     *
     */
    public interface SqlSession {
        public <E> List<E> selectList(String statementId, Object... params)throws SecurityException, SQLException, Exception;
    
        public <E> E selectOne(String statementId, Object... params) throws SecurityException, SQLException, Exception;
    
        public int executeUpdate(String statementId, Object... params) throws SecurityException, SQLException, Exception;
    
        public int update(String statementId, Object... params) throws SecurityException, SQLException, Exception;
    
        public int insert(String statementId, Object... params) throws SecurityException, SQLException, Exception;
    
        public int delete(String statementId, Object... params) throws SecurityException, SQLException, Exception;
    
        public void close();
    
        public <T> T getMapper(Class<?> mapperClass);
    
        public void commit();
    }
    
    
    
    
    package com.Ipersistence.session;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Proxy;
    import java.sql.SQLException;
    import java.util.List;
    
    import com.Ipersistence.configuration.Configuration;
    import com.Ipersistence.configuration.MappedStatement;
    import com.Ipersistence.executor.BaseExecutor;
    import com.Ipersistence.executor.Executor;
    
    /**
     * 
     * @author ;linxu
     *
     */
    public class DefaultSession implements SqlSession {
        private Configuration configuration;
    
        public DefaultSession(Configuration configuration) {
            this.configuration = configuration;
        }
    
        Executor baseExecutor = new BaseExecutor();
    
        @Override
        public <E> List<E> selectList(String statementId, Object... params)
                throws SecurityException, SQLException, Exception {
            final MappedStatement mappedStatement = configuration.getMappedStatement().get(statementId);
            if (mappedStatement != null) {
                return baseExecutor.query(configuration, mappedStatement, params);
            }
            return null;
        }
    
        @Override
        public <E> E selectOne(String statementId, Object... params) throws SecurityException, SQLException, Exception {
            List<E> list = selectList(statementId, params);
            if (list != null && list.size() == 1) {
                return list.get(0);
            } else {
                throw new RuntimeException("查询数据为Null或则查询数据过多:");
            }
        }
    
        @Override
        public int executeUpdate(String statementId, Object... params) throws SecurityException, SQLException, Exception {
            final MappedStatement mappedStatement = configuration.getMappedStatement().get(statementId);
            if (mappedStatement == null) {
                return this.baseExecutor.executeUpdate(configuration, mappedStatement, params);
            }
            return 0;
        }
    
        @Override
        public int update(String statementId, Object... params) throws SecurityException, SQLException, Exception {
            // TODO Auto-generated method stub
            return this.executeUpdate(statementId, params);
        }
    
        @Override
        public int insert(String statementId, Object... params) throws SecurityException, SQLException, Exception {
            // TODO Auto-generated method stub
            return this.executeUpdate(statementId, params);
        }
    
        @Override
        public int delete(String statementId, Object... params) throws SecurityException, SQLException, Exception {
            // TODO Auto-generated method stub
            return this.executeUpdate(statementId, params);
        }
    
        @SuppressWarnings("unchecked")
        @Override
        public <T> T getMapper(Class<?> mapperClass) {
            Object proxy = Proxy.newProxyInstance(DefaultSession.class.getClassLoader(), new Class[] { mapperClass },
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
                            // 方法名字
                            String methodname = method.getName();
                            // 获取接口类
                            String className = method.getDeclaringClass().getName();
                            String statementId = className + "." + methodname;
                            java.lang.reflect.Type resultType = method.getGenericReturnType();
                            MappedStatement mappedStatement = configuration.getMappedStatement().get(statementId);
                            if (mappedStatement == null) {
                                throw new RuntimeException("sql配置不存在:" + DefaultSession.class.getName());
                            }
                            if (mappedStatement.getDbAction().equals("select")) {
                                // 如果返回值类型是泛型,调用selectList,否则selectOne
                                if (resultType instanceof ParameterizedType) {
                                    return selectList(statementId, params);
                                } else {
                                    return selectOne(statementId, params);
                                }
                            } else if (mappedStatement.getDbAction().equals("insert")
                                    || mappedStatement.getDbAction().equals("delete")
                                    || mappedStatement.getDbAction().equals("update")) {
                                return executeUpdate(statementId, params);
                            } else {
                                throw new RuntimeException("mapper配置文件错误:");
                            }
                        }
                    });
            return (T) proxy;
        }
    
        @Override
        public void close() {
            try {
                baseExecutor.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        @Override
        public void commit() {
            try {
                baseExecutor.commit();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
    }
    
    
    
    package com.Ipersistence.session;
    
    /**
     * SqlSessionFactory工厂类:生产SqlSession
     * @author linxu
     *
     */
    public interface SqlSessionFactory{
        public SqlSession openSession();
    }
    
    
    
    package com.Ipersistence.session;
    
    import com.Ipersistence.configuration.Configuration;
    /**
     * 
     * @author linxu
     *
     */
    public class DefaultSqlSessionFactory implements SqlSessionFactory {
        private Configuration configuration;
    
    
        public DefaultSqlSessionFactory(Configuration configuration) {
            this.configuration = configuration;
        }
    
        @Override
        public SqlSession openSession() {
            // TODO Auto-generated method stub
            return new DefaultSession(configuration);
        }
    
    }
    
    
    
    
    package com.Ipersistence.session;
    
    import java.beans.PropertyVetoException;
    import java.io.InputStream;
    
    import org.dom4j.DocumentException;
    
    import com.Ipersistence.configuration.Configuration;
    import com.Ipersistence.configuration.XMLConfigerBuilder;
    
    /**
     * SqlSessionFactoryBuilder,利用配置构建个SqlSessionFactory工厂
     * 
     * @author linxu
     * 
     */
    public class SqlSessionFactoryBuilder {
        private Configuration configuration;
    
        /**
         * 
         * @param inputStream
         * @return
         * @throws PropertyVetoException
         * @throws DocumentException
         */
        public SqlSessionFactory builder(InputStream inputStream) throws DocumentException, PropertyVetoException {
            XMLConfigerBuilder xMLConfigerBuilder = new XMLConfigerBuilder();
            this.configuration = xMLConfigerBuilder.parseConfig(inputStream);
            DefaultSqlSessionFactory defaultSqlSessionFactory = new DefaultSqlSessionFactory(configuration);
            return defaultSqlSessionFactory;
        }
    }
    
    
    Io读取
    
    package com.Ipersistence.io;
    
    import java.io.InputStream;
    /**
     * 
     * @author linxu
     *
     */
    public class Resources {
         /**
          * 
          * @param path
          * @return
          */
        public static InputStream getResourceAsStream(String path) {
            return Resources.class.getClassLoader().getResourceAsStream(path);
        }
    }
    
    
    
    Executor实现(主要封装了jdbc对数据库的操作)
    
    package com.Ipersistence.executor;
    
    import java.sql.SQLException;
    import java.util.List;
    
    import com.Ipersistence.boundsql.BoundSql;
    import com.Ipersistence.configuration.Configuration;
    import com.Ipersistence.configuration.MappedStatement;
    /**
     * 
     * @author linxu
     *
     */
    public interface Executor {
        public <E> List<E> query(Configuration configuration, MappedStatement mappedStatement, Object... params)
                throws SQLException, Exception, SecurityException;
    
        public int executeUpdate(Configuration configuration, MappedStatement mappedStatement, Object... params)
                throws SQLException, Exception, SecurityException;
    
        // 关闭连接操作
        public void close() throws SQLException;
    
        public BoundSql getBoundSql(String sql);
        
        public void commit() throws SQLException;
    
    }
    
    
    
    package com.Ipersistence.executor;
    
    import java.beans.PropertyDescriptor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.ResultSetMetaData;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;
    
    import com.Ipersistence.boundsql.BoundSql;
    import com.Ipersistence.configuration.Configuration;
    import com.Ipersistence.configuration.MappedStatement;
    import com.Ipersistence.utils.GenericTokenParser;
    import com.Ipersistence.utils.ParameterMapping;
    import com.Ipersistence.utils.ParameterMappingTokenHandler;
    /**
     * 
     * @author linxu
     *
     */
    public class BaseExecutor implements Executor {
        private Connection connection;
    
        @SuppressWarnings("unchecked")
        @Override
        public <E> List<E> query(Configuration configuration, MappedStatement mappedStatement, Object... params)
                throws SQLException, Exception, SecurityException {
            this.connection = configuration.getDataSource().getConnection();
            String sql = mappedStatement.getSql();
            BoundSql boundSql = getBoundSql(sql);
            PreparedStatement preparedStatement = connection.prepareStatement(boundSql.getSqlText());
            List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
            if(parameterMappings!=null&&!parameterMappings.isEmpty()) {
            for (int i = 0; i < parameterMappings.size(); i++) {
                ParameterMapping parameterMapping = parameterMappings.get(i);
                String valuename = parameterMapping.getContent();
                // 鎷垮埌杩欎釜瀛楁�瀵硅薄
                Field field = mappedStatement.getParamterType().getDeclaredField(valuename);
                // 璁剧疆鏉冮檺
                field.setAccessible(true);
                Object o = field.get(params[0]);
                preparedStatement.setObject(i + 1, o);
            }
            }
            // 鎵ц�鏁版嵁鏌ヨ�
            ResultSet resultSet = preparedStatement.executeQuery();
            // 瑙f瀽鏁版嵁
            List<E> result_list = new ArrayList<>();
            while (resultSet.next()) {
                ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
                E e = (E) mappedStatement.getResultType().newInstance();
                for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
                    String columnname = resultSetMetaData.getColumnName(i);
                    Object value = resultSet.getObject(columnname);
                    PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnname,
                            mappedStatement.getResultType());
                    Method method = propertyDescriptor.getWriteMethod();
                    method.invoke(e, value);
                }
                result_list.add(e);
            }
            return result_list;
        }
    
        @Override
        public int executeUpdate(Configuration configuration, MappedStatement mappedStatement, Object... params)
                throws SQLException, Exception, SecurityException {
            // 瀹屾垚瀵规暟鎹�簱鑳¤�闂�
            // 1鑾峰彇杩炴帴
            connection = configuration.getDataSource().getConnection();
            // 鍒ゆ柇鏄�惁鏄��缃�嚜鍔ㄦ彁浜�
            if (mappedStatement.isAutoCommit())
                connection.setAutoCommit(true);
            // 鍏抽棴鑷�姩鎻愪氦
            connection.setAutoCommit(false);
            // 2鑾峰彇Sql
            String sql = mappedStatement.getSql();
            // 3杞�崲sql,灏嗚В鏋�
            BoundSql boundSql = getBoundSql(sql);
            // 4鑾峰彇棰勫�鐞嗗�璞�reparedStatement
            PreparedStatement preparedStatement = connection.prepareStatement(boundSql.getSqlText());
            // 鑾峰彇鍙傛暟瀵硅薄绫诲瀷
            Class<?> parameterClass = mappedStatement.getParamterType();
            // 鏁版嵁鍙傛暟璁剧疆
            List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
            for (int i = 0; i < parameterMappings.size(); i++) {
                ParameterMapping parameterMapping = parameterMappings.get(i);
                String content = parameterMapping.getContent();
                // 鑾峰彇灞炴�у�璞�
                Field field = parameterClass.getDeclaredField(content);
                // 璁剧疆鏉冮檺
                field.setAccessible(true);
                // 鑾峰彇灞炴�у�璞″��
                Object o = field.get(params[0]);
                // 瑷�疆鍙傛暟
                preparedStatement.setObject(i + 1, o);
            }
    
            // 鎵ц�sql
            return preparedStatement.executeUpdate();
        }
    
        @Override
        public void close() throws SQLException {
            if (connection != null) {
                this.connection.close();
            }
    
        }
    
        @Override
        public BoundSql getBoundSql(String sql) {
            final ParameterMappingTokenHandler parameterMappingTokenHandler = new ParameterMappingTokenHandler();
            final GenericTokenParser genericTokenParser = new GenericTokenParser("#{", "}", parameterMappingTokenHandler);
            String sqlText = genericTokenParser.parse(sql);
            List<ParameterMapping> parameterMappings = parameterMappingTokenHandler.getParameterMappings();
            return new BoundSql.Builder().putSqlText(sqlText).putParameterMappings(parameterMappings).builder();
        }
    
        @Override
        public void commit() throws SQLException {
            // 濡傛灉宸茬粡璁剧疆涓鸿嚜鍔ㄦ彁浜や簡锛屽氨娌″繀瑕佸啀閲嶅�鎻愪氦
            if (connection != null) {
                if (connection.getAutoCommit() == true) {
                    return;
                }
                try {
                    connection.commit();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    
    }
    
    
    sql转换(和mybatis原理一致)
    
    package com.Ipersistence.boundsql;
    
    import java.util.List;
    
    import com.Ipersistence.utils.ParameterMapping;
    
    /**
     * 转换sql
     * @author linxu
     *
     */
    public class BoundSql {
        private String sqlText;
        private List<ParameterMapping> parameterMappings;
    
        public String getSqlText() {
            return sqlText;
        }
    
        public void setSqlText(String sqlText) {
            this.sqlText = sqlText;
        }
    
        public List<ParameterMapping> getParameterMappings() {
            return parameterMappings;
        }
    
        public void setParameterMappings(List<ParameterMapping> parameterMappings) {
            this.parameterMappings = parameterMappings;
        }
    
        public BoundSql(Builder builder) {
            this.sqlText = builder.sqlText;
            this.parameterMappings = builder.parameterMappings;
        }
    
        public static class Builder {
            private String sqlText;
            private List<ParameterMapping> parameterMappings;
    
            public Builder putSqlText(String sql) {
                this.sqlText = sql;
                return this;
            }
    
            public Builder putParameterMappings(List<ParameterMapping> parameterMappings) {
                this.parameterMappings = parameterMappings;
                return this;
            }
    
            public BoundSql builder() {
                return new BoundSql(this);
            }
    
        }
    
    }
    
    
    以下工具类是我从mybatis拷贝而来的,也贴上
    
    /**
     *    Copyright 2009-2017 the original author or authors.
     *
     *    Licensed under the Apache License, Version 2.0 (the "License");
     *    you may not use this file except in compliance with the License.
     *    You may obtain a copy of the License at
     *
     *       http://www.apache.org/licenses/LICENSE-2.0
     *
     *    Unless required by applicable law or agreed to in writing, software
     *    distributed under the License is distributed on an "AS IS" BASIS,
     *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     *    See the License for the specific language governing permissions and
     *    limitations under the License.
     */
    package com.Ipersistence.utils;
    
    /**
     * @author Clinton Begin
     */
    public class GenericTokenParser {
    
      private final String openToken; //�?始标�?
      private final String closeToken; //结束标记
      private final TokenHandler handler; //标记处理�?
    
      public GenericTokenParser(String openToken, String closeToken, TokenHandler handler) {
        this.openToken = openToken;
        this.closeToken = closeToken;
        this.handler = handler;
      }
    
      /**
       * 解析${}�?#{}
       * @param text
       * @return
       * 该方法主要实现了配置文件、脚本等片段中占位符的解析�?�处理工作,并返回最终需要的数据�?
       * 其中,解析工作由该方法完成,处理工作是由处理器handler的handleToken()方法来实�?
       */
      public String parse(String text) {
        // 验证参数问题,如果是null,就返回空字符串�?
        if (text == null || text.isEmpty()) {
          return "";
        }
    
        // 下面继续验证是否包含�?始标签,如果不包含,默认不是占位符,直接原样返回即可,否则继续执行�??
        int start = text.indexOf(openToken, 0);
        if (start == -1) {
          return text;
        }
    
       // 把text转成字符数组src,并且定义默认偏移量offset=0、存储最终需要返回字符串的变量builder�?
        // text变量中占位符对应的变量名expression。判断start是否大于-1(即text中是否存在openToken),如果存在就执行下面代码
        char[] src = text.toCharArray();
        int offset = 0;
        final StringBuilder builder = new StringBuilder();
        StringBuilder expression = null;
        while (start > -1) {
         // 判断如果�?始标记前如果有转义字符,就不作为openToken进行处理,否则继续处�?
          if (start > 0 && src[start - 1] == '\') {
            builder.append(src, offset, start - offset - 1).append(openToken);
            offset = start + openToken.length();
          } else {
            //重置expression变量,避免空指针或�?��?�数据干扰�??
            if (expression == null) {
              expression = new StringBuilder();
            } else {
              expression.setLength(0);
            }
            builder.append(src, offset, start - offset);
            offset = start + openToken.length();
            int end = text.indexOf(closeToken, offset);
            while (end > -1) {////存在结束标记�?
              if (end > offset && src[end - 1] == '\') {//如果结束标记前面有转义字符时
                // this close token is escaped. remove the backslash and continue.
                expression.append(src, offset, end - offset - 1).append(closeToken);
                offset = end + closeToken.length();
                end = text.indexOf(closeToken, offset);
              } else {//不存在转义字符,即需要作为参数进行处�?
                expression.append(src, offset, end - offset);
                offset = end + closeToken.length();
                break;
              }
            }
            if (end == -1) {
              // close token was not found.
              builder.append(src, start, src.length - start);
              offset = src.length;
            } else {
              //首先根据参数的key(即expression)进行参数处理,返回?作为占位�?
              builder.append(handler.handleToken(expression.toString()));
              offset = end + closeToken.length();
            }
          }
          start = text.indexOf(openToken, offset);
        }
        if (offset < src.length) {
          builder.append(src, offset, src.length - offset);
        }
        return builder.toString();
      }
    }
    
    
    
    package com.Ipersistence.utils;
    
    public class ParameterMapping {
    
        private String content;
    
        public ParameterMapping(String content) {
            this.content = content;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    }
    
    
    package com.Ipersistence.utils;
    
    import java.util.ArrayList;
    import java.util.List;
    
    
    
    
    public class ParameterMappingTokenHandler implements TokenHandler {
        private List<ParameterMapping> parameterMappings = new ArrayList<ParameterMapping>();
    
        // context是参数名�? #{id} #{username}
    
        public String handleToken(String content) {
            parameterMappings.add(buildParameterMapping(content));
            return "?";
        }
    
        private ParameterMapping buildParameterMapping(String content) {
            ParameterMapping parameterMapping = new ParameterMapping(content);
            return parameterMapping;
        }
    
        public List<ParameterMapping> getParameterMappings() {
            return parameterMappings;
        }
    
        public void setParameterMappings(List<ParameterMapping> parameterMappings) {
            this.parameterMappings = parameterMappings;
        }
    
    }
    
    
    
    /**
     *    Copyright 2009-2015 the original author or authors.
     *
     *    Licensed under the Apache License, Version 2.0 (the "License");
     *    you may not use this file except in compliance with the License.
     *    You may obtain a copy of the License at
     *
     *       http://www.apache.org/licenses/LICENSE-2.0
     *
     *    Unless required by applicable law or agreed to in writing, software
     *    distributed under the License is distributed on an "AS IS" BASIS,
     *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     *    See the License for the specific language governing permissions and
     *    limitations under the License.
     */
    package com.Ipersistence.utils;
    
    /**
     * @author Clinton Begin
     */
    public interface TokenHandler {
      String handleToken(String content);
    }
    
    
    
    
    测试:
    
    
    package com.test;
    
    public class User {
    
        private int id;
        private String username;
        private String userid;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getUserid() {
            return userid;
        }
        public void setUserid(String userid) {
            this.userid = userid;
        }
        @Override
        public String toString() {
            return "User [id=" + id + ", username=" + username + ", userid=" + userid + ", getId()=" + getId()
                    + ", getUsername()=" + getUsername() + ", getUserid()=" + getUserid() + ", getClass()=" + getClass()
                    + ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]";
        }
        
    }
    
    
    //dao接口
    package com.test;
    
    import java.util.List;
    
    public interface UserDao {
    public List<User>selectUser(User user);
    }
    
    
    
    package com.test;
    
    import java.beans.PropertyVetoException;
    
    import org.dom4j.DocumentException;
    
    import com.Ipersistence.io.Resources;
    import com.Ipersistence.session.SqlSession;
    import com.Ipersistence.session.SqlSessionFactory;
    import com.Ipersistence.session.SqlSessionFactoryBuilder;
    
    public class UserTest {
    public static void main(String[] args) throws DocumentException, PropertyVetoException {
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
                .builder(Resources.getResourceAsStream("SqlMapConfig.xml"));
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        User user=new User();
        
        
        System.err.println(userDao.selectUser(user).toString());
        sqlSession.close();
    }
    
    }

    ------------恢复内容结束------------

  • 相关阅读:
    Open_basedir 开启后项目变慢
    PHP导入百万级excel数据方案
    使用Python统计项目代码行数(Python3.X)
    AttributeError: '_io.TextIOWrapper' object has no attribute 'xreadlines'
    startTime = time.clock()AttributeError: module 'time' has no attribute 'clock
    SyntaxError: Missing parentheses in call to 'print'. Did you mean print
    误删 Win10 应用商店应该如何恢复?
    win10无法开启Windows Defender Firewall服务,错误1058
    设备管理器里面的AAP Server是什么?
    layui——Cannot create property 'LAY_TABLE_INDEX' on number '2'
  • 原文地址:https://www.cnblogs.com/mature1021/p/13371049.html
Copyright © 2011-2022 走看看