MyBatis基础使用

文章介绍了MyBatis的基本概念和历史,包括从iBATIS到MyBatis的转变。通过创建DAO、XML映射文件和配置文件展示了如何启动MyBatis,以及如何通过接口和注解进行数据库操作。文中还提到了字段映射和Spring整合的重要性。
摘要由CSDN通过智能技术生成

Mybatis的前身是iBATIS,是2001年发起的开源项目,在2004年作者将它捐给了Apache软件基金会,在接下来6年中,开源世界的基础、许可及数据库技术等都发生了很大变化,到2010年,核心开发团队离开了Apache软件基金会,将iBATIS改名为Mybatis。和其它的ORM框架不同,Mybatis并没有将Java对象与数据表绑定,而是将Java对象的方法和SQL语句关联,所以说如果是需要对SQL语句有完全控制的需求,Mybatis是一个不错的选择

让MyBatis跑起来

在使用之前,明确以下两点原则,有助于提纲挈领

  1. 在Java中通用的与数据库打交道的相关事情,都需要遵守JDBC,Mybatis也不例外
  2. Mybatis的整个故事都开始于SqlSessionFactory

最简单的使用Mybatis只需要以下几个步骤:

  1. 创建一个DAO对象,确保有对应库表
  2. 创建一个XML,里面写一个和DAO对象有关系的语句
  3. 创建mybatis-config,通过该配置文件生成SqlSessionFactory
  4. SqlSessionFactory打开session,并执行相关调用

基本的项目搭建不再赘述,需要注意的是mysql-connector-java和你的MySQL版本需要一致,否则可能会出现调用异常。
首先我们创建一个简单的实体类User,对应的数据表是sys_user,并创建一个简单的mapper文件,在其中编写一个selectAll方法

@Data
public class User {
    private Long id;
    private String userName;
    private String userPassword;
    private Date createTime;
}
<?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">
<mapper namespace="userMappler">
    <resultMap id="userMap" type="model.User">
        <id property="id" column="id"/>
        <result property="userName" column="user_name"/>
        <result property="userPassword" column="user_password"/>
        <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
    </resultMap>

    <select id="selectAll" resultMap="userMap">
        select * from sys_user
    </select>
</mapper>

接下来是配置文件,现在就算我们什么也不知道,稍微一想的话,这配置文件里起码也该有数据库连接的相关配置,以及某些让mybatis能找到mapper文件的配置,而我们现在的配置文件中也确实只需要这些信息

<?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">
                <property name="" value=""/>
            </transactionManager>
            <dataSource type="UNPOOLED">
                <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=""/>
            </dataSource>
        </environment>
    </environments>

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

准备就绪后,现在我们就可以写一个测试用例来执行一下查询语句。测试代码非常容易理解,我们通过配置文件生成了SqlSessionFactory,之后开启一个session,用mapper中select语句的id作为参数进行调用,这样我们就可以获取到数据库中数据。

/**
 * @Author Sonnsei
 * @Date 2023/7/13 11:59 PM
 * Have a great day!
 **/
public class UserMapperTest {
    private static SqlSessionFactory sqlSessionFactory;

