Version: Next

Mybatis快速入门

Mybatis-9.28

环境:

  • jdk1.8
  • Mysql5.7
  • maven 3.6.1
  • IDEA

回顾:

  • JDBC
  • Mysql
  • JavaSE&JavaEE
  • Maven
  • Junit

SSM框架:学习配置文件的最好方式,看官方文档

1. 简介

1.1 什么是Mybatis

  • 优秀的持久层框架

  • 支持定制SQL、存储过程以及高级映射

  • 避免几乎所有JDBC代码和手动设置参数和获取结果集

  • 使用XML或注解来配置和映射原生类型、接口和Java的POJO(Plian Old Java Objects,普通老式(java对象)为数据库中的记录

  • apche开源项目Ibatis,迁移到google code, 2013.11迁移到github

如何获得Mybatis:

1.2 持久化

数据持久化

  • 持久化就是将程序的数据在持久状态和瞬时状态转化的过程
  • 内存:断电即失
  • 数据库、IO文件持久化

1.3 持久层

Dao层、Service层、Controller层

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

1.4 为什么需要Mybatis

  • 传统的JDBC过于复杂。简化。框架。
  • 帮助程序员将数据存入到数据库中
  • 不用Mybatis也可以
  • SQL和代码分离
  • 提供映射标签、这支持对象与数据库的orm字段映射
  • 提供对象关系映射标签,支持对象关系组维护
  • 提供xml标签,支持编写动态sql

最重要的一点:用的人多

2. 第一个Mybatis程序

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

2.1 搭建环境

搭建数据库

CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(30) DEFAULT NULL,
PASSWORD VARCHAR(20) DEFAULT NULL
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO USER (id,NAME,PASSWORD) VALUES
(NULL,'狂神1','123456'),
(NULL,'狂神2','123456'),
(NULL,'狂神3','123456');

新建项目,导入Jar包

  • (SSM/Mybatis/project/MybatisFirst)

  • 新建一个普通maven项目

  • 删除src目录,就可以当一个父工程用

  • 导入以来

    • Mybatis
    • sql驱动
    • junit
    <!-- mysql-->
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.46</version>
    </dependency>
    <!-- mysql-->
    <!-- mybatis -->
    <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.2</version>
    </dependency>
    <!-- mybatis -->
    <!-- junit-->
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
    </dependency>
    <!-- junit-->

2.2 创建一个模块(父工程下的子工程)

  • 在父工程中导入了坐标,所有子模块不必再导

  • 编写Mybatis的核心配置文件 扔到src-main-resources下

    • 文件名 mybatis-config.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="development">
      <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
      <property name="driver" value="com.mysql.jdbc.Driver"/>
      <property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
      <property name="username" value="root"/>
      <property name="password" value="root"/>
      </dataSource>
      </environment>
      </environments>
      <!-- 每一个mapper.xml都需要在mybatis核心xml中注册-->
      <mappers>
      <mapper resource="com/bsx/dao/UserMapper.xml"/>
      </mappers>
      <!-- 每一个mapper.xml都需要在mybatis核心xml中注册-->
      </configuration>
  • 编写mybatis工具类

/***
* 工厂模式
* sqlSessionFactory -> sqlSession
*/
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
//获取sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
/***
* 从sqlSessionFactory里获取sqlSession 相当于jdbc的PreparedStatement
*/
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}

2.3 编写代码

  • 实体类Pojo(偷懒使用lombok)

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User implements Serializable {
    private int id;
    private String name;
    private String password;
    }
  • Dao接口(Mapper)

    public interface IUserDao {
    List<User> getUserList();
    }
  • 接口实现类 -> 映射配置文件 (现在Dao(Mapper)目录下) 在JDBC中,会在实现类中写数据库代码Mybatis避免几乎所有JDBC代码和手动设置参数和获取结果集

    • 新建UserMapper.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)
    相当于帮我们实现接口
    <mapper>标签下一共只有几个标签,包括了常用的CRUD
    - id: 方法名 (相当于实现类重写方法)
    对于实现类:接下来应当编写sql然后放到preparedStatement中执行
    再接收结果集
    Mybatis中配置好,自动扔给sqlSession执行sql
    - select标签下的其他属性
    - resultType: 返回一个,实体类类型
    - resultMap: 返回多个,封装为集合
    -->
    <mapper namespace="com.bsx.dao.IUserDao">
    <select id="getUserList" resultType="com.bsx.pojo.User">
    SELECT * FROM USER;
    </select>
    </mapper>

2.4 测试

warning

注意:需要在mybatis核心xml文件中,注册mapper的xml文件,否则会出现以下异常

org.apache.ibatis.binding.BindingException:
Type interface com.bsx.dao.IUserDao is not known to the MapperRegistry.
<!-- 每一个mapper.xml都需要在mybatis核心xml中注册-->
<mappers>
<mapper resource="com/bsx/dao/UserMapper.xml"/>
</mappers>
<!-- 每一个mapper.xml都需要在mybatis核心xml中注册-->
warning

注意:由于maven约定大于配置,可能会导致所写配置文件无法导出或者生效的问题,解决方案

<!-- 修改pom.xml,在build中配置resource资源过滤,来防止我们的资源导出失败 -->
<!-- 扫描src/main/resources下和src/main/java下的所有properties和xml文件-->
<!-- 我这里添加在父工程的pom.xml中就成功了,如果不成功可以在子模块的pom.xml里也来一份 -->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
  • Junit单元测试
public class UserDaoTest {
/***
* 在JDBC中,获取preparedStatement然后执行sql
*
* 在Mybatis中,获取sqlSession
* - 利用先前编写好的工具类,获取sqlSession
* - 用sqlSession执行sql语句,为此需要获取编写好的IUserDao对象,传入字节码文件
*/
@Test
public void test() {
//1. 获取sqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//2. 执行sql,getMapper传入接口字节码
IUserDao mapper = sqlSession.getMapper(IUserDao.class);
// 3. 方式一:getMapper
// 3. 调用方法时会跑到接口对应的Mapper.xml文件中,按照Mapper标签内配置的sql语句进行执行
List<User> userList = mapper.getUserList();
for (User user : userList) {
System.out.println(user);
}
// 方式二,不推荐
/*List<User> userList1 = sqlSession.selectList("com.bsx.dao.IUserDao.getUserList");
for (User user : userList1) {
System.out.println(user);
}*/
//4,关闭sqlSesuin
sqlSession.close();
}
}

可能出现的问题

  1. 配置文件没有注册
  2. 绑定接口错误 -> 要写全限定类名
  3. 方法名不对
  4. 返回类型不对 -> 要写实体类的全限定类名
  5. Maven导出资源问题
  6. 数据库,useSSL=true可能会失败,用useSSL=false
  7. 确保xml文件,idea全局,idea当前文件全部采用统一编码(推荐utf-8) 确保不了就不要在父工程的pom.xml中写中文注释