Mybatis-基础使用

前言

Mybatis是一款Java持久层框架,内部将操作数据库需要的Jdbc相关代码进行了封装,同时能将SQL语句执行结果与Pojo直接进行映射。本篇文章将先对Jdbc进行学习,并在此基础上学习Mybatis的基础使用,无论是Jdbc还是Mybatis,均是基于原生组件,不会与Spring等框架进行整合。

Mybatis版本:3.5.6

正文

一. Jdbc基础

Jdbc全称为JavaDataBase Connectivity,即Java数据库连接,基于Jdbc可以获取数据库连接并执行SQL语句,还能处理SQL语句的执行结果集。下面将对Jdbc的操作步骤进行介绍。

1. 加载数据库驱动

首先需要加载数据库驱动,这里以Mysql数据库驱动为例,如下所示。

Class.forName("com.mysql.jdbc.Driver");

2. 获取数据库连接

然后需要获取数据库连接,如下所示。

// url用于标识数据库位置,即告诉Jdbc连接哪个数据库
String url = "jdbc:mysql://127.0.0.1:3306/test";
// 数据库用户名和密码
String username = "root";
String password = "root";
// Connection是数据库编程中的一个重要对象,客户端与数据库的所有交互均依赖该对象
Connection connection = DriverManager.getConnection(url, username, password);

Connection对象部分重要方法如下所示。

方法 描述
Statement createStatement() 创建向数据库发送SQLStatement对象
PreparedStatement prepareStatement(String sql) 创建向数据库发送预编译SQLPreparedStatement对象
commit() 提交事务
rollback() 回滚事务

3. 获取Statement对象

Statement对象用于向数据库发送SQL语句,获取方式如下所示。

Statement statement = connection.createStatement();

Statement对象的常用方法如下所示。

方法 描述
ResultSet executeQuery(String sql) 向数据库发送查询SQL语句
int executeUpdate(String sql) 向数据库发送插入,更新或删除SQL语句
boolean execute(String sql) 向数据库发送任意SQL语句

使用Statement的查询示例如下所示。

Statement statement = connection.createStatement();
String sql = "SELECT * FROM worker";
ResultSet resultSet = statement.executeQuery(sql);

由于Statement的使用会引入安全效率问题,所以通常Jdbc执行SQL语句是基于PreparedStatement对象。PreparedStatement继承于Statement,使用PreparedStatement的查询示例如下所示。

String sql = "SELECT * FROM worker WHERE sex = ?"
// 获取PreparedStatement对象时就需要传入SQL语句进行预编译
PreparedStatement preparedStatement = connection.prepareStatement(sql);
// 设置参数,将第一个占位符替换为"male"
preparedStatement.setString(1, "male");
// 执行查询,查询结果由ResultSet对象封装
ResultSet resultSet = preparedStatement.executeQuery();

相较于Statement对象,PreparedStatement对象执行效率更高(因为对SQL语句完成了预编译),并且可以防止SQL注入(因为获取PreparedStatement对象时就需要传入SQL语句进行预编译,此时不会产生用户输入数据改变SQL语句结构的现象)。

4. 处理执行结果

ResultSet代表JdbcSQL语句的执行结果。ResultSet封装执行结果时,采用的是表格的方式,ResultSet对象维护了一个指向表格数据行的游标,初始状态时,游标在第0行(此时没有指向结果数据),调用next()方法后,游标会指向结果数据里的第一行数据,此时可以通过ResultSet对象来操作游标指向的这一行数据。ResultSet的常用方法如下所示。

方法 描述
boolean next() 游标移动到下一行
boolean previous() 游标移动到上一行
boolean absolute( int row ) 游标移动到指定行
Object getObject(int columnIndex) 获取游标指向的行的第columnIndex列的任意类型数据
Object getObject(String columnLabel) 获取游标指向的行的columnLabel列的任意类型数据

5. 释放连接

操作完数据库后,需要释放连接,如下所示。

if (resultSet != null) {
    resultSet.close();
}
if (preparedStatement != null) {
    preparedStatement.close();
}
if (connection != null) {
    connection.close();
}

二. Mybatis基础使用

1. Mybatis结构

Mybatis的一个整体结构如下所示。

上图中出现的Mybatis的组件的说明如下。

组件 说明
mybatis-config.xml Mybatis的全局配置文件。配置Mybatis的运行环境(数据库连接等)。
Mapper.xml 映射文件。映射文件中配置了操作数据库的SQL语句。
SqlSessionFactory 通过mybatis-config.xml文件构建SqlSessionFactory,称为会话工厂。用于创建SqlSession
SqlSession 通过SqlSessionFactory创建SqlSession,称为会话。操作数据库需要通过SqlSession进行。
Executor SqlSession内部通过Executor执行数据库操作。
MappedStatement Executor通过MappedStatement在执行SQL语句前将输入的参数映射到SQL语句中,在执行SQL语句后将输出结果映射到设置的输出结果类型中。

2. 原始Mybatis使用

原始Mybatis的使用中,在引入Mybatis的包以及配置好mybatis-config.xml之后,最重要的就是编写映射文件(Mapper.xml)。这里给出一个映射文件如下所示。




    

原始Mybatis执行映射文件时,首先需要获取SqlSession,然后通过SqlSession来调用映射文件。获取SqlSession的步骤如下所示。

