为了账号安全,请及时绑定邮箱和手机立即绑定

Mybatis持久层框架学习教程

标签:
Java SSM 数据库
概述

本文详细介绍了mybatis持久层框架学习的内容,包括Mybatis的基本概念、环境搭建与配置、CRUD操作、关联查询以及事务管理等。通过本文,你将全面掌握Mybatis的使用方法和技巧,提升数据库操作的灵活性和性能。

Mybatis持久层框架学习教程
Mybatis简介与安装配置

Mybatis是什么

Mybatis是一个优秀的持久层框架,它支持定制化SQL查询,存储过程和高级映射。Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。Mybatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。

Mybatis的优势与应用场景

Mybatis具有以下优势:

  1. 灵活性:Mybatis的灵活性主要体现在SQL语句的灵活性上,它可以完全自定义SQL语句,从而可以根据需要进行优化。
  2. 性能:Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集,从而显著减少了代码量,提升了应用的性能。
  3. 简洁性:Mybatis将接口和Java的POJOs映射成数据库中的记录,因此代码简洁,易于理解和维护。
  4. 可扩展性:Mybatis提供了一系列的插件机制,可以通过自定义插件来拦截Mybatis运行时的循环,以此来对Mybatis的功能进行扩展。
  5. 支持存储过程:Mybatis支持存储过程,提供了存储过程的支持。

Mybatis适用于以下场景:

  1. 需要自定义SQL语句:当业务逻辑复杂,需要自定义SQL语句时,可以使用Mybatis。
  2. 需要高性能:Mybatis可以避免编写大量的JDBC代码,减少代码量,提升应用性能。
  3. 需要简洁的代码:Mybatis提供了简洁的代码,易于理解和维护。
  4. 支持存储过程:当需要使用存储过程时,可以使用Mybatis。

Mybatis环境搭建与配置

