D36-Mybatatis框架

一、框架的概述

1.1 什么是框架

  • 框架: 是整个或部分系统的可重用设计。是某种应用的半成品 ,是一组组件。

1.2 要解决的问题

  • 解决的最重要的一个问题是**技术整合 ** 的问题。
  • 框架一般处在低层应用平台(如J2EE)和高层业务逻辑之间的中间层。

1.3 分层开发的常见框架

1.3.1解决数据的持久化问题的Mybatis框架

  • 是一个dao层(持久层)的框架,是apache下的开源框架(Ibatis)。内部封装了jdbc 操作,使开发者只需要关注SQL本身,而不需要花费精力去处理例如注册驱动,创建connection,创建statement,封装statement,封装结果集等jdbc 繁杂的代码操作。(搭建好框架后我们只需要提供sql和返回值既就可以了。)

1.3.2 解决WEB层问题的MVC框架

1.3.3 解决技术整合问题的框架–spring

Spring框架是由于软件开发 的复杂性而创建的。

  • 目的: 解决企业应用开发的复杂性
  • 功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能。
  • 范围:任何java应用
  • Spring是一个轻量级控制反转(loC)和面向切面(AOP) 的容器框架。

1.2 JDBC编程分析

JDBC: 原始
Class.forName(“com.mysql.jdbc.driver”);  // 加载驱动
Connection conn = DriverManager.getConnection(url,name,pwd); // 创建连接
PreparedStatement ps = conn.PreparedStatement();  // 获得语句执行者
String sql = "select * from User  "; // 编写sql
ResultSet rs = ps.query(sql);  // 执行sql
while(rs.next()){
  // 处理结果集
   id
   name
   pwd   // 元数据  -- 
}
// 关闭连接

1.2.1 JDBC操作数据库的弊端

  • 连接数据库的基本信息都是硬编码到代码中
    • 将动态的数据抽离成xml配置文件
  • 动态的sql语句和返回值也是硬编码到代码中
    • 将动态的sql和返回值抽离成xml配置文件
  • jdbc操作数据库流程繁琐
    • 抽取工具类

二 、Mybatis框架的使用步骤

  • 创建maven项目
  • 引入Mybatis框架所需的jar包
  • 导入Mybatis框架的核心配置文件(xml)
    1. SqlMapConfig.xml(连接数据库的基本信息 username,password,url ,driver)

三、自定义MyBatis框架

3.1 Mybatis框架解决的问题

  • 准备数据库和表 以及表数据
  • 配置文件
  • 1.数据库信息(核心配置文件SqlMapConfig.xml) 存放java连接数据库的基本信息
    1. Sql语句(sql配置文件:UserMapper.xml) 存放要执行的sql语句(eg:select * from 表名)

3.2 自定义Mybatis图解

在这里插入图片描述

3.3自定义Mybatis实现步骤

  1. 由图可知,需要先配置xml 文件
    • 1.配置pom.xml
      • 导入mybatis jar包文件以及其他文件jar包
 <!-- 日志信息 -->
       <dependency>
           <groupId>log4j</groupId>
           <artifactId>log4j</artifactId>
           <version>1.2.12</version>
       </dependency>
       <!-- 解析xml的jar包 -->
       <dependency>
           <groupId>dom4j</groupId>
           <artifactId>dom4j</artifactId>
           <version>1.6.1</version>
       </dependency>
       <!-- xpath的jar包 -->
       <dependency>
           <groupId>jaxen</groupId>
           <artifactId>jaxen</artifactId>
           <version>1.1.6</version>
       </dependency>
       <!-- mysql驱动包 -->
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>5.1.6</version>
       </dependency>
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.0</version>
       </dependency>
    • 2.配置UserMapper.xnl文件
<!--namespace:名称空间
		区分模块
	唯一:namespace.id
 -->  
<mapper namespace="com.itheima.dao.UserDao">
<!-- select 查询 -->   
	<select id="findAll" resultType="com.itheima.domain.User">
		select *  from user   
	</select>    
</mapper>   
      • 得到Mapper实体类
private String sql;
 private  String resultType;
      • get,set,tostring方法自行补上。
    • 3.配置SqlMapConfig.xml文件
<!--配置所有sql的映射文件-->
  <mappers>
    <!--相对路径-->
    <mapper resource="UserMapper.xml"></mapper>
  </mappers>
    • 得到Configuration实体
 private  String  username;
 private  String password;
 private  String url;
 private  String driver;
 private Map<String ,Mapper> mappers;
    • 代码的其他部分自行补上。get,set,tostring方法。
  1. 创建SqlSessionFactoryBuilder
/**
 * 1.解析核心配置文件,得到Configuration实体对象
 * 2.创建SqlSessionFactory对象,并将cf传递给SqlSessionFactory
 */
public class SqlSessionFactoryBuilder {

    public SqlSessionFactory builder(InputStream is) throws Exception {

        //1.解析核心配置文件,得到Configuration实体对象
        Configuration cfg = XMLConfigBuilder.buildConfiguration(is);
        //2. 创建SqlSessionFactory对象,并将cfg传递给SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactory(cfg);
        return sqlSessionFactory;

    }
}
  1. 创建SqlSessionFactory