    @BeforeClass
    public static void init(){
        try {
            Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void selectAllTest(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try{
            List<User> users = sqlSession.selectList("selectAll");
            System.out.println(users);
        }finally {
            sqlSession.close();
        }
    }
}

引入接口和注解

在平时的工作中我们几乎不会直接用XML标签节点id作为参数来进行方法调用,最最起码也得有个接口,所以我们现在首先就尝试一下接口调用的方式来重写一下之前的逻辑。

首先我们写一个接口,用来定义我们的数据库操作

/**
 * @Author Sonnsei
 * @Date 2023/7/18 10:15 PM
 * Have a great day!
 **/
public interface UserMapper {
    List<User> selectAll();
}

有了这个接口以后,其实可以看下下面的代码,我们最终的测试代码改动非常的小,只是获取了一个UserMapper的接口实现,然后调用其中的方法。当然,测试代码现在还不能执行,稍微一想就能知道,要让MyBatis感知到这个接口,并且能让它知道去哪找对应的写在XML里面的语句。

public void selectAllTest(){
    SqlSession sqlSession = sqlSessionFactory.openSession();
    try{
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = userMapper.selectAll();
        System.out.println(users);
    }finally {
        sqlSession.close();
    }
}

回想一下,我们之前在配置文件中其实已经扫过mapper的xml文件了,而xml中有一个namespace属性,mybatis就可以通过这个属性将接口和xml关联起来,我们现在要做的就是将userMapper.xml中的namespace改成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">
<mapper namespace="com.sonnse.mapper">
    <resultMap id="userMap" type="model.User">
        <id property="id" column="id"/>
        <result property="userName" column="user_name"/>
        <result property="userPassword" column="user_password"/>
        <result property="userEmail" column="user_email"/>
        <result property="userInfo" column="user_info"/>
        <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
    </resultMap>

    <select id="selectAll" resultMap="userMap">
        select * from sys_user
    </select>
</mapper>

这样一来,我们的测试代码就可以正常运行了。

现在还有一个问题,如果我们定义了很多个Mapper的xml文件,难道需要在配置文件中全都写一遍吗?其实全部写一遍也行,但是我们确实有一些更为快捷优雅的方式。像前面说的,通过namespace,xml文件和接口就能建立联系,那反过来其实也是可以的,只是对类路径和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">-->
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    ......

    <mappers>
<!--        <mapper resource="mapper/UserMapper.xml"/>-->
        <package name="com.sonnsei.mapper"/>
    </mappers>
</configuration>

可以看到,我们将mappers标签中的一个个mapper元素直接替换成了package标签,而内容的com.sonnse.mapper则是我们的接口所在包的名称,此时,我们的UserMapper接口的全定名是com.sonnsei.mapper.UserMapper,我们的mapper的xml文件的资源目录则是resources/mapper/UserMapper.xml,现在我们去执行测试方法的时候它会绑定失败,这是为何?我们之前扫描xml的时候通过namespace的全限定名可以直接找到接口建立联系,那通过接口是如何找到xml的呢?答案很简单,以我们的com.sonnsei.mapper.UserMapper为例,它会根据类名去寻找resources/com/sonnsei/mapper/UserMapper.xml这个文件,所以说扫描接口的时候,我们的xml资源文件的位置是需要注意的。当我们把xml放到指定位置后,测试方法不出意外地顺利执行了。

最后来说一下注解。注解其实就是提供了另一种方式让我们来定义方法对应的查询语句,如下所示,我们用注解的方式写一个根据id单个查询的

/**
 * @Author Sonnsei
 * @Date 2023/7/18 10:15 PM
 * Have a great day!
 **/
public interface UserMapper {
    List<User> selectAll();

    @Select({"select * from sys_user where id = #{id}"})
    User selectById(long id);
}

但是如果这样直接去执行测试的话,我们会发现它获取不到属性值
User(id=1, userName=null, userPassword=null, createTime=null)
这是因为我们之前是在XML中通过resultMap定义了数据表字段到Java对象字段之间的映射的,我们知道数据表字段名一般使用蛇形命名,而Java是使用驼峰,所以在很多情况下它们的字段名都是不相等的,所以就需要做一个映射。
首先,我们可以使用mybatis的自动下划线转驼峰来进行处理,只需要在配置文件中增加一些如下配置来打开该功能,这里值得注意的是,配置文件中各标签之间是有顺序要求的,如果顺序不对,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">-->
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"></setting>
    </settings>
  	......
</configuration>

此时我们再执行测试用例时,便可以得到预期结果
User(id=1, userName=sc, userPassword=12345, createTime=Tue Jul 18 20:28:08 CST 2023

此外,注解其实也支持我们做字段的映射,如下所示增加我们的注解信息,也是可以拿到预期结果的

/**
 * @Author Sonnsei
 * @Date 2023/7/18 10:15 PM
 * Have a great day!
 **/
public interface UserMapper {
    List<User> selectAll();

    @Results({
            @Result(property = "userName", column = "user_name"),
            @Result(property = "userPassword", column = "user_password"),
            @Result(property = "createTime", column = "create_time"),
    })
    @Select({"select * from sys_user where id = #{id}"})
    User selectById(long id);
}

最后,无论是XML还是注解,我们都是可以通过SQL的字段更名功能直接把结果集字段映射成Java对象字段的。


在我们平时的工作中,因为Spring已经成为Java开发最普遍的一个标准,所以对于MyBatis我们接触较多的也是其与Spring的整合,如果单纯是使用的话,应该把终点放在mybatis-spring上,我们之后也会对其进行介绍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值