mybatis-9.28

环境:

  • JDK1.8

  • MySQL5.7

  • maven 3.6.1

  • IDEA

回顾:

  • JDBC
  • MySQL
  • Java基础
  • Maven
  • Junit

SSM框架:配置文件的。最好的方式就是看官网文档

1、简介

1.1什么是mybatis

  • Mybatis是一款优秀的持久层框架
  • 它支持定制化SQL,存储过程以及高级映射
  • Mybatis避免了JDBC和手动设置参数以及获取结果集。Mybatis使用简单的XML或者注解来配置和映射原生类型、接口和Java的POJO为数据库中的记录
  • MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code code/2346604),并且改名为MyBatis 。2013年11月迁移到Github

如何获得Mybatis?

  • Maven仓库
  • GitHub
  • 中文文档

1.2持久化

数据持久化

  • 数据持久化就是将持久状态和瞬时状态转化的过程
  • 内存:断电即失
  • 数据库(jdbc),io文件持久化。

为什么需要持久化

  • 有一些对象,不能丢掉
  • 内存太贵了

1.3持久层

Dao层,Service层,Controller层。。。

  • 完成持久化工作的代码块
  • 层是界限十分明显的

1.4为什么需要Mybatis

传统JDBC代码太复杂。简化。框架。自动化

2、第一个Mybatis程序

思路:搭建环境—>导入Mybatis—>编写代码—>测试

2.1搭建环境

搭建数据库

新建项目

思路

  1. 搭建环境 -- 导入mybatis -- 编写代码 -- 进行测试
  1. 新建普通maven项目

  2. 删除src,当做父工程

  3. 导入maven依赖

    1. <!--导入依赖-->
    2. <dependencies>
    3. <dependency>
    4. <groupId>org.mybatis</groupId>
    5. <artifactId>mybatis</artifactId>
    6. <version>3.4.5</version>
    7. </dependency>
    8. <dependency>
    9. <groupId>mysql</groupId>
    10. <artifactId>mysql-connector-java</artifactId>
    11. <version>5.1.47</version>
    12. </dependency>
    13. <dependency>
    14. <groupId>junit</groupId>
    15. <artifactId>junit</artifactId>
    16. <version>4.13</version>
    17. <scope>test</scope>
    18. </dependency>
    19. </dependencies>

2.2创建一个模块

  • 编写Mybatis核心配置文件

    1. <!--mybatis的核心配置文件-->
    2. <configuration>
    3. <!--配置环境-->
    4. <environments default="development">
    5. <!--配置mysql的环境-->
    6. <environment id="development">
    7. <!--配置事务的类型-->
    8. <transactionManager type="JDBC"/>
    9. <!--配置数据源,也叫连接池-->
    10. <dataSource type="POOLED">
    11. <property name="driver" value="com.mysql.jdbc.Driver"/>
    12. <property name="url" value="jdbc:mysql://localhost:3306/mybatisdesign?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
    13. <property name="username" value="root"/>
    14. <property name="password" value="123456"/>
    15. </dataSource>
    16. </environment>
    17. </environments>
    18. <mappers>
    19. <mapper resource="org/mybatis/example/BlogMapper.xml"/>
    20. </mappers>
    21. </configuration>
  • 编写Mybatis的工具类 ```java //SqlSessionFactory —> SqlSession public class MybatisUtils {

    //提升作用域 public static SqlSessionFactory sqlSessionFactory;

    static{

    1. try {
    2. //使用Mybatis第一步:获取SqlSessionFactory
    3. String resource = "org/mybatis/example/mybatis-config.xml";
    4. InputStream inputStream = Resources.getResourceAsStream(resource);
    5. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    6. } catch (IOException e) {
    7. e.printStackTrace();
    8. }

    }

    //既然有了SqlSessionFactory,我们就可以使用SqlSession的实例了 //SqlSession完全包含了面向数据库执行SQL的所有方法

    public static SqlSession getSqlSession(){

    1. return sqlSessionFactory.openSession();

    }

}

  1. <a name="a750c17c"></a>
  2. ## 2.3、编写代码
  3. <a name="5407ca53"></a>
  4. ### 1.实体类
  5. (???lombock是个啥??)
  6. ```java
  7. package com.zmy.pojo;
  8. public class User {
  9. private int id;
  10. private String name;
  11. private String password;
  12. public User() {
  13. }
  14. public User(int id, String name, String password) {
  15. this.id = id;
  16. this.name = name;
  17. this.password = password;
  18. }
  19. public int getId() {
  20. return id;
  21. }
  22. public void setId(int id) {
  23. this.id = id;
  24. }
  25. public String getName() {
  26. return name;
  27. }
  28. public void setName(String name) {
  29. this.name = name;
  30. }
  31. public String getPassword() {
  32. return password;
  33. }
  34. public void setPassword(String password) {
  35. this.password = password;
  36. }
  37. }