public class SqlSessionFactory {
    private Configuration cfg;
    public SqlSessionFactory(Configuration cfg){
        this.cfg=cfg;
    }
    //创建SqlSession对象的实现类
    public SqlSession openSession(){
        return new DefaultSqlSession(cfg);
    }
}
  1. 创建SqlSession接口
public interface SqlSession {
    <T> List <T> findAll(String mapperId) throws Exception;
}
  1. 创建DefaultSqlSession
public class DefaultSqlSession implements SqlSession {
    private Configuration cfg;
    public DefaultSqlSession(Configuration cfg){
        this.cfg=cfg;

    }

    /**
     * 查询所有数据
     *      加载 驱动,执行sql,返回结果集
     * @param mapperId
     * @param <T>
     * @return
     */
    public <T> List<T> findAll(String mapperId) throws Exception {
        Map<String, Mapper> mappers = cfg.getMappers();
        //Mapper
        Mapper mapper = mappers.get(mapperId);
        //获取要执行的sql语句
        String sql = mapper.getSql();
        //获取响应的返回值的全限定名
        String resultType = mapper.getResultType();
        Executor executor = new Executor(cfg);

        List<T> list = executor.executeQuery(sql, resultType);
        return list;
    }
}
  1. 测试:
public class TestMybatis {
@Test
    public void testFindAll() throws Exception {
        //1.创建SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        //解析配置文件
        InputStream is = this.getClass().getClassLoader().getResourceAsStream("SqlMapConfig.xml");
        //2.SqlSessionFactory
        SqlSessionFactory builder = sqlSessionFactoryBuilder.builder(is);
        //3.通过SqlSessionFactory得到 SqlSession对象
        SqlSession sqlSession = builder.openSession();
        //4.调用sqlSession的方法,获取结果集
        List<User> list = sqlSession.findAll("com.itheima.dao.UserDao.findAll");
        for (User user : list) {
            System.out.println(user);
        }
    }
}

四 、使用注解的方式实现Mybatis

在注解上提供sql和返回值的全限定名

4.1 SelectAll注解

/**
 * 代替sql映射文件
 *      sql:
 *      resultType:
 */
@Target(ElementType.METHOD)//设置注解的使用位置 方法上
@Retention(RetentionPolicy.RUNTIME)//设置注解存活的时期
public @interface SelectAll {
    String sql();
    String resultType();
}

4.2 **重新编写DefaultSqlSession **

public class DefaultSqlSession implements SqlSession {
    private Configuration cfg;
    public DefaultSqlSession(Configuration cfg){
        this.cfg=cfg;

    }

    /**
     * 查询所有数据
     *      加载 驱动,执行sql,返回结果集
     * @param mapperId
     * @param <T>
     * @return
     */
    public <T> List<T> findAll(String mapperId) throws Exception {
        Map<String, Mapper> mappers = cfg.getMappers();
        //Mapper
        Mapper mapper = mappers.get(mapperId);
        //获取要执行的sql语句
        String sql = mapper.getSql();
        //获取响应的返回值的全限定名
        String resultType = mapper.getResultType();
        Executor executor = new Executor(cfg);

        List<T> list = executor.executeQuery(sql, resultType);
        return list;
    }

    @Override
    /**
     * 注解的方式
     */
    public <T> List<T> findAll(String sql, String resultType) throws Exception {
        Executor executor = new Executor(cfg);
        List<T> list = executor.executeQuery(sql, resultType);
        return list;
    }

    /**
     * 使用动态代理生成接口的实现类对象
     * @param clazz
     * @param <E>
     * @return
     */
    public <E> E getMapper(Class clazz) {
        E proxy =(E) Proxy.newProxyInstance(
                clazz.getClassLoader(),//类加载器
                new Class[]{clazz}, //代理类需要实现的接口
                new InvocationHandler() {//处理业务逻辑
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                   String name=method.getName();//获取执行的方法
                   if ("findAll".equals(name)){
                            //查询所有信息,
                            //获取代理类所实现的接口的权限定名称(命名空间)
                     String nameSpace = proxy.getClass().getGenericInterfaces()[0].getTypeName();
                            //获取id的值,(当前执行的方法名称)
                     String mapperId = nameSpace+"."+name;
                     List list = findAll(mapperId);
                     return list;
                        }
                  return null;
                    }
                }
        );
        return proxy    ;
    }
}

4.3 测试类

public class TestMybatis {
@Test
    public void testFindAll() throws Exception {
        //1.创建SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        //解析配置文件
        InputStream is = this.getClass().getClassLoader().getResourceAsStream("SqlMapConfig.xml");
        //2.SqlSessionFactory
        SqlSessionFactory builder = sqlSessionFactoryBuilder.builder(is);
        //3.通过SqlSessionFactory得到 SqlSession对象
        SqlSession sqlSession = builder.openSession();
        //4.调用sqlSession的方法,获取结果集
       // List<User> list = sqlSession.findAll("com.itheima.dao.UserDao.findAll");
   // UserDaoImpl dao = new UserDaoImpl();
    //使用动态代理的方式生成UserDao的实现类

    UserDao dao = sqlSession.getMapper(UserDao.class);
    List<User> list = dao.findAll();
    for (User user : list) {
            System.out.println(user);
        }
	}
  }

猜你喜欢

转载自blog.csdn.net/qq_33852347/article/details/84919503
36