Mybatis小demo总结

 

 

最近复习一下Mybatis框架,简单的记录一下。

Mybatis框架:JDBC的增强

三层架构:界面层(和用户打交道,接收用户请求参数,显示处理结果):controller包(servlet)

                  业务逻辑层(接收界面传送的数据,计算逻辑,调用数据库,获取数据):service包

                    持久层(访问数据库,执行对数据增删改查):dao包

三层的交互:

用户使用界面层(springMVC)-->业务逻辑层(service类、spring)--->持久层(Mybatis)--->数据库

动手实现一个小demo:

实现步骤:

1.新建user表

2加入maven的mybatis坐标

3.创建实体类User,

4.创建持久层dao接口,定义操作数据库的方法,userDao

5.创建配置文件(sql映射文件),在接口所在的目录中,文件名称和接口保持一致,userDao.xml

6.创建主配置文件,mybatis-config.xml

     提供了数据库连接信息和sql映射文件的位置信息

7.创建使用mybatis的类,通过mybatis访问数据库

首先创建一个项目:

配置好maven,注意添加一下archetypeCatalog=internal,否则可能会报错,出现没有src目录的情况;

首先目录结构是这样的,

1.加入依赖:

 

<dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.4</version>
    </dependency>

加入mysql驱动:

<dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.20</version>
    </dependency>

2.数据库中新建表user,

3.创建实体类User,

package com.example.entity;

import java.text.SimpleDateFormat;
import java.util.Date;

public class User {
    private Integer id;
    private String user_name;
    private String psd;
    private String name;
    private Integer sex;
    private Integer age;
    private Date birthday;
    private String created;
    private  String updated;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUser_name() {
        return user_name;
    }

    public void setUser_name(String user_name) {
        this.user_name = user_name;
    }

    public String getPsd() {
        return psd;
    }

    public void setPsd(String psd) {
        this.psd = psd;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getSex() {
        return sex;
    }

    public void setSex(Integer sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

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

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getCreated() {
        return created;
    }

    public void setCreated(String created) {
        this.created = created;
    }

    public String getUpdated() {
        return updated;
    }

    public void setUpdated(String updated) {
        this.updated = updated;
    }

   

    @Override
    public String toString() {
        return "User{" +
                "id='" + id + '\'' +
                ", user_name='" + user_name + '\'' +
                ", psd='" + psd + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                ", birthday='" + new SimpleDateFormat("yyyy-MM-dd").format(birthday) + '\'' +
                ", created='" + created + '\'' +
                ", updated='" + updated + '\'' +
                '}';
    }


}

4.创建接口UserDao,

package com.example.dao;

import com.example.entity.User;

import java.util.List;
//操作接口
public interface UserDao {
    //int表示执行后,影响数据库的行数
    public void addUser(User user);

    public void deleteUser(User user);

    public void updateUser(User user);

    public User queryUserById(Integer id);
//查询表中所有数据,返回一个集合,保存User对象
    public List<User> queryUserAll();
}

5.创建配置文件(sql映射文件),在接口所在的目录中(或者放在resources目录下mapper目录中),文件名称和接口保持一致,userDao.xml

<?xml version='1.0' encoding='UTF-8'?>
<!--约束文件,限制、检查在当前文件中出现的标签,属性必须符合mybatis要求 -->
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--当前文件根标签,必须的
   namespace:命名空间,唯一值,可以是自定义的字符串,要求使用dao接口的全限定名称
 -->
<mapper namespace="com.example.dao.UserDao">
<!--在当前文件中,可以使用特定的标签,表示数据库的特定操作 -->


    <!--查询-->
    <!-- id要求使用接口中的方法名
        resultType表示sql执行后得到的ResultSet,遍历这个结果集得到Java对象的类型,要求是类型的全限定名称 -->


<select id="queryUserAll"  resultType="com.example.entity.User">
    select * from user ;
</select>
    <insert id="addUser" parameterType="com.example.entity.User">
         INSERT INTO user (
        user_name,
        psd,
        name ,
        age,
        sex,
        birthday,
        created,
        updated
        )
        VALUES
        (
        #{user_name},
        #{psd},
        #{name},
        #{age},
        #{sex},
        #{birthday},
        now(),
        now()
        );
    </insert>
    <delete id="deleteUser">
        delete from user where id=#{id};
    </delete>

    <update id="updateUser" parameterType="com.example.entity.User">
        update user
       <trim prefix="set" suffixOverrides=",">
            <if test="user_name!=null">user_name = #{user_name},</if>
            <if test="psd!=null">psd = #{psd},</if>
            <if test="name!=null">name = #{name},</if>
            <if test="age!=null">age = #{age},</if>
            <if test="sex!=null">sex = #{sex},</if>
            <if test="birthday!=null">birthday = #{birthday},</if>
            updated = now(),
        </trim>
       where id = #{id};
    </update>

</mapper>

6,全局配置文件mybatis-config.xml,放在resources下,

<?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="development">
    <environment id="development">
        <!--mybatis事务类型,type表示使用jdbc中的Connection对象的commit、rollback做事务处理
        -->
        <transactionManager type="JDBC"></transactionManager>

        <!-- 数据库连接池 -->
        <dataSource type="POOLED">
            <property name="driver" value="com.mysql.cj.jdbc.Driver" />
            <property name="url" value="jdbc:mysql://localhost:3306/testdemo" />
            <property name="username" value="root" />
            <property name="password" value="root" />
        </dataSource>
    </environment>
</environments>
    <!--sql映射文件的位置 -->
<mappers>
    <mapper resource="mapper/UserDao.xml"></mapper>
</mappers>

</configuration>

7.编写测试类进行单元测试,其中,mybatis默认不提交事务,需要在insert,update,delete后手动提交事务,否则在数据库中查询不到数据更新,

package com.example.test;

import com.example.entity.User;
import com.example.utils.MybatisUtils;
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.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class Test {

    /**
     * 查询数据
     */
    @org.junit.Test
    public void queryUserAll() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        try {

            //5.【重要】指定要执行的sql语句的标识,sql映射文件中的namespace+"."+标签的id值
            String sqlId="com.example.dao.UserDao"+"."+"queryUserAll";
            //6.执行sql语句
            List<User> userList = sqlSession.selectList(sqlId);

            //7.遍历结果
            for (User user : userList) {
                System.out.println(user);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }

    }

    /**
     * 添加数据
     */
    @org.junit.Test
    public void addUser() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        try {

            //5.【重要】指定要执行的sql语句的标识,sql映射文件中的namespace+"."+标签的id值
            String sqlId = "com.example.dao.UserDao" + "." + "addUser";
            //执行sql语句


            User user = new User();
            //user.setId(3);
            user.setUser_name("ls");
            user.setAge(27);
            user.setName("李四");
            user.setPsd("222222");
            user.setSex(2);
//            String time = "1993-12-13";
//            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//            Date date = null;
//            date = sdf.parse(time);
           user.setBirthday(new Date());
            int flag=sqlSession.insert(sqlId,user);

            //7.输出结果
            System.out.println(user);
//mybatis默认不提交事务,需要在insert,update,delete后手动提交
            sqlSession.commit();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }

    }


    /**
     * 修改数据
     */
@org.junit.Test
    public void updateUser() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        try {

            //5.【重要】指定要执行的sql语句的标识,sql映射文件中的namespace+"."+标签的id值
            String sqlId = "com.example.dao.UserDao" + "." + "updateUser";
            //执行sql语句
            User user = new User();
            user.setName("李");
            user.setUser_name("ls");
            //user.setAge(26);
            user.setSex(2);
            user.setId(12);
            user.setPsd("111111");
           String time = "1993-12-13";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date date = null;
            date = sdf.parse(time);
            user.setBirthday(date);
            int flag=sqlSession.update(sqlId,user);

            //7.输出结果
            System.out.println(user);
//mybatis默认不提交事务,需要在insert,update,delete后手动提交
            sqlSession.commit();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }

    }


