黑马程序员技术交流社区

标题: Mybatis入门案例(一)之传统DAO开发模式 [打印本页]

作者: z_sir    时间: 2018-11-1 19:30
标题: Mybatis入门案例(一)之传统DAO开发模式
本帖最后由 z_sir 于 2018-11-1 19:48 编辑

Mybatis入门案例之传统DAO开发模式一、前言
    MyBatis的前身叫iBatis,本是apache的一个开源项目, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis。
        MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。
        MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。
        MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plan Old Java Objects,普通的Java对象)映射成数据库中的记录。
二、MyBatis的执行流程
        1>mybatis配置文件,包括Mybatis全局配置文件和Mybatis映射文件,其中全局配置文件配置了数据源、事务等信息;映射文件配置了SQL执行相关的
        信息。
        2>mybatis通过读取配置文件信息(全局配置文件和映射文件),构造出SqlSessionFactory,即会话工厂。
        3>通过SqlSessionFactory,可以创建SqlSession即会话。Mybatis是通过SqlSession来操作数据库的。
        4>SqlSession本身不能直接操作数据库,它是通过底层的Executor执行器接口来操作数据库的。Executor接口有两个实现类,一个是普通执行器,一个是缓存执行器(默认)。
        5>Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中。该对象包括:SQL语句、输入参数映射信息、输出结果集映射信息。其中输入参数和输出结果的映射类型包括java的简单类型、HashMap集合对象、POJO对象类型。
三、Mybatis经典入门案例之传统DAO开发模式
1、环境准备
                JDK环境:jdk1.8
                开发工具:IntelliJ IDEA
                数据库环境:mysql5.1
                Mybatis:3.4.5
         1.1 mysql建表:
[SQL] 纯文本查看 复制代码
CREATE TABLE `user` (

     `id` int(11) NOT NULL AUTO_INCREMENT,

     `username` varchar(20) ,

     `password` varchar(20) ,

    `age` int(11) ,

     PRIMARY KEY (`id`)

)

        1.2 Maven坐标
