一、什么是框架

  • 它是我们软件开发中的一套解决方案,不同的框架解决不同的问题
  • 使用框架的好处:

    • 框架封装了很多的细节,是开发者可以使用极简的方式实现功能,大大提高开发效率

二、三层架构

2.1 表现层

  • 用于展示数据

2.2 业务层

  • 处理业务需求

2.3 持久层

  • 和数据库交互

三、持久层技术的解决方案

3.1 JDBC技术

  1. Connection
  2. PreparedStatement
  3. ResultSet
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("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8","root", "root"); 
        //定义sql语句 ?表示占位符 
        String sql = "select * from user where username = ?";
        //获取预处理statement 
        preparedStatement = connection.prepareStatement(sql); 
        //设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值 
        preparedStatement.setString(1, "王五"); 
        //向数据库发出sql执行查询,查询出结果集 
        resultSet = preparedStatement.executeQuery(); 
        //遍历查询结果集 
        while(resultSet.next()){ 
            System.out.println(resultSet.getString("id")+" "+resultSet.getString("username")); 
        } 
    } catch (Exception e) { 
        e.printStackTrace(); 
    }finally{ 
        //释放资源 
        if(resultSet!=null){ 
            try { 
                resultSet.close(); 
                } catch (SQLException e) { 
                e.printStackTrace(); 
            } 
        } 
        if(preparedStatement!=null){ 
            try { 
                preparedStatement.close(); 
            } catch (SQLException e) { 
                e.printStackTrace(); 
            } 
        } 
        if(connection!=null){ 
            try { 
                connection.close(); 
            } catch (SQLException e) { 
                // TODO Auto-generated catch block 
                e.printStackTrace(); 
            } 
        }
    } 
} 
//上边使用jdbc的原始方法(未经封装)实现了查询数据库表记录的操作。

3.2 Spring的JdbcTemplate

  • Spring中对JDBC的简单封装

3.3 Apache的DBUtils

  • 与Spring的JdbcTemplate类似,也是对Jdbc的简单封装

3.4 注意

  • 以上都不是框架

    • JDBC是规范
    • Spring的JdbcTemplate和Apache的DBUtils都只是工具类

3.5 JDBC问题的分析

  1. 数据库连接创建、释放频繁会造成西戎资源浪费从而影响系统性能,如果使用数据库连接池可解决此问题。
  2. Sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
  3. 使用preparedStatement向占位符传参数存在硬编码,因为sql语句的where条件不一定,有多有少,修改sql还要修改代码,系统不易维护
  4. 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。

四、MyBatis概述

  • MyBatis是一个持久层的框架,是使用java编写的。
  • 它封装了jdbc操作的很多细节,使开发者只需要关注sql语句本身,而无需关注注册驱动,创建连接等繁杂过程。
  • 它使用了ORM思想实现了结果集的封装。

    • ORM:Object Relational Mapping 对象关系映射

      • 将数据库的表及字段名和实体类及属性对应起来。

    | user(表) | User(实体类) |
    | :--------: | :------------: |
    | id | userId |
    | user_name | userName |

    • 最好将实体类中的属性和数据库的字段名保持一致

    | user(表) | User(实体类) |
    | :--------: | :------------: |
    | id | id |
    | user_name | user_name |

五、MyBatis入门(基于xml配置文件)

5.1 环境搭建

  • 前提

5.1.1 创建Maven工程并导入依赖

  • pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.ruki</groupId>
        <artifactId>day01_eesy_01mybatis</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <packaging>jar</packaging>
    
        <dependencies>
            <!-- mybatis依赖 -->
            <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.4.5</version>
            </dependency>
            <!-- mysql依赖 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.6</version>
            </dependency>
            <!-- 日志依赖 -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.12</version>
            </dependency>
            <!-- 单元测试依赖 -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
        </dependencies>
    
    </project>

5.1.2 创建实体类和dao接口

  • 准备数据库表

  • 创建实体类,User

    package com.ruki.domain;
    
    import java.io.Serializable;
    import java.util.Date;
    
    public class User implements Serializable {
        private Integer id;
        private String username;
        private Date birthday;
        private String sex;
        private String address;
    
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", username='" + username + '\'' +
                    ", birthday=" + birthday +
                    ", sex='" + sex + '\'' +
                    ", address='" + address + '\'' +
                    '}';
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public Date getBirthday() {
            return birthday;
        }
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    }
    
  • 创建dao,IUserDao

    package com.ruki.dao;
    
    import com.ruki.domain.User;
    
    import java.util.List;
    
    /**
     * 用户的持久层接口
     */
    public interface IUserDao {
        /**
         * 查询所有的操作
         * @return list
         */
        List<User> findAll();
    }
    