Mybatis环境搭建与配置步骤如下:

  1. 下载Mybatis:首先,从Mybatis官网下载Mybatis的最新版本的jar包,将其添加到项目的ClassPath路径下。也可以通过Maven或Gradle等构建工具自动管理依赖。

  2. 创建数据库和表:创建一个数据库,并在其中创建一张表,用于测试。

  3. 创建实体类:创建一个与表对应的实体类,例如:

    public class User {
       private int id;
       private String username;
       private String password;
       private String email;
       private String phone;
    
       // 省略getter和setter方法
    }
  4. 创建XML映射文件:创建一个XML映射文件,用于定义表与实体类的映射关系,例如:

    <mapper namespace="com.example.mapper.UserMapper">
    
       <select id="selectUser" resultType="com.example.entity.User">
           SELECT id, username, password, email, phone
           FROM user
           WHERE id = #{id}
       </select>
    
       <insert id="insertUser">
           INSERT INTO user(username, password, email, phone)
           VALUES (#{username}, #{password}, #{email}, #{phone})
       </insert>
    
       <update id="updateUser">
           UPDATE user
           SET username = #{username}, password = #{password}, email = #{email}, phone = #{phone}
           WHERE id = #{id}
       </update>
    
       <delete id="deleteUser">
           DELETE FROM user
           WHERE id = #{id}
       </delete>
    
    </mapper>
  5. 创建SqlSessionFactory:创建一个SqlSessionFactory,用于生成SqlSession。SqlSessionFactory是线程不安全的,因此通常使用一个SqlSessionFactory的单例。

    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  6. 创建SqlSession:通过SqlSessionFactory生成SqlSession,用于执行各种数据库操作。

    SqlSession session = sqlSessionFactory.openSession();
  7. 编写Mapper接口:创建一个Mapper接口,用于定义SQL语句。Mapper接口中的方法名必须与XML映射文件中的id值对应。

    public interface UserMapper {
       User selectUser(int id);
       void insertUser(User user);
       void updateUser(User user);
       void deleteUser(int id);
    }
  8. 配置mybatis-config.xml:配置mybatis的全局配置文件,如数据源、事务管理器等。

    <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" />
                   <property name="username" value="root" />
                   <property name="password" value="password" />
               </dataSource>
           </environment>
       </environments>
       <mappers>
           <mapper resource="com/example/mapper/UserMapper.xml" />
       </mappers>
    </configuration>
  9. 执行SQL语句:通过SqlSession执行SQL语句,例如:

    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = mapper.selectUser(1);
    mapper.insertUser(new User(1, "zhangsan", "123456", "zhangsan@163.com", "12345678901"));
    mapper.updateUser(new User(1, "zhangsan", "123456", "zhangsan@163.com", "12345678901"));
    mapper.deleteUser(1);
    session.commit();
    session.close();
Mybatis的基本概念

SqlSessionFactory与SqlSession

SqlSessionFactory是一个工厂类,用于创建SqlSession对象。SqlSession是Mybatis中最重要的接口之一,它代表了和数据库交互的会话,能够执行预定义的SQL语句,并返回映射的数据。

创建SqlSessionFactory的代码如下:

String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

通过SqlSessionFactory创建SqlSession的代码如下:

SqlSession session = sqlSessionFactory.openSession();

Mapper接口与XML映射文件

Mapper接口是一个普通的Java接口,用于定义SQL语句。Mapper接口中的方法名必须与XML映射文件中的id值对应。

例如,创建一个Mapper接口:

public interface UserMapper {
    User selectUser(int id);
    void insertUser(User user);
    void updateUser(User user);
    void deleteUser(int id);
}

创建一个XML映射文件,用于定义表与实体类的映射关系:

<configuration>
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml" />
    </mappers>
</configuration>

Pojo与Sql语句绑定

Pojo是普通的Java对象,用于表示数据库中的记录。SQL语句用于定义数据库操作,例如查询、插入、更新和删除。

例如,创建一个Pojo:

public class User {
    private int id;
    private String username;
    private String password;
    private String email;
    private String phone;
    // 省略getter和setter方法
}

创建一个SQL语句,用于查询用户信息:

<select id="selectUser" resultType="com.example.entity.User">
    SELECT id, username, password, email, phone
    FROM user
    WHERE id = #{id}
</select>

参数和结果映射

参数和结果映射用于定义SQL语句中的参数和结果类型。

例如,创建一个SQL语句,用于插入用户信息:

<insert id="insertUser">
    INSERT INTO user(username, password, email, phone)
    VALUES (#{username}, #{password}, #{email}, #{phone})
</insert>

在上述SQL语句中,#{username}表示一个参数,它将被替换成实际的值。此外,还可以使用@Param注解为参数指定别名,例如:

public interface UserMapper {
    void insertUser(@Param("username") String username, @Param("password") String password, @Param("email") String email, @Param("phone") String phone);
}

在XML映射文件中,可以使用resultMap标签定义结果映射,如下所示:

<resultMap id="userResultMap" type="com.example.entity.User">
    <id column="id" property="id"/>
    <result column="username" property="username"/>
    <result column="password" property="password"/>
    <result column="email" property="email"/>
    <result column="phone" property="phone"/>
</resultMap>

在上述代码中,id表示主键,result表示普通字段。

Mybatis的CRUD操作

基本的增删改查语句

Mybatis支持基本的增删改查操作,这些操作可以通过Mapper接口和XML映射文件实现。

例如,创建一个Mapper接口,用于定义SQL语句:

public interface UserMapper {
    User selectUser(int id);
    void insertUser(User user);
    void updateUser(User user);
    void deleteUser(int id);
}

创建一个XML映射文件,用于定义表与实体类的映射关系:

<configuration>
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml" />
    </mappers>
</configuration>

例如,定义一个查询用户信息的SQL语句:

<select id="selectUser" resultType="com.example.entity.User">
    SELECT id, username, password, email, phone
    FROM user
    WHERE id = #{id}
</select>

定义一个插入用户信息的SQL语句:

<insert id="insertUser">
    INSERT INTO user(username, password, email, phone)
    VALUES (#{username}, #{password}, #{email}, #{phone})
</insert>

定义一个更新用户信息的SQL语句:

<update id="updateUser">
    UPDATE user
    SET username = #{username}, password = #{password}, email = #{email}, phone = #{phone}
    WHERE id = #{id}
</update>

定义一个删除用户信息的SQL语句:

<delete id="deleteUser">
    DELETE FROM user
    WHERE id = #{id}
</delete>

使用Mapper接口执行CRUD操作

使用Mapper接口执行CRUD操作的代码如下:

SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUser(1);
mapper.insertUser(new User(1, "zhangsan", "123456", "zhangsan@163.com", "12345678901"));
mapper.updateUser(new User(1, "zhangsan", "123456", "zhangsan@163.com", "12345678901"));
mapper.deleteUser(1);
session.commit();
session.close();

动态SQL的使用

动态SQL用于根据不同的条件生成不同的SQL语句。Mybatis提供了动态SQL标签,如ifchoosewhenotherwisetrimwheresetforeach等。

例如,创建一个Mapper接口,用于定义SQL语句:

public interface UserMapper {
    List<User> selectUsers(Map<String, Object> params);
}

创建一个XML映射文件,用于定义表与实体类的映射关系:

<configuration>
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml" />
    </mappers>
</configuration>

例如,定义一个查询用户信息的SQL语句,使用动态SQL:

<select id="selectUsers" resultType="com.example.entity.User">
    SELECT id, username, password, email, phone
    FROM user
    <where>
        <if test="username != null">
            username = #{username}
        </if>
        <if test="email != null">
            AND email = #{email}
        </if>
    </where>
</select>

使用动态SQL的代码如下:

SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
Map<String, Object> params = new HashMap<>();
params.put("username", "zhangsan");
params.put("email", "zhangsan@163.com");
List<User> users = mapper.selectUsers(params);
session.commit();
session.close();
Mybatis的关联查询

一对一关联查询

一对一关联查询用于查询两张表中的数据,其中两张表之间存在一对一的关系。

例如,创建两个实体类,分别为User和Address,User和Address之间存在一对一的关系:

public class User {
    private int id;
    private String username;
    private String password;
    private String email;
    private String phone;
    private Address address;
    // 省略getter和setter方法
}

public class Address {
    private int id;
    private String street;
    private String city;
    private String province;
    private User user;
    // 省略getter和setter方法
}

创建一个Mapper接口,用于定义SQL语句:

public interface UserMapper {
    User selectUser(int id);
}

创建一个XML映射文件,用于定义表与实体类的映射关系:

<configuration>
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml" />
    </mappers>
</configuration>

例如,定义一个查询用户信息的SQL语句,使用一对一关联查询:

<select id="selectUser" resultType="com.example.entity.User">
    SELECT u.id, u.username, u.password, u.email, u.phone, a.id as address_id, a.street, a.city, a.province
    FROM user u
    LEFT JOIN address a ON u.id = a.user_id
    WHERE u.id = #{id}
</select>

在上述代码中,定义了一个resultMap标签,用于定义User和Address的关系:

<resultMap id="userResultMap" type="com.example.entity.User">
    <id column="id" property="id"/>
    <result column="username" property="username"/>
    <result column="password" property="password"/>
    <result column="email" property="email"/>
    <result column="phone" property="phone"/>
    <association property="address" javaType="com.example.entity.Address">
        <id column="address_id" property="id"/>
        <result column="street" property="street"/>
        <result column="city" property="city"/>
        <result column="province" property="province"/>
    </association>
</resultMap>

使用一对一关联查询的代码如下:

SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUser(1);
session.commit();
session.close();

一对多关联查询

一对多关联查询用于查询两张表中的数据,其中两张表之间存在一对多的关系。

例如,创建两个实体类,分别为User和Order,User和Order之间存在一对多的关系:

public class User {
    private int id;
    private String username;
    private String password;
    private String email;
    private String phone;
    private List<Order> orders;
    // 省略getter和setter方法
}

public class Order {
    private int id;
    private String product;
    private String quantity;
    private User user;
    // 省略getter和setter方法
}

创建一个Mapper接口,用于定义SQL语句:

public interface UserMapper {
    User selectUser(int id);
}

创建一个XML映射文件,用于定义表与实体类的映射关系:

<configuration>
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml" />
    </mappers>
</configuration>

例如,定义一个查询用户信息的SQL语句,使用一对多关联查询:

<select id="selectUser" resultType="com.example.entity.User">
    SELECT u.id, u.username, u.password, u.email, u.phone, o.id as order_id, o.product, o.quantity
    FROM user u
    LEFT JOIN order o ON u.id = o.user_id
    WHERE u.id = #{id}
</select>

在上述代码中,定义了一个resultMap标签,用于定义User和Order的关系:

<resultMap id="userResultMap" type="com.example.entity.User">
    <id column="id" property="id"/>
    <result column="username" property="username"/>
    <result column="password" property="password"/>
    <result column="email" property="email"/>
    <result column="phone" property="phone"/>
    <collection property="orders" ofType="com.example.entity.Order">
        <id column="order_id" property="id"/>
        <result column="product" property="product"/>
        <result column="quantity" property="quantity"/>
    </collection>
</resultMap>

使用一对多关联查询的代码如下:

SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUser(1);
session.commit();
session.close();

多对多关联查询

多对多关联查询用于查询三张表中的数据,其中三张表之间存在多对多的关系。

例如,创建三个实体类,分别为User、Product和Order,User和Product之间存在多对多的关系:

public class User {
    private int id;
    private String username;
    private String password;
    private String email;
    private String phone;
    private List<Order> orders;
    // 省略getter和setter方法
}

public class Product {
    private int id;
    private String name;
    private String price;
    private List<Order> orders;
    // 省略getter和setter方法
}

public class Order {
    private int id;
    private User user;
    private Product product;
    // 省略getter和setter方法
}

创建一个Mapper接口,用于定义SQL语句:

public interface UserMapper {
    User selectUser(int id);
}

创建一个XML映射文件,用于定义表与实体类的映射关系:

<configuration>
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml" />
    </mappers>
</configuration>

例如,定义一个查询用户信息的SQL语句,使用多对多关联查询:

<select id="selectUser" resultType="com.example.entity.User">
    SELECT u.id, u.username, u.password, u.email, u.phone, o.id as order_id, p.id as product_id, p.name, p.price
    FROM user u
    LEFT JOIN order o ON u.id = o.user_id
    LEFT JOIN product p ON o.product_id = p.id
    WHERE u.id = #{id}
</select>

在上述代码中,定义了一个resultMap标签,用于定义User、Product和Order的关系:

<resultMap id="userResultMap" type="com.example.entity.User">
    <id column="id" property="id"/>
    <result column="username" property="username"/>
    <result column="password" property="password"/>
    <result column="email" property="email"/>
    <result column="phone" property="phone"/>
    <collection property="orders" ofType="com.example.entity.Order">
        <id column="order_id" property="id"/>
        <association property="product" javaType="com.example.entity.Product">
            <id column="product_id" property="id"/>
            <result column="name" property="name"/>
            <result column="price" property="price"/>
        </association>
    </collection>
</resultMap>

使用多对多关联查询的代码如下:

SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUser(1);
session.commit();
session.close();
Mybatis的事务管理

事务的基本概念

事务是数据库中的一种操作,它包含了一组数据库操作,这些操作要么全部成功,要么全部失败,不存在只完成一部分的操作。

Mybatis中事务的使用

Mybatis中事务的使用包括以下几个步骤:

  1. 开启事务:通过SqlSession的openSession()方法创建SqlSession对象,将参数设置为true,开启事务。

    SqlSession session = sqlSessionFactory.openSession(true);
  2. 执行数据库操作:通过SqlSession执行数据库操作。

    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = mapper.selectUser(1);
    mapper.insertUser(new User(1, "zhangsan", "123456", "zhangsan@163.com", "12345678901"));
  3. 提交事务:通过SqlSession的commit()方法提交事务。

    session.commit();
  4. 关闭资源:通过SqlSession的close()方法关闭SqlSession对象,释放资源。

    session.close();

事务的传播特性

事务的传播特性用于定义事务的传播行为,例如,是否需要创建新的事务,是否需要加入到现有事务中等。

Mybatis支持以下几种事务的传播特性:

  1. PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新的事务;如果当前存在事务,就加入到当前事务中。
  2. PROPAGATION_SUPPORTS:如果当前存在事务,就加入到当前事务中;如果当前不存在事务,就以非事务的方式继续运行。
  3. PROPAGATION_MANDATORY:如果当前存在事务,就加入到当前事务中;如果当前不存在事务,就抛出异常。
  4. PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,就暂停当前事务。
  5. PROPAGATION_NOT_SUPPORTED:以非事务的方式运行,如果当前存在事务,就暂停当前事务。
  6. PROPAGATION_NEVER:以非事务的方式运行,如果当前存在事务,就抛出异常。
  7. PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内运行;如果当前没有事务,则行为与PROPAGATION_REQUIRED相同。

例如,在Mapper接口中使用事务的传播特性:

public interface UserMapper {
    @Transactional(propagation = Propagation.REQUIRED)
    User selectUser(int id);
}
Mybatis的日志与调试

Mybatis的日志插件

Mybatis提供了多种日志插件,例如SLF4J、Log4j、JdkLogging、CommonsLogging等。

例如,使用Log4j作为日志插件:

<configuration>
    <settings>
        <setting name="logImpl" value="org.apache.ibatis.logging.log4j.Log4jImpl" />
    </settings>
</configuration>

Mybatis的配置与调试技巧

Mybatis的配置与调试技巧包括以下几个方面:

  1. 配置日志级别:在配置文件中设置日志级别,例如:

    <configuration>
       <settings>
           <setting name="logImpl" value="org.apache.ibatis.logging.log4j.Log4jImpl" />
       </settings>
    </configuration>
  2. 开启调试模式:在配置文件中开启调试模式,例如:

    <configuration>
       <settings>
           <setting name="configurationFactory" value="org.apache.ibatis.session.ConfigurationFactory" />
       </settings>
    </configuration>
  3. 使用事务管理:使用事务管理,保证数据库操作的完整性,例如:

    SqlSession session = sqlSessionFactory.openSession(true);
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = mapper.selectUser(1);
    mapper.insertUser(new User(1, "zhangsan", "123456", "zhangsan@163.com", "12345678901"));
    session.commit();
    session.close();
  4. 使用动态SQL:使用动态SQL,根据不同的条件生成不同的SQL语句,例如:

    <select id="selectUsers" resultType="com.example.entity.User">
       SELECT id, username, password, email, phone
       FROM user
       <where>
           <if test="username != null">
               username = #{username}
           </if>
           <if test="email != null">
               AND email = #{email}
           </if>
       </where>
    </select>
  5. 使用关联查询:使用关联查询,查询多张表中的数据,例如:

    <select id="selectUser" resultType="com.example.entity.User">
       SELECT u.id, u.username, u.password, u.email, u.phone, a.id as address_id, a.street, a.city, a.province
       FROM user u
       LEFT JOIN address a ON u.id = a.user_id
       WHERE u.id = #{id}
    </select>
  6. 使用事务传播特性:使用事务传播特性,定义事务的传播行为,例如:

    @Transactional(propagation = Propagation.REQUIRED)
    User selectUser(int id);
  7. 使用Mybatis的调试工具:使用Mybatis的调试工具,例如mybatis-spring-integration,它提供了Mybatis与Spring的集成,方便调试Mybatis。

通过上述配置与调试技巧,可以有效地调试Mybatis。

总结

Mybatis是一个优秀的持久层框架,它支持定制化SQL查询,存储过程和高级映射。通过本文的介绍,您应已经了解Mybatis的基本概念、事务管理、日志与调试等内容。希望本文能够帮助您更好地理解和使用Mybatis。更多详细的使用方法和技巧,您可以参考Mybatis的官方文档,或在Moo课网上学习更多相关课程。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消