// 指定全局配置文件
String resource = "mybatis-config.xml";
// 读取全局配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
// 构建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();

SqlSession调用映射文件的示例如下所示。

// 第一个参数为:(映射文件的)命名空间 + "." + (映射文件的SQL语句的)id
// 第二个参数为:需要执行的SQL语句的参数值
List workers = sqlSession.selectList("MyMapper.selectWorker", "male");

最后不要忘记关闭SqlSession,如下所示。

if (sqlSession != null) {
    sqlSession.close();
}

3. 动态代理Mybatis使用

动态代理Mybatis使用时,需要编写映射文件和映射接口,这里先给出映射文件,如下所示。


    

上面的映射文件中,标签的namespace属性需要设置为与映射文件关联的映射接口的全限定名,标签

标签的使用。

例子1:通过Map传入两个参数,分别为age和salary,然后查询年龄大于age并且工资大于salary的所有工人数据。

映射文件如下所示。




    

映射接口如下所示。

public interface WorkerMapper {

    List selectAgeSalaryByMap(Map map);

}

测试代码如下所示(省略SqlSession的获取)。

......
WorkerMapper workerMapper = sqlSession.getMapper(WorkerMapper.class);
Map map = new HashMap<>();
map.put("age", 20L);
map.put("salary", 10000L);
List workers = workerMapper.selectAgeSalaryByMap(map);
......

例子2:通过Java Bean传入两个参数,分别为age和salary,然后查询年龄大于age并且工资大于salary的所有工人数据。

Java Bean如下所示。

public class SelectInfo {

    private Long age;
    private Long salary;

    public Long getAge() {
        return age;
    }

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

    public Long getSalary() {
        return salary;
    }

    public void setSalary(Long salary) {
        this.salary = salary;
    }
    
}

映射文件如下所示。




    

映射接口如下所示。

public interface WorkerMapper {

    List selectAgeSalaryByBean(SelectInfo selectInfo);

}

测试代码如下所示(省略SqlSession的获取)。

......
WorkerMapper workerMapper = sqlSession.getMapper(WorkerMapper.class);
SelectInfo selectInfo = new SelectInfo();
selectInfo.setAge(20L);
selectInfo.setSalary(10000L);
List workers = workerMapper.selectAgeSalaryByBean(selectInfo);
......

2. 标签

标签表示插入SQL语句,Mybatis执行完一条插入语句后,将返回一个整数表示其影响的行数。标签属性与标签的属性大体一致,并且在执行后会返回一个整数表示影响的记录数。

4. 标签

从数据库中查询出数据时,通常会将查询出来的数据映射成一个Java Bean,但是如果数据库表的列名与Java Bean的属性名不一致时,会无法进行映射,此时需要使用标签来指定表列名和Java Bean属性名之间的映射关系。现在创建一张名为book的表,如下所示。

CREATE TABLE book(
    id INT(11) PRIMARY KEY AUTO_INCREMENT,
    b_name VARCHAR(255) NOT NULL,
    b_price INT(11) NOT NULL
)

创建一个Book类,用于与book表的查询结果进行映射,如下所示。

public class Book {

    private long id;
    private String bookName;
    private long bookPrice;

    // 省略getter和setter
    ......

}

可以看到,Book类的bookNamebookPrice属性与book表的b_nameb_price列的名称不一致,从book表查询出的数据无法映射到Book类上,此时需要使用标签来解决无法映射的问题。映射文件如下所示。




    
        
        
        
    

    

标签的id属性表示当前namespace下的唯一标识,可以通过标签的id属性来引用该标签的type属性表映射类的全限定名,比如需要与Book类进行映射,则type字段应该为Book类的全限定名。标签下,一个标签代表一对表列名和类属性名的映射,标签的column属性为表的列名,标签的property属性为类属性名。

上面映射文件对应的映射接口如下所示。

public interface BookMapper {

    List selectBookByName(String bookName);

}

测试代码如下所示(省略SqlSession的获取)。

......
BookMapper bookMapper = sqlSession.getMapper(BookMapper.class);
List mathBooks = bookMapper.selectBookByName("Math");
......

如果Book类中有一个属性为一个类,如下所示。

Book

public class Book {

    private long id;
    private String bookName;
    private long bookPrice;

    private BookStore bookStore;

    // 省略getter和setter
    ......

}

BookStore

public class BookStore {

    private long bsId;
    private String bsName;

    // 省略getter和setter
    ......

}

此时映射文件如下所示。




    
        
        
        

        
            
            
        
    

    

关于Mybatis标签的基础语法就分析到这里,其中标签作为Mybatis中的功能最强大标签,其所能实现的功能远不止上述介绍的功能,后续会单独就标签的使用进行深入学习。

总结

本文对JDBC的基础使用和Mybatis的基础使用进行了分析,并针对Mybatis的映射文件中的常用标签的基础语法进行了介绍。通常Mybatis的使用需要编写映射文件和映射接口,且一个映射文件与一个映射接口相对应,Mybatis会使用JDK动态代理为映射接口生成代理对象,当调用映射接口的方法时,调用请求会被代理对象拦截,然后根据映射接口全限定名+方法名定位到相应的MappedStatement然后执行SQL语句。

你可能感兴趣的:(Mybatis-基础使用)