5.1.3 创建映射配置文件(IUserDao.xml)

  • 要求:

    1. 创建位置:必须和持久层接口在相同的包中
    2. 名称:必选以持久层接口名称命名文件名,扩展名为.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- dao的全限定类名-->
 <mapper namespace="com.ruki.dao.IUserDao">
    <!-- 配置查询所有
        id: 方法的名称
        resultType:必须说清楚返回的类型是什么,不然查出来不知道以什么类型返回
    -->
    <select id="findAll" resultType="com.ruki.domain.User">
        select * from user
    </select>
</mapper>
  • mapper

    • namespace:限定标签中的内容去哪里找。

      • <font color="red">全限定类名</font>:如标签体中的findAll()方法去com.ruki.dao包下的IUserDao中找
  • select

    • id:方法名
    • resultType:返回结果的类型。

      • <font color="red">全限定类名</font>:规定以具体包下某个类的类型返回。
    • 标签体:sql语句

5.1.4 创建MyBatis主配置文件(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">

<!-- mybatis的主配置文件 -->
<configuration>
    <!-- 配置环境 -->
    <environments default="mysql">
        <!-- 配置mysql的环境 -->
        <environment id="mysql">
            <!-- 配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!-- 配置连接数据库的4个基本信息-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis01"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 指定映射配置文件,映射配置文件指的是每个dao独立的配置文件-->
    <mappers>
        <mapper resource="com/ruki/dao/IUserDao.xml" />
    </mappers>
</configuration>
  • configuration
  • environments

    • default:mysql
  • environment

    • id:mysql
  • transactionManager:事务管理对象

    • type:JDBC
  • dataSource

    • type:POOLED
  • property:数据库连接的4个基本信息

    • name

      • driver
      • url
      • username
      • password
    • value
  • mappers
  • mapper

    • resource:告知mybatis映射配置文件的位置

5.2 环境搭建的注意事项

  1. 创建IUserDao.xmlIUserDao.java,名称是为了和之前的保持一致。

    1. 在MyBatis中,它把持久成的操作接口名称和映射文件也叫做Mapper
    2. IUserDaoIUserMapper是一样的
  2. 在idea中创建目录的时候,和创建包是不一样的

    1. 包在创建时:com.ruki.dao是三级结构
    2. 目录在创建时:com.ruki.dao是一级目录
  3. MyBatis的映射配置文件位置必须和dao接口的包结构相同
  4. 映射配置文件的mapper标签和namespace属性的取值必须是dao接口的全限定类名
  5. 映射配置文件的操作配置(select),id属性的取值必须是dao接口的方法名
  • 遵从了第3、4、5点后,在之后的开发中就无需再写dao的实现类(xxDaoImpl)

六、测试步骤

  1. 读取配置文件
  2. 创建SqlSessionFactory工厂
  3. 创建SqlSession
  4. 创建Dao接口的代理对象

    1. 创建代理对象
    2. 在代理对象中调用selectList
  5. 执行Dao中的方法
  6. 释放资源

package com.ruki.test;

import com.ruki.dao.IUserDao;
import com.ruki.domain.User;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MyBatisTest {
    public static void main(String[] args) throws IOException {
        //1. 读取配置文件
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2. 创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sessionFactory = builder.build(in);
        //3. 使用工厂生产一个SqlSession对象
        SqlSession session = sessionFactory.openSession();
        //4. 使用SqlSession创建Dao接口的代理对象
        IUserDao userDao = session.getMapper(IUserDao.class);
        //5. 使用代理对象执行方法
        List<User> users = userDao.findAll();
        for(User user : users){
            System.out.println(user);
        }
        //6. 释放资源
        session.close();
        in.close();
    }
}
  • 注意事项:

    • 不要忘记在映射配置中告知mybatis要封装到哪个实体类中
    • 配置的方式:指定实体类的全限定类名

七、MyBatis入门(基于注解)

  • IUserDao.xml删除,在dao接口的方法上使用@Select注解,并且指定sql语句

    • @Select("select * from user")
    package com.ruki.dao;
    
    import com.ruki.domain.User;
    import org.apache.ibatis.annotations.Select;
    
    import java.util.List;
    
    /**
     * 用户的持久层接口
     */
    public interface IUserDao {
        /**
         * 查询所有的操作
         * @return list
         */
        @Select("select * from user")
        List<User> findAll();
    }
  • SqlMapConfig.xml中的mapper配置时,使用<font color="red">class</font>属性指定dao接口的全限定类名,而不是之前的resource

        <mappers>
            <!--<mapper resource="com/ruki/dao/IUserDao.xml" />-->
            <mapper class="com.ruki.dao.IUserDao" />
        </mappers>
Last modification:September 14th, 2019 at 10:30 am