    /**
     * 删除数据
     */
    @org.junit.Test
    public void deleteUser() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        try {

            //5.【重要】指定要执行的sql语句的标识,sql映射文件中的namespace+"."+标签的id值
            String sqlId="com.example.dao.UserDao"+"."+"deleteUser";
            //6.执行sql语句
           int num= sqlSession.delete(sqlId,12);

                System.out.println(num);
                sqlSession.commit();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }

    }
}



8.其中用到了一个工具类MybatisUtils,和Hibernate中同样原理,构建单态模式下的SqlSessionFactory。首先声明了一个私有的静态类型的SqlSessionFactory对象,来供类中的其他成员使用,接下来通过静态方法构建SqlSessionFactory实例,最后提供了一个公有的静态方法供外部获取SqlSession对象。通过此工具类,在项目中就可以直接通过MybatisUtils.getSqlSession()的方式获取SqlSession对象:

package com.example.utils;

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;

public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            // 1.指定全局配置文件
            String resource = "mybatis-config.xml";
            // 2.读取配置文件
            InputStream inputStream = Resources.getResourceAsStream(resource);
            // 3.构建sqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //4.构建sqlSession,从sqlSessionFactory获取

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }
}

中间遇到报错,说是空指针异常:

因为定义完全局变量sqlSessionFactory之后,又在static中定义了sqlSessionFactory导致getsession中的sqlsession对象为空。
只需要将static对象中的factory类名去掉就行。

最终目录结构:

关于具体的配置讲解,

1、 mybatis配置 
mybatis-config.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。 
mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在mybatis-config.xml中加载。

2、 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂 
3、 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。 
4、 mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。 
5、 Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。 
6、 Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的Java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。 
7、 Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

输出映射(返回的结果集可以有哪些类型)

1)基本类型

2)pojo类型

3)List类型

核心对象:

1.SqlSessionFactoryBuilder
用过即丢,其生命周期只存在于方法体内
可重用其来创建多个 SqlSessionFactory 实例
负责构建SqlSessionFactory,并提供多个build方法的重载

2.SqlSessionFactory
SqlSessionFactory是每个MyBatis应用的核心
作用:创建SqlSession实例
作用域:Application
生命周期与应用的生命周期相同
单例模式
存在于整个应用运行时,并且同时只存在一个对象实例

3.SqlSession
包含了执行SQL所需的所有方法
对应一次数据库会话,会话结束必须关闭
线程级别,不能共享,在SqlSession里可以执行多次SQL语句,但一旦关闭了SqlSession就需要重新创建

SqlSession的两种使用方式
01.通过SqlSession实例直接运行映射的SQL语句
02.基于Mapper接口方式操作数据

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值