mybatis开发dao的方法——(三)

------------------------1.    SqlSession使用范围-------------------

  

  1.1     SqlSessionFactoryBuilder

 通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory

将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder。

在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。

 

  1.2     SqlSessionFactory

通过SqlSessionFactory创建SqlSession,使用单例模式管理sqlSessionFactory(工厂一旦创建,使用一个实例)。

将来mybatis和spring整合后,使用单例模式管理sqlSessionFactory。

 

  1.3     SqlSession

SqlSession是一个面向用户(程序员)的接口。

SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)、selectList(返回单个或多个对象)、。

 

SqlSession是线程不安全的,在SqlSesion实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。

 

SqlSession最佳应用场合在方法体内,定义成局部变量使用。

 

-----------2.   原始dao开发方法(程序员需要写dao接口和dao实现类)--------

  

1.    思路

程序员需要写dao接口和dao实现类。

需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession

 

2.    dao接口

 

 

 

 

3.dao实现类

public class UserDaoImpl implements UserDao {

    // 需要向dao实现类中注入SqlSessionFactory
    // 这里通过构造方法注入
    private SqlSessionFactory sqlSessionFactory;

    public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    @Override
    public User findUserById(int id) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();

        User user = sqlSession.selectOne("test.findUserById", id);

        // 释放资源
        sqlSession.close();

        return user;

    }

    @Override
    public void insertUser(User user) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //执行插入操作
        sqlSession.insert("test.insertUser", user);

        // 提交事务
        sqlSession.commit();

        // 释放资源
        sqlSession.close();

    }

    @Override
    public void deleteUser(int id) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //执行插入操作
        sqlSession.delete("test.deleteUser", id);

        // 提交事务
        sqlSession.commit();

        // 释放资源
        sqlSession.close();

    }

}

 

 

4.     测试代码:

 

5.  原始 dao开发问题

1、dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。

 

2、调用sqlsession方法时将statement的id硬编码了

 

3、调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。

 

--------------3.   mapper代理开发程序员只需要写mapper接口----------------------

1    思路(mapper代理开发规范)

程序员还需要编写mapper.xml映射文件

程序员编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。

开发规范:

1、在mapper.xml中namespace等于mapper接口地址

2、mapper.java接口中的方法名和mapper.xml中statement的id一致

 

3、mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。

 

4、mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。

 

总结:

以上开发规范主要是对下边的代码进行统一生成:

User user = sqlSession.selectOne("test.findUserById", id);

sqlSession.insert("test.insertUser", user);

 

2.    mapper.java

  

 

3.    mapper.xml

  

4.    在SqlMapConfig.xml中加载mapper.xml

 

5.测试

 

 

6.总结:

如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库。

如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库。

 

 

 

附一个完整的mapper开发的配置文件以及测试:(Maven结构)

0.目录结构:

 

 

1.Exam表结构:

 

 

2.Exam.java与ExamExample.java都是mybatis逆向工程导出来的:

 

 

3.ExamMapper,java与ExamMapper.xml也是mybatis逆向工程导出来的:

 

 

4.SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <!-- 加载属性文件 -->
    <properties resource="db.properties">
        <!--properties中还可以配置一些属性名和属性值 -->
        <!-- <property name="jdbc.driver" value=""/> -->
    </properties>
    <!-- 全局配置参数,需要时再设置 -->
    <!-- <settings> </settings> -->

    <!-- 别名定义 -->
    <typeAliases>

        <!-- 针对单个别名定义 type:类型的路径 alias:别名 -->
        <!-- <typeAlias type="cn.itcast.mybatis.po.User" alias="user"/> -->
        <!-- 批量别名定义 指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大写或小写都可以) -->
        <package name="cn.itcast.mybatis.po" />

    </typeAliases>

    <!-- 和spring整合后 environments配置将废除 -->
    <environments default="development">
        <environment id="development">
            <!-- 使用jdbc事务管理,事务控制由mybatis -->
            <transactionManager type="JDBC" />
            <!-- 数据库连接池,由mybatis管理 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
            </dataSource>
        </environment>
    </environments>
    <!-- 加载 映射文件 -->
    <mappers>
        <!-- 批量加载mapper 指定mapper接口的包名,mybatis自动扫描包下边所有mapper接口进行加载 遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 
            中 上边规范的前提是:使用的是mapper代理方法 -->
        <package name="cn.xm.exam.mapper" />

    </mappers>

</configuration>

 

 

5.测试代码:

package cn.xm.exam.daoTest;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import cn.xm.exam.bean.exam.Exam;
import cn.xm.exam.mapper.exam.ExamMapper;

public class PageHelperTest {

    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void setUp() throws IOException {
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void test1() {
         SqlSession sqlSession = sqlSessionFactory.openSession();
         //创建UserMapper对象
         ExamMapper examMapper = sqlSession.getMapper(ExamMapper.class);
         Exam exam = examMapper.selectByPrimaryKey("02e23c37781b4f71a84c5074a8b844d1");
         System.out.println(exam.toString());
    }
}

 

posted @ 2017-08-06 15:50  QiaoZhi  阅读(414)  评论(0编辑  收藏  举报