002.持久層框架設計實現及MyBatis源碼分析-----自定義持久層框架

一.JDBC問題分析

  1. JDBC使用
/**
     * JDBC連接
     * @param args
     */
    public static void main(String[] args) {
        Connection connection = null ;
        PreparedStatement preparedStatement = null ;
        ResultSet resultSet = null ;

        try {
            //加載數據庫驅動
            Class.forName("com.mysql.jdbc.Driver");
            //通過驅動管理類獲取數據庫連接
            connection = DriverManager.getConnection("dbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8",
                    "root","root");
            //定義Sql語句
            String sql = "SELECT * FROM sys_user";
            //獲取預處理statement
            preparedStatement = connection.prepareStatement(sql);
            //向數據庫發起請求
            resultSet = preparedStatement.executeQuery();
            //遍歷結果集
            while(resultSet.next()) {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                //封裝數據
                user.setId(id);
                user.setName(name);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //釋放資源
        }
  1. JDBC存在問題
  1. 數據庫創建連接,釋放頻繁造成資源浪費
  2. sql,配置信息硬編碼,代碼不易維護
  1. 解決方案
  1. 使用連接池
  2. 使用配置文件
  1. 自定義框架設計
  1. 使用端:
    (1). 提供核心配置
    (2). sqlMapConfig.xml: 存放數據源信息
    (3). mapping.xml: sql語句配置信息
  1. 框架端:
    (1). 讀取配置文件
    (2). 解析配置文件
    (3). 創建sqlSessionFactory
    (4). 創建sqlSession接口及實現類,封裝CRUD方法

二.自定義框架實現

1. 使用端實現
  1. sqlMapConfig.xml
<configuration>

    <property name="driverClass" value="com.mysql.jdbc.Driver"></property>  <!--驅動-->
    <property name="jdbcUrl" value="jdbc:mysql:///zdy_mybatis"></property>  <!--數據庫路徑-->
    <property name="user" value="root"></property>  <!--用戶-->
    <property name="password" value="root"></property>  <!--密碼-->

    <mapper resource="UserMapper.xml"></mapper>

</configuration>
  1. mapping.xml
<mapper namespace="user">

    <!--sql的唯一標識,用namespace.id 區分-->
    <select id="selectList" resultType="com.lgj.user" paramsType="com.lgj.user">
        select * from user where id = #{id}
    </select>
</mapper>
2.框架端
  1. 說明:自定義持久框架本身:本質就是對JDBC代碼的封裝
  2. 步驟:
  1. 加載配置文件:根據配置文件路徑,加載配置文件成字節輸入流,存儲在內存中
    創建Resources類 方法:InputStream getResourceAsStream(String path)
  1. 創建兩個JavaBean: (容器對象):存放的就是配置文件解析出來的內容
    Configuration: 核心配置類 : 存放sqlMapConfig.xml解析出來的內容
    MappedStatement: 映射配置類:存放mapper.xml解析出來內容
  1. 解析配置文件:dom4j
    創建類:SqlSessionFactoryBuilder
    第一:使用dom4j解析配置文件,將解析出來的內容封裝到容器對象中
    第二:創建sqlSessionFactory對象;生產sqlSession:會話對象
  1. 創建SqlSessionFacoty接口及實現類DefaultSqlSessionFacory
    第一:openSession() : 生產sqlSession
  1. 創建SqlSession接口及實現類DefaultSession
    定義對數據庫的crud操作:
  1. 創建Executor接口及實現類SimpleExecutor實現類
    query : 執行的就是JDBC代碼
三.Resources類定義
  1. 定義Resources生成字節流
 /**
     * 獲取文件輸入流
     * @param path
     * @return
     */
    public static InputStream getResourceAsSteam(String path) {
        InputStream resourcesStream = Resources.class.getResourceAsStream(path);
        return resourcesStream ;
    }
四.容器對象定義
  1. MappedStatement : 存放UserMapping.xml中數據,每一個sql對應一個MappedStatement
public class MappedStatement {
    //id
    private Integer id;
    //sql語句
    private String sql;
    //請求參數
    private String paramterType;
    //返回值
    private String resultType;
    }
  1. Configuration: 存放sqlMapConfig對象
public class Configuration {

    //sqlMapConfig.xml 中數據最終會生產一個DataSource
    private DataSource dataSource ;

    //關聯UserMapping.xml中sql key: 爲ID
    private Map<String,MappedStatement> mappedStatementMap = new HashMap<String, MappedStatement>();
    }
五.解析配置文件sqlMapConfig.xml中內容
  1. 使用dom4j解析xml內容,封裝DataSource
   //1.解析配置文件,封裝Configuration
    public void analysis(InputStream in) {
        Document document = new SAXReader().read(inputStream);
        Element rootElement = document.getRootElement();
        List<Element> propertyElements =
                rootElement.selectNodes("//property");
        Properties properties = new Properties();
        for (Element propertyElement : propertyElements) {
            String name = propertyElement.attributeValue("name");
            String value = propertyElement.attributeValue("value");
            properties.setProperty(name,value);
        }
        //連接池
        ComboPooledDataSource comboPooledDataSource = new
                ComboPooledDataSource();
        comboPooledDataSource.setDriverClass(properties.getProperty("driverClass"));
        comboPooledDataSource.setJdbcUrl(properties.getProperty("jdbcUrl"));
        comboPooledDataSource.setUser(properties.getProperty("username"));
        comboPooledDataSource.setPassword(properties.getProperty("password"));
        //填充configuration
        configuration.setDataSource(comboPooledDataSource);
    }
六. 解析映射配置文件mapper.xml
  1. mapper.xml部分
		//mapper部分
        List<Element> mapperElements = rootElement.selectNodes("//mapper");
        XMLMapperBuilder xmlMapperBuilder = new
                XMLMapperBuilder(configuration);
        for (Element mapperElement : mapperElements) {
            String mapperPath = mapperElement.attributeValue("resource");
            InputStream resourceAsSteam =
                    Resources.getResourceAsSteam(mapperPath);
            xmlMapperBuilder.parse(resourceAsSteam);
        }
        return configuration;
七.會話對象sqlSession類/方法定義
  1. sqlSession接口及DefaultSqlSession實現類
public interface SqlSession {
	public <E> List<E> selectList(String statementId, Object... param) throws
Exception;
	public <T> T selectOne(String statementId,Object... params) throws
Exception;
	public void close() throws SQLException;
}
  1. DefaultSqlSession
八.查詢對象Query定義
  1. 解析#{id} 使用myBatis底層工具類
  2. Query類
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章