[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.itcast</groupId>
    <artifactId>Itcast_Mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--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.17</version>
        </dependency>
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
        
    1.3 目录结构
            
2.核心配置文件sqlConfig.xml
        核心配置文件名称没特殊要求,在resources下创建一个XML文档,具体配置如下:
   
[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>
    <!--配置环境-->
    <environments default="mysql">
        <environment id="mysql">
            <!--配置事务-->
            <transactionManager type="JDBC"/>
            <!--配置数据库连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="org.gjt.mm.mysql.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis08"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--指定映射文件的位置-->
    <mappers>
        <mapper resource="com/itheima/dao/UserDao.xml"></mapper>
    </mappers>
</configuration>
3.创建实体类:User.java
[Java] 纯文本查看 复制代码
package com.itheima.enity;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable{
    private Integer id;
    private String username;
    private String password;
    private Integer age;

    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 String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

4.创建映射配置文件:UserDao.xml
  
[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">
<!--
    namespace:命名空间,SQL区域块
        如果使用传统DAO开发模式的话,则没有特殊要求(只要保证唯一即可)
        如果是Mapper代理模式的话,则必须是接口的全限定名
-->
<mapper namespace="one">
    <!--查询全部用户-->
    <!--
        id:唯一的标识
        resultType:结果类型(输出类型)
        parameterType:输入类型
        #{}占位符
    -->
    <select id="findAllUsers" resultType="com.itheima.enity.User">
        SELECT * FROM user
    </select>
    <!--根据ID查询-->
    <select id="findUserById" parameterType="int" resultType="com.itheima.enity.User">
        SELECT * FROM user WHERE id=#{uid}
    </select>
    <!--根据ID删除信息-->
    <delete id="deleteUserById" parameterType="java.lang.Integer">
        DELETE FROM user where id=#{uid}
    </delete>
    <!--根据ID修改User-->
    <update id="updateUserById" parameterType="com.itheima.enity.User">
        UPDATE user SET username=#{username},password=#{password},age=#{age} WHERE id=#{id}
    </update>
    <!--保存User-->
    <insert id="saveUser" parameterType="com.itheima.enity.User">
        INSERT INTO user VALUES (id,#{username},#{paasword},#{age});
    </insert>
</mapper>
5.创建DAO接口:UserDao.java
[Java] 纯文本查看 复制代码
package com.itheima.dao;

import com.itheima.enity.User;
import java.util.List;

public interface UserDao {
    //查询全部用户
    public List<User> findAllUsers();
    //根据ID查询
    public User findUserById(Integer id);
    //根据ID删除信息
    public void deleteUserById(Integer id);
    //根据ID修改User
    public void updateUserById(User user);
    //保存User
    public void saveUser(User user);
   
}

6.创建DAO实现类:UserDaoImpl.java
[Java] 纯文本查看 复制代码
package com.itheima.dao.impl;

import com.itheima.dao.UserDao;
import com.itheima.enity.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 UserDaoImpl implements UserDao{

    public List<User> findAllUsers() throws IOException {
        //1.核心配置文件
        String resource="sqlConfig.xml";
        //2.读取核心配置文件
        InputStream is= Resources.getResourceAsStream(resource);
        /*3.创建SqlSessionFactory对象:SqlSessionFactory是接口,
         *  所以使用SqlSessionFactoryBuilder对象build()构建SqlSessionFactory对象
         */
        SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
        SqlSessionFactory factory=builder.build(is);
        //4.通过SqlSessionFactory对象获取SqlSession对象
        SqlSession session=factory.openSession();
        //5.使用SqlSession提供的SelectList()执行遍历查询,其中的参数:namespace+'.'+statement对象ID
        List<User> list=session.selectList("one.findAllUsers");

        //6.释放资源
        session.close();
        is.close();
        return list;
    }

    public User findUserById(Integer id) throws IOException {
        //1.核心配置文件
        String resource="sqlConfig.xml";
        //2.读取核心配置文件
        InputStream is= Resources.getResourceAsStream(resource);
        /*3.创建SqlSessionFactory对象:SqlSessionFactory是接口,
         *  所以使用SqlSessionFactoryBuilder对象build()构建SqlSessionFactory对象
         */
        SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
        SqlSessionFactory factory=builder.build(is);
        //4.通过SqlSessionFactory对象获取SqlSession对象
        SqlSession session=factory.openSession();
        //5.使用SqlSession提供的SelectList()执行遍历查询,其中的参数:namespace+'.'+statement对象ID
        User user=session.selectOne("one.findUserById",id);
        //6.释放资源
        session.close();
        is.close();
        return user;
    }

    public void deleteUserById(Integer id) throws IOException {
        //1.核心配置文件
        String resource="sqlConfig.xml";
        //2.读取核心配置文件
        InputStream is= Resources.getResourceAsStream(resource);
        /*3.创建SqlSessionFactory对象:SqlSessionFactory是接口,
         *  所以使用SqlSessionFactoryBuilder对象build()构建SqlSessionFactory对象
         */
        SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
        SqlSessionFactory factory=builder.build(is);
        //4.通过SqlSessionFactory对象获取SqlSession对象
        SqlSession session=factory.openSession();
        //5.使用SqlSession提供的SelectList()执行遍历查询,其中的参数:namespace+'.'+statement对象ID
        session.delete("one.deleteUserById",id);
        //6.事务提交
        session.commit();
        //7.释放资源
        session.close();
        is.close();


    }

    public void updateUserById(User user) throws IOException {
        //1.核心配置文件
        String resource="sqlConfig.xml";
        //2.读取核心配置文件
        InputStream is= Resources.getResourceAsStream(resource);
        /*3.创建SqlSessionFactory对象:SqlSessionFactory是接口,
         *  所以使用SqlSessionFactoryBuilder对象build()构建SqlSessionFactory对象
         */
        SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
        SqlSessionFactory factory=builder.build(is);
        //4.通过SqlSessionFactory对象获取SqlSession对象
        SqlSession session=factory.openSession();
        //5.使用SqlSession提供的SelectList()执行遍历查询,其中的参数:namespace+'.'+statement对象ID
        session.update("one.updateUserById",user);
        //6.事务提交
        session.commit();
        //7.释放资源
        session.close();
        is.close();

    }

    public void saveUser(User user) throws IOException {

        //1.核心配置文件
        String resource="sqlConfig.xml";
        //2.读取核心配置文件
        InputStream is= Resources.getResourceAsStream(resource);
        /*3.创建SqlSessionFactory对象:SqlSessionFactory是接口,
         *  所以使用SqlSessionFactoryBuilder对象build()构建SqlSessionFactory对象
         */
        SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
        SqlSessionFactory factory=builder.build(is);
        //4.通过SqlSessionFactory对象获取SqlSession对象
        SqlSession session=factory.openSession();
        //5.使用SqlSession提供的SelectList()执行遍历查询,其中的参数:namespace+'.'+statement对象ID
        session.insert("one.saveUser",user);
        //6.事务提交
        session.commit();
        //7.释放资源
        session.close();
        is.close();
    }
}
SqlSession提供了对应的增删改查的方法:
selectList()、selectOne()、update()、delete()等等。
注意 :  增删改操作需要事务提交,查询不需要事务管理。
7.编写测试类:Demo01.java
[Java] 纯文本查看 复制代码
package com.demo;
import com.itheima.dao.UserDao;
import com.itheima.dao.impl.UserDaoImpl;
import com.itheima.enity.User;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.List;

public class Demo01 {
    private  UserDao userDao=null;
    @Before
    public void init(){
        userDao=new UserDaoImpl();
    }
    //1.测试遍历用户
    @Test
    public void testFindAll() throws IOException {
        List<User> list=userDao.findAllUsers();
        for (User u:list) {
            System.out.println(u);
        }
    }
    //2.测试根据ID查询
    public void testFindUserById() throws IOException {
        User user=userDao.findUserById(1);
        System.out.println(user);
    }
    //3.测试根据ID删除信息
    public void testDeleteUserById() throws IOException {
        userDao.deleteUserById(2);
    }
    //4.测试根据ID修改User
    public void testUpdateUserById() throws IOException {
        User user=new User();
        user.setId(1);
        user.setUsername("itcast");
        user.setPassword("123456");
        user.setAge(18);
        userDao.updateUserById(user);
    }
    //5.测试保存用户
    public void testSaveUser() throws IOException {
        User user=new User();
        user.setId(3);
        user.setUsername("itcast6");
        user.setPassword("123456");
        user.setAge(18);
        userDao.saveUser(user);
    }
}
到此,一套完整的Mybatis的传统DAO开发入门案例已经初步完成,从此开发模式中我们可以发现一些问题的存在:
1>存在一定量的模板代码。比如:通过SqlSessionFactory创建SqlSession;调用SqlSession的方法操作数据   库;关闭Sqlsession。
2>存在一些硬编码。调用SqlSession的方法操作数据库时,需要指定statement的id,这里存在了硬编码。
那么Mybatis的另外一种开发模式,开发效率比较高,同时在实际开发中一般都会采用,即Mapper代理模式。

作者: wxd    时间: 2019-1-15 21:54
国哥6666666666666666666




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2