MyBasic - 图1MyBatis.xmind

一、框架概述

1、软件开发常用的结构

1、三层框架

包括:界面层User Interface layer ,业务逻辑层(Business Logic Layer),数据访问层(Data access layer)

2、三层界面的职责

  1. 界面层(表示层、视图层)主要功能是接受用户数据,显示请求的处理结果。使用web页面和用户交互,手机app也是表示层,用户在app层操作,业务逻辑在服务器中处理(controller包,servlet、jsp)
  2. 业务逻辑层,接受表示传递过来的数据,检查数据,计算业务逻辑,调用数据访问层获取数据(Service类)
  3. 数据访问层,与数据库打交道,主要负责对数据库的增删改查,将存储在数据库的数据提交给业务层,同时将业务层的数据保存在数据库

三层的处理请求的交互

用户——界面层——业务逻辑层——数据访问层——DB数据库

三层框架对应的处理框架

界面层——servlet——springmvc

业务逻辑层——service类——spring框架

数据访问层——dao类——mybatis框架

Mybatis

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

实现步骤:

  1. 新建student表
  2. 加入maven的mybatis坐标、mysql坐标
  3. 创建实体类,Student,属性要与Student数据库表的属性一致
  4. 创建持久层的dao接口,定义操作数据库的方法
  5. 创建一个mybatis使用的配置文件
    • 这个文件称为sql映射文件,用于书写sql语句,一般一个表一个sql映射文件,此文件为xml文件
  6. 创建mybatis的主配置文件
    1. 一个项目就一个主配置文件
    2. 主配置文件提供了数据库的连接信息,和sql映射文件的位置信息
  7. 创建使用mybatis类
    1. 通过Mybatis访问数据库

基本实现代码

maven配置

  1. <dependency>
  2. <groupId>org.mybatis</groupId>
  3. <artifactId>mybatis</artifactId>
  4. <version>3.5.1</version>
  5. <dependency>
  6. <groupId>mysql</groupId>
  7. <artifactId>mysql-connector-java</artifactId>
  8. <version>8.0.20</version>
  9. </dependency>
  10. </dependency>

student类

  1. package com.mayfly.domain;
  2. import java.util.Date;
  3. public class Student {
  4. //注意属性名需要和表的字段名一致,否则将无法产生映射关系
  5. //解决方法,使用别名访问数据库,需要在对应的mybatis配置文件中设置
  6. private int id = 0;
  7. private String name = null;
  8. private String sex = null;
  9. private String birth = null;
  10. private String department = null;
  11. private String address = null;
  12. public Student() { super.() }
  13. @Override
  14. public String toString() {
  15. return "student{" +
  16. "id=" + id +
  17. ", name='" + name + '\'' +
  18. ", sex='" + sex + '\'' +
  19. ", birth=" + birth +
  20. ", department='" + department + '\'' +
  21. ", address='" + address + '\'' +
  22. '}';}
  23. public int getId() { return id; }
  24. public void setId(int id) { this.id = id; }
  25. public String getName() { return name; }
  26. public void setName(String name) { this.name = name; }
  27. public String getSex() { return sex; }
  28. public void setSex(String sex) { this.sex = sex; }
  29. public String getBirth() { return birth; }
  30. public void setBirth(String birth) { this.birth = birth; }
  31. public String getDepartment() { return department; }
  32. public void setDepartment(String department) { this.department = department; }
  33. public String getAddress() { return address; }
  34. public void setAddress(String address) { this.address = address; }
  35. }

StudentDao接口

  1. //接口操作Student表
  2. public interface StudentDao {
  3. //查询student表的所有的数据
  4. public List<Student> selectStudents();
  5. }

StudentDao对应的Mybatis配置文件Mapper

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <!--sql映射文件
  6. 1,约束文件:mybatis-3-mapper.dtd"
  7. 2,约束当前文件中出现的标签,属性必须符合mybatis规范
  8. 3,mapper是当前文件的根标签,
  9. 4,namespace命名空间,必须是唯一的值,可以自定义,但是一般最好是dao接口的全限定名称
  10. -->
  11. <!--操作数据库的标签:
  12. <select>,表示执行查询,
  13. <update>更新
  14. <insert>插入
  15. <delect>删除
  16. -->
  17. <mapper namespace="com.mayfly.dao.StudentDao">
  18. <!--id可以自定义,但是一般要求要与dao的方法名一致,如果使用动态代理,则id名必须和接口的方法名一致0-->
  19. <!--查询返回,使用一个类保存数据-->
  20. <select id="selectStudents" resultType="com.mayfly.domain.Student">
  21. select * from student order by id
  22. </select>
  23. </mapper>

Mybatis主配置文件

<?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-3-config.dtd是Mybatis的约束文件,做约束认证-->
<configuration>
    <settings>
        <!--设置mybatis日志-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <!--定义别名,解决类属性和表格字段名不一致的方法-->
    <typeAliases>
        <!--可以指定一个类型的自定义别名
            type:自定义类型的全限定名称
            aliaes:别名
         -->
        <typeAlias type="com.mayfly.domain.Student" alias="stu"/>
        <typeAlias type="com.mayfly.vo.ViewStudent" alias="vstu"/>
    </typeAliases>
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"/>
    </plugins>
    <environments default="mydev">
        <environment id="mydev">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3308/book?serverTimezone=GMT"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--指定sql mapper(SQL)映射文件的路径-->
    <mappers>
        <!--一个mapper标签表示一个mapper配置文件的位置,默认是从编译后的classes往下-->
        <mapper resource="com/mayfly/dao/StudentDao.xml"/>
    </mappers>
</configuration>

测试类

@Test
public void testFindAll() throws IOException {
    //访问Mybatis读取student数据库
    //1,定义mybatis主要配置文件的名称,类的根路径开始(target/classes)
    String config = "mybatis.xml";
    //2,读取这个config表示的文件
    InputStream in = Resources.getResourceAsStream(config);
    //3,创建SqlSessionhFactoryBuiler对象
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    //4,创建SqlSessionFactory对象
    SqlSessionFactory factory = builder.build(in);
    //5,获取SqlSeeion对象,从SqlSession中获取SqlSession
    SqlSession sqlSession = factory.openSession();
    //6,指定要执行的sql语句标识,  sql映射文件namesapce+“.”+标签的id值
    String sqlId = "com.mayfly.dao.StudentDao" + "." + "selectStudents";
    //7,遍历出查询结果
    List<Student> studentList = sqlSession.selectList(sqlId);
    //studentList.forEach(stu -> System.out.println(stu));
    for (Student stu : studentList) {
        System.out.println("查询的学生=" + stu);
    }
    //关闭sqlSession的session连接
    sqlSession.close();
}

查询方法

插入方法

insert、update、delete默认不是自动提交事务,需要手动设置

代码

//接口操作Student表
public interface StudentDao {
    //通过数据(通过类对象)
    //参数:students,表示需要插入到数据库的数据
    //返回值:int,表示执行insert操作后的返回值,表示插入的行数,插入一行就返回1
    public int insertStudent(Student student);}
<!--mapper    -->
<insert id="insertStudent">
    <!--#{...}内对应的student的属性名,注意不要写错-->
    insert into student values(#{id},#{name},#{sex},#{birth},#{department},#{address});
</insert>

测试方法

@Test
public void testInsert() throws IOException {
    String config = "mybatis.xml";
    InputStream in = Resources.getResourceAsStream(config);
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = builder.build(in);
    SqlSession sqlSession = factory.openSession(true);


    String sqlId = "com.mayfly.dao.StudentDao" + "." + "insertStudent";
    Student student = new Student();
    Calendar calendar = Calendar.getInstance();
    calendar.set(1996, 0, 0);
    Date date = calendar.getTime();
    SimpleDateFormat SimpleDateFormat = new SimpleDateFormat("YYYY");
    String birth = SimpleDateFormat.format(date.getTime());

    student.setId(7);
    student.setName("关羽");
    student.setSex("男");
    student.setBirth(birth);
    student.setDepartment("计算机");
    student.setAddress("河南");
    int studentList = sqlSession.insert(sqlId, student);
    //studentList.forEach(stu -> System.out.println(stu));

    //MyBatis默认不会自动提交事务,需要手动设置
    sqlSession.commit();
    System.out.println(studentList);
    sqlSession.close();
}

设置mybatis的输出日志

<!--在mybatis的主配置文件中设置-->
<settings>
    <!--设置mybatis日志-->
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

主要类的介绍

Resources

Mybatis中的一个类,主要用来读取配置文件

//2,读取这个config表示的文件
InputStream in = Resources.getResourceAsStream(config);

SqlSessionFactory

重量级对象,程序创建一个对象耗时比较长,使用资源比较多,在整个项目中,有一个就已经足够。一般设置为静态对象

SqlSeesionFactory接口

接口实现类:DefaultSqlSessionFactory

SqlSessionFactory作用,获取SqlSession对象。

SqlSession sqlSession =factory.openSession();

openSession()方法使用说明

  1. openSession() :无参数的, 获取是非自动提交事务的SqlSession对象
    2. openSession(boolean): openSession(true) 获取自动提交事务的SqlSession.
    openSession(false) 非自动提交事务的SqlSession对象

SqlSession接口

定义了操作数据的方法,例如 selectOne() ,selectList() ,insert(),update(), delete(), commit(), rollback()。

SqlSession接口的实现类:DefaultSqlSession。

使用要求:

SqlSession对象不是线程安全的,需要在方法内部使用, 在执行sql语句之前,使用openSession()获取SqlSession对象。<br />    在执行完sql语句后,需要关闭它,执行**SqlSession.close().** 这样能保证他的使用是线程安全的。

动态代理

动态代理:使用SqlSession.getMapper(dao接口.class)获取dao这个接口的对象

Mybatis的动态代理:mybatis根据dao方法的调用,执行sql语句的信息,自动根据dao接口,创建出一个dao接口的实现类,并创建这个实现类的对象,

/*
 * 实际开发中使用的模式:
 * 使用myBatis的动态代理机制,使用sqlSession.getMapper(dao接口)
 * getMapper可以获取dao接口对应的实现类对象
 * 前提:mapper.xml配置文件的namepace要对应的dao类的全限定名称,id需要对应具体方法名、
 * 相当于我们写了StudentDao的实现类。StudentDaoImp
 * */
//查询
@Test
public void testFindAll4() {
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    StudentDao dao = sqlSession.getMapper(StudentDao.class);
    List<Student> studentList = dao.selectStudents();
    for (Student stu : studentList) {
        System.out.println("学生信息:" + stu);
    }
    //查看dao对象类型,结果显示属于jdk的动态代理
    //System.out.println("dao="+dao.getClass().getName());
}

传入参数

从java代码中把数据传入mapper文件的sql语句中

  1. parameterType:写在mapper 文件中的一个属性,表示dao接口中方法的参数的数据类型
    例如:StudentDao接口
    public Student  selectStudentById(Integer id)
    
    <!--parameterType设置参数数类型。通过文档查询别名-->
    <select id="selectStudentsId"
         parameterType="java.lang.Integer"
         resultType="com.mayfly.domain.Student">
         select * from student where id=#{id};
    </select>
    
    @Test
    public void testSelectStudenId(){
     SqlSession sqlSession = MyBatisUtils.getSqlSession();
     StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
     Student student = studentDao.selectStudentsId(1);
     System.out.println("数据:" + student);
    }