2.Dao接口

  1. public interface UserDao {
  2. List<User> getUserList();
  3. }

3.接口实现类

由原来的Implement实现类转为了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. <!--namespace绑定的是对应的Dao/Mapper接口-->
  6. <mapper namespace="com.zmy.dao.UserDao">
  7. <!--select查询语句-->
  8. <select id="getUserList" resultType="com.zmy.pojo.User">
  9. select * from user;
  10. </select>
  11. </mapper>

2.4、测试

  1. Type interface com.zmy.dao.UserMapper is not known to the MapperRegistry

注意一点:maven的资源过滤问题(约定大于配置)

xml配置文件不存在,或者无法导出生效。解决方案:

  1. <build>
  2. <resources>
  3. <resource>
  4. <directory>src/main/resources</directory>
  5. <includes>
  6. <include>**/*.properties</include>
  7. <include>**/*.xml</include>
  8. </includes>
  9. <filtering>true</filtering>
  10. </resource>
  11. <resource>
  12. <directory>src/main/java</directory>
  13. <includes>
  14. <include>**/*.properties</include>
  15. <include>**/*.xml</include>
  16. </includes>
  17. <filtering>true</filtering>
  18. </resource>
  19. </resources>
  20. </build>
  • tips:在resource目录中新建层级目录用\隔开

  • junit测试

    1. public class UserMapperTest {
    2. @Test
    3. public void test(){
    4. //第一步:获得SqlSession对象
    5. SqlSession sqlSession = MybatisUtils.getSqlSession();
    6. //执行SQL 方式一:getMapper
    7. UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    8. List<User> userList = mapper.getUserList();
    9. for (User user : userList) {
    10. System.out.println(user);
    11. }
    12. //关闭SqlSession
    13. sqlSession.close();
    14. }
    15. }

3、问题总结

  1. 配置文件没有注册
  2. 绑定接口错误
  3. 方法名不对
  4. 返回类型不对
  5. 目录建造方式不对\ .
  6. maven导出资源不对

4、CRUD

1、namespace

namespace中的包名要和Dao/Mapper接口的报名一致

2、select

选择,查询语句

  • id 对应namespace中的方法名

  • resultType SQL语句执行的返回值!:对应的实体类pojo的全限定类名

  • parameterType 参数类型

  1. 编写接口
    1. //根据id查询用户
    2. User getUserById(int id);
  1. 编写对应的mapper中的SQL语句
    1. <select id="getUserById" parameterType="int" resultType="com.zmy.pojo.User">
    2. select * from mybatis.user where id = #{id};
    3. </select>
  1. 测试

    1. @Test
    2. public void testGetUserById(){
    3. //第一步:获得SqlSession对象
    4. SqlSession sqlSession = MybatisUtils.getSqlSession();
    5. //执行SQL 方式一:getMapper
    6. UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    7. User user = mapper.getUserById(2);
    8. System.out.println(user);
    9. //关闭SqlSession
    10. sqlSession.close();
    11. }

3、insert(增删改提交事务)

  1. <insert id="addUser" parameterType="com.zmy.pojo.User">
  2. insert into mybatis.user (id,name,password) values (#{id},#{name},#{password});
  3. </insert>

4、update

  1. <update id="updateUser" parameterType="com.zmy.pojo.User">
  2. update mybatis.user set name = #{name}, password = #{password} where id = #{id} ;
  3. </update>

5、delete

  1. <delete id="delUser" parameterType="int">
  2. delete from mybatis.user where id = #{id};
  3. </delete>

6、分析错误

  1. 标签匹配
  2. namespace绑定. resource绑定/
  3. 程序配合文件规范
  4. 空指针异常 没有注册到资源 SqlsessionFactory
  5. maven资源没有导出 build

7、万能map

  1. int addU(Map<String,Object> map);
  1. <insert id="addU" parameterType="map">
  2. insert into mybatis.user (id, name, password) values (#{userId},#{userName},#{userPassword});
  3. </insert>
  1. @Test
  2. public void testAdd2(){
  3. //第一步:获得SqlSession对象
  4. SqlSession sqlSession = MybatisUtils.getSqlSession();
  5. //执行SQL 方式一:getMapper
  6. UserMapper mapper = sqlSession.getMapper(UserMapper.class);
  7. Map<String,Object> map = new HashMap<String, Object>();
  8. map.put("userId",5);
  9. map.put("userName","yyds");
  10. mapper.addU(map);
  11. //提交事务
  12. sqlSession.commit();
  13. //关闭SqlSession
  14. sqlSession.close();
  15. }

8、模糊查询

5、配置解析

1、核心配置文件

  • mybatis-config.xml

  • MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。

    1. configuration(配置)
    2. properties(属性)
    3. settings(设置)
    4. typeAliases(类型别名)
    5. typeHandlers(类型处理器)
    6. objectFactory(对象工厂)
    7. plugins(插件)
    8. environments(环境配置)
    9. environment(环境变量)
    10. transactionManager(事务管理器)
    11. dataSource(数据源)
    12. databaseIdProvider(数据库厂商标识)
    13. mappers(映射器)

2、环境配置(environments)

3、属性(properties)

我们可以通过properties属性来实现引用配置文件

这些属性可以在外部进行配置,并可以进行动态替换,既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。【db.properties】

  1. 编写一个配置文件【db.properties】
    1. driver = com.mysql.jdbc.Driver
    2. url = jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8
    3. username = root
    4. password = 123456
  1. 在核心配置文件中引入
    1. <properties resource="db.properties">
    2. <property name="username" value="root"/>
    3. <property name="password" value="1231156"/>
    4. </properties>
  • 可以直接引入外部文件
  • 可以在其中加入属性配置
  • 同一字段优先使用配置文件的!

4、类型别名(typeAliases)

  • 类型别名可为 Java 类型设置一个缩写名字。
  • 它仅用于 XML 配置,意在降低冗余的全限定类名书写
  1. <typeAliases>
  2. <typeAlias type="com.zmy.pojo.User" alias="user"/>
  3. </typeAliases>

也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean

  1. <typeAliases>
  2. <package name="com.zmy.pojo"/>
  3. </typeAliases>

也可以注解

  1. @Alias("user")
  2. public class User {

5、设置(settings)

官方文档

6、其他配置

  • 类型处理器(typeHandlers)
  • 对象工厂(objectFactory)
  • 插件(plugins)

    • mybatis-generator-core
    • mybatis-plus
    • 通用mapper

7、映射器(mappers)

MapperRegistry:注册绑定我们的Mapper文件
方式一:[推荐使用]

  1. <mappers>
  2. <mapper resource="com/zmy/dao/UserMapper.xml"/>
  3. </mappers>

方式二:使用class文件绑定注册

  1. <mappers>
  2. <mapper class="com.zmy.dao.UserMapper"/>
  3. </mappers>
  • 注意点
  • 接口与Mapper配置文件同名
  • 接口与Mapper配置文件在同一个包下

方式三:使用包扫描

  1. <mappers>
  2. <package name="com.zmy.dao"/>
  3. </mappers>

8、生命周期和作用域

6、结果集映射(ResultMap)

解决字段名和属性名不一致的问题 resultType==ResultMap

  1. <resultMap id="userResultMap" type="User">
  2. <id property="id" column="user_id" />
  3. <result property="username" column="user_name"/>
  4. <result property="password" column="hashed_password"/>
  5. </resultMap>

7、日志工厂

  • [ ] 代替sout和debug

  • STDOUT_LOGGING

  • LOG4J

1、LOG4J

  1. 导入log4j包 (maven依赖)
    1. <dependency>
    2. <groupId>log4j</groupId>
    3. <artifactId>log4j</artifactId>
    4. <version>1.2.17</version>
    5. </dependency
  1. resoure—-log4j.properties

  2. 配置log4j的实现 settings中配置

简单使用

  1. 再要使用Log4J的类中,导入包 import org.aphace。log4j.logger

  2. 日志对象,参数为当前类的class

    1. static Logger logger = Logger.getLogger(UserDaoTest.class);
  1. 日志级别

8、分页

  • 减少数据的处理量

8.1、使用Limit分页

  1. select * from user limit 0,4;

使用mybatis实现分页,核心SQL

  1. 接口Dao
    1. //分页
    2. List<User> getUserByLimit(Map<String, Integer> map);
  1. mapper.xml
    1. <select id="getUserByLimit" parameterType="map" resultType="user">
    2. select * from mybatis.user limit #{startIndex},#{pageSize};
    3. </select>
  1. 测试

    1. @Test
    2. public void limit(){
    3. //第一步:获得SqlSession对象
    4. SqlSession sqlSession = MybatisUtils.getSqlSession();
    5. //执行SQL 方式一:getMapper
    6. UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    7. Map<String,Integer> map = new HashMap();
    8. map.put("startIndex",0);
    9. map.put("pageSize",2);
    10. List<User> userList = mapper.getUserByLimit(map);
    11. for (User user : userList) {
    12. System.out.println(user);
    13. }
    14. //关闭SqlSession
    15. sqlSession.close();
    16. }

9、注解开发

9.1、面向接口编程

解耦

  1. 在一个[面向对象](https://baike.baidu.com/item/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1)的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部是如何实现自己的,对[系统设计](https://baike.baidu.com/item/%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1)人员来讲就不那么重要了;而各个对象之间的协作关系则成为系统设计的关键。小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主要工作内容。面向接口编程就是指按照这种思想来编程。

关于接口的理解。

  1. 接口从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离。

接口的本身反映了系统设计人员对系统的抽象理解。

  • 接口应有两类:

    • 第一类是对一个个体的抽象,它可对应为一个抽象体(abstract class);
    • 第二类是对一个个体某一方面的抽象,即形成一个抽象面(interface);

一个体有可能有多个抽象面。抽象体与抽象面是有区别的。

三个面向区别

  • 面向对象是指,我们考虑问题时,以对象为单位,考虑它的属性及方法
  • 面向过程是指,我们考虑问题时,以一个具体的流程(事务过程)为单位,考虑它的实现
  • 接口设计与非接口设计是针对复用技术而言的,与面向对象(过程)不是一个问题。更多的体现就是对系统整体的架构

9.2、使用注解开发

  • ### mybatis执行流程

10、Lombock

使用步骤:

  1. idea安装插件 lombock
  2. 在项目中导入lombock的jar包

11、多对一

  • 按照查询嵌套处理
  • 按照结果嵌套处理
  1. <select id="getStudent" resultMap="StudentTeacher">
  2. select s.id sid,s.name sname,t.name tname
  3. from student s , teacher t
  4. where s.tid = t.id;
  5. </select>
  6. <resultMap id="StudentTeacher" type="Student">
  7. <result property="id" column="sid"/>
  8. <result property="name" column="sname"/>
  9. <association property="teacher" javaType="Teacher">
  10. <result property="name" column="tname"/>
  11. </association>
  12. </resultMap>

12、一对多

  • 按照查询嵌套处理
  • 按照结果嵌套处理
  1. <select id="getTeacher" resultMap="TeacherStudent">
  2. select s.id sid,s.name sname,t.name tname,t.id tid
  3. from student s , teacher t
  4. where s.tid = t.id and t.id = #{tid};
  5. </select>
  6. <resultMap id="TeacherStudent" type="Teacher">
  7. <result property="id" column="tid"/>
  8. <result property="name" column="tname"/>
  9. <colletion property="student" ofType="Student">
  10. <result property="name" column="sname"/>
  11. <result property="id" column="sid"/>
  12. </colletion>
  13. </resultMap>

小结

  • associaation 【多对一】
  • collection 【一对多】
  • JavaType & ofType

    1. JavaType 用来指定实体类中的类型
    2. ofType 用来指定映射到List或者集合中的pojo类型,泛型中的约束类型

注意点:

  • 保证 sql 的可读性
  • 注意多对多的,属性和字段名匹配问题
  • 标签

慢SQL

面试高频

  • MySQL引擎
  • InnoDB底层原理
  • 索引
  • 索引优化

13、动态SQL

什么是动态SQL:根据不同的条件生成不同的SQL语句

  1. 动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
  2. 使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。
  3. 如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
  4. if
  5. choose (when, otherwise)
  6. trim (where, set)
  7. foreach

搭建环境

if

  1. <select id="findActiveBlogWithTitleLike" resultType="Blog">
  2. SELECT * FROM BLOG
  3. WHERE state = ‘ACTIVE’
  4. <if test="title != null">
  5. AND title like #{title}
  6. </if>
  7. </select>