mybatis框架是一款持久层框架,它支持自定义SQL、存储过程以及高级映射。Mybatis 免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。MyBatis可以通过简单的XML或注解来配置和映射实体类型、接口和Java POJO为数据库中记录。

Mybatis导入

1.创建maven工程引入依赖

引入mybatis依赖和数据库连接依赖即可,其余的看自己的需求。

  <!--mybatis的依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.9</version>
        </dependency>
        <!--mysql的依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>

        <!--lombok依赖[1]idea安装lombok插件 [2]引入依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
        </dependency>
        <!--junit单元测试-->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.10.2</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

2.创建mybatis配置文件

将下列property中的value值根据自己的需求进行更改,其余的可不作变动。

<?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">
                <!--name是固定的 value根据需要配置为自己的内容-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/数据库名" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>

    </environments>
</configuration>

3.映射文件编写

映射文件的配置可根据需求复制,其中<mapper> 标签里的内容需要根据自身项目进行编写。

<?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">
<?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">

<!--namespace:命名空间。需要和接口所在的包对应-->
<mapper namespace="com.aaa.dao.RoleDao">

    <!--select表示查询sql标签
           id:表示sql语句的唯一标识,通常使用mapper接口的全类名.方法名组成
           resultType:表示结果类型。 mysql执行完该sql后返回的数据类型

        #{id}:表示占位符。mybatis会自动给该占位符赋值
    -->
    <select id="getById" resultType="com.aaa.entity.Teacher">
        select * from tbl_teacher where id=#{id}
    </select>
</mapper>

4.把映射文件放到配置中

找到mybatis的配置文件,向其中添加映射文件的路径,放在<configuration>标签中。

    <mappers>
        <mapper resource="mapper/roleMapper.xml"/>
    </mappers>
<?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>
<!--    引入属性文件-->
    <properties resource="db.properties"></properties>
<!--    起别名-->
    <typeAliases>
        <package name="com.aaa.entity"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <!--name是固定的 value改为自己的内容-->
                <property name="driver" value="${jdbc.driver}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
            </dataSource>
        </environment>

    </environments>

    <!--引入对应的映射文件注意:改为自己的映射文件-->
    <mappers>
        <mapper resource="mapper/roleMapper.xml"/>
    </mappers>
</configuration>

到此mybatis即配置成功,可以根据数据库连接语句进行查询。

Mybatis接口绑定

mybatis提供了一种接口绑定模式,mybatis会自动为接口生成实现类。这样做的好处是传递方法是如果参数格式有误编译会自动提示。

这是Dao接口。

public interface RoleDao {

    public Role getRoleById(int id);
    public int insertRole(Role role);
    public int updateRole(Role role);
    public int deleteRole(int id);
    public List<Role> getAllRole();

}

这是映射文件。

这里注意命名空间必须和接口的存放路径对应才能根据接口映射。

<?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">

<!--namespace:命名空间。必须和接口对应-->
<mapper namespace="com.aaa.dao.RoleDao">
    <insert id="insertRole" useGeneratedKeys="true" keyProperty="id">
        insert into t_role(rolename,rolecode,description) values(#{rolename},#{rolecode},#{description})
    </insert>
    <update id="updateRole">
        update t_role set rolename = #{rolename}, rolecode = #{rolecode}, description = #{description} where id = #{id}
    </update>
    <delete id="deleteRole">
        delete from t_role where id =#{id}
    </delete>

    <select id="getRoleById" resultType="Role">
        select * from t_role where id =#{id}
    </select>

    <select id="getAllRole" resultType="com.aaa.entity.Role">
        select * from t_role
    </select>
</mapper>

Mybatis注解使用

mybatis提供了一种便捷方式进行sql语句的查询,使得我们不用在映射文件中编写sql语句。但这种方式仅限于单表。

举例:可以在注解中写Sql语句进行查询。

public interface TeacherDao {
    //适合单表的操作
    @Select(value = "select * from tbl_teacher where id=#{id}")
    public Teacher getById(int id);

    @Insert(value = "insert into tbl_teacher(name,age,salary) values(#{name},#{age},#{salary})")
    public int add(Teacher teacher);

    @Select(value = "select * from tbl_teacher")
    public List<Teacher> selectAll();

    public int delete(int id);
}

注意:如果只在Dao层编写sql而没有生成映射文件,需要在mybatis配置文件中,将映射路径更改为Dao层路径。如果既使用注解又使用映射文件可以在<mapper>中只填写mybatis配置文件的路径。(如果使用注解写了部分方法sql语句,就不要在xml文件再写了,会发生报错)

<mappers>
        <mapper class="com.aaa.dao.RoleDao"/>
</mappers>
    <mappers>
        <!--如果即用了注解又使用了xml文件,那么这里使用xml-->
        <mapper resource="mapper/TeacherMapper.xml"/>
    </mappers>

Mybatis的优化

1.生成sql执行语句

引入log4j依赖可以在控制台显示sql的执行语句,查看sql是否编写错误。

1.引入依赖

  <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

2.存放日志文件

创建一个名为log4j.properties文件,并填写下列内容。(注意:该文件名必须为log4j.properties,必须存放在resources下)

log4j.rootLogger=DEBUG, Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

进行上述操作后,对sql语句进行查询,就能看到sql语句的执行情况了。

2.为实体类起别名

需要在mybatis配置文件中添加<typeAliases>标签。放在<configuration>标签中。 name后填写你的实体类路径,如果不指定具体类名而是存放类的包,那么别名就是类的名称。

<typeAliases>
        <package name="com.aaa.entity"/>
</typeAliases>

这样resultType就可以直接 不用再填写路径,而是直接写别名即可。

  <select id="getAllRole" resultType="Role">
        select * from t_role
    </select>

3.把数据源信息提取到属性文件中

之前我们配置数据库时,将数据库的信息都再mybatis的配置文件中填写,这样在以后进行数据库的连接修改时很不方便,为此将数据库的信息单独提取出来进行配置。mybtais配置文件进行引入即可,方便日后数据库的修改。

1.创建一个配置文件

这里暂时创建一个db.properties文件,里面填写下列信息,实际上前面的格式并无要求,只是为了便于区分加了jdbc的前缀。等号后面填写自己的数据库连接信息。

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test03
jdbc.username=root
jdbc.password=123456

2.在mybatis配置文件中引入属性文件

在<configuration>中添加你创建的文件名。

 <properties resource="db.properties"></properties>

然后在原先 <property>标签的value值中用${}引用数据库配置文件的信息。

<configuration>
<!--    引入属性文件-->
    <properties resource="db.properties"></properties>
<!--    起别名-->
    <typeAliases>
        <package name="com.aaa.entity"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <!--name是固定的 value改为自己的内容-->
                <property name="driver" value="${jdbc.driver}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
            </dataSource>
        </environment>

    </environments>
</configuration>

4.Mybatis配置多个参数

Mybatis配置多个参数,默认Mybatis映射的接口方法只能传递一个参数,如果传递多个参数,传递给xml映射文件的参数名就变成了param1,param2等,这样不便于理解代码,为此可以使用@Param注解使得,传递的参数名就是方法的参数名。

举例:

5.Mybatis出现特殊字符

在Mybatis映射文件中如果使用特殊字符Mybatis会无法理解,这时需要使用转移字符或者CDATA标签才能够处理。

举例:<、>、&等都是特殊字符需要用转移字符或CDATA标签包裹sql语句才能识别。

 <!--在xml中出现特殊符号.处理特殊符合:
         1.第一种使用转义符: &lt;[<]  &gt;[>] &amp;[&]等
         2.第二种使用CDATA标签:<![CDATA[sql]]>
    -->
    <select id="selectRoleByUserIdScope" resultType="Role">
        <![CDATA[select * from t_role where id > #{min} and id < #{max}]]>
    </select>

6.获取主键递增的值

在进行sql语句时,某些时候需要获取到该对象的id值,但由于这时执行的操作没有包含id值,那么可以使用部分属性来进行获取。

举例:这是我进行了sql插入操作,我没有插入id值,但我又想获取到id值就需要添加属性

useGeneratedKeys ="true" 是否使用生成的主键值

keyProperty = "id" 把生成的主键值赋给哪个属性(这里我的实体类有id这个属性)

发现执行sql插入前获取不到id值,插入后获取到了id值 

7.模糊查询

 在Mybatis中进行模糊查询需要用concat连接符进行拼接。

<select id="selectByName" resultType="Role">
        select * from t_role where rolename like concat('%',#{name},'%')
    </select>

8.解决列名和属性名不一致问题 

在实际使用中,我们起的实体名和数据库名不可能永远一致,这时我们可以创建映射,使得实体类的属性名变得和数据库名一致,以便进行数据库的查询。

这里需要在映射文件的<mapper>标签中添加<resulMap> 标签,id为这个标签的唯一标识,type为你要映射的实体类型。

<resultMap> 标签为我们设置了主键映射和普通字段的映射,这里的column填写数据库中的列属性名,property中填写实体类的属性名。

    <resultMap id="baseMapper" type="com.aaa.entity.Role">
        <!-- 主键映射-->
        <id column="id" property="id" />
        <!-- 普通字段的映射 -->
        <result column="rolename" property="name" />
        <result column="rolecode" property="code" />
    </resultMap>

然后在有返回值对象的sql语句查询将resultType 更改为resultMap,等号后面填写你要映射的resultMap的id值。 

9.mybatis代码自动生成

如果装了mybatisX插件那么就可以让插件自动生成实体类和映射文件,并写好简单的sql语句,这将大大提升我们日常开发的效率。

 安装完插件后,需要在idea中连接数据库,将数据库连接后找到要使用的表,右键发现出现了MybatisX-Generator按钮。

 点击按钮后,Mybatis会先弹出一个实体类的生成选项,module path 选择您的模块路径,base package是要生成的实体类包的存放位置,relative package 是要填写生成的实体类包的名字,ignore table prefix 是根据数据库的表名生成的实体类是否忽略数据库表的前缀。

点击next后,会进行数据库接口方法的生成选项,如果在选择options中选择Lombok那么会为实体类添加Lombok注解,在template 中选择了default-all 那么会为接口方法生成对应的sql映射文件。

 10.pagehelper的使用

分页查询可以借助插件来进行查询,这样可以提升代码的开发效率,也使得分页查询功能的实现变得更为简单。

我们需要先引入pageHelper的依赖。

   <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.3.3</version>
        </dependency>

然后在mybatis配置文件<configuration>中添加<plugins>标签

<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">

        <property name="param1" value="value1"/>
    </plugin>
</plugins>

这样我们就完成了pagehelper插件的配置,接下来进行使用。

在进行数据库查询前先开启PageHelper,其中startPage的第一个参数是查询的页数,第二个参数是每页的数据数。这样就完成了分页查询,它会帮我们在sql语句中拼接 limit。

如果想知道总数据可以获取pageInfo对象,使用pageInfo.getTotal()就能获取,总页数也同样通过pageInfo.getPages()获取。

 //1.开启分页--使用PageHelper分页.查询前开启分页
        PageHelper.startPage(1,3);
        List<Teacher> teachers = teacherDao.selectAll();
        //2.把查询的结果封装到PageInfo类中
        PageInfo<Teacher> pageInfo=new PageInfo<>(teachers);
        //3.展示相关的信息
        System.out.println("总数据数:"+pageInfo.getTotal());
        System.out.println("总页数:"+pageInfo.getPages());
        System.out.println("当前的记录:");
        List<Teacher> list = pageInfo.getList();
        for(Teacher t:list){
            System.out.println(t);
        }

11.mybatis中多对一的实现

在数据查询中,通常会出现一个表中的数据多次对应另一个表中的数据。例如有一个员工表,员工都有对应的部门,可能会有多个员工对应一个部门的情况。这个时候如果我们要查询员工的部门信息,就需要进行联表查询。为此mybatis提供了一个标签帮助我们进行查询。

这里我们需要在员工实体类下添加一个部门对象的信息,使得进行联表查询时将部门的信息存放在员工对象中。

 这里在进行结果映射中添加了<association>标签,其中 property表示员工实体类的 dept属性,javaType 表示这个dept属性所属于哪个路径下的实体类。    之后的步骤就跟之前的<resultMap>表签中的内容一致。

然后进行联表查询就会发现数据已经关联到了。

12.mybatis中一对多的实现 

之前举例是通过员工表查询部门表的信息,那么反过来,通过部门表查所有员工的信息该如何查询呢?       

首先我们在部门的实体类下创建一个员工集合的属性。

 然后我们在部门表的映射文件中添加<resultMap>标签,这里用到了<collection>标签用来关联我们刚创建的emps集合属性。 property属性填写实体类的emps属性,ofType填写这个集合实体类的路径。之后的内容就跟之前的<resultMap>用法一致,填写emp员工的映射即可。

这里别忘了写resultMap 

这里我们就完成了一对多的映射。之后进行联表查询就能发现数据成功映射。 

13.动态Sql

动态sql可以帮助我们完成sql的拼接,例如有的时候查询会根据许多不同的条件,如果按照之前所展示的方法那么就要写多条sql语句,这样十分的耗费时间和精力,为此mybatis提供了一个快捷方式,可以在映射文件中动态地根据条件更改sql语句,使得代码的复用性提高。

这里先展示可能要用到的动态sql标签,我们利用这些标签来实现动态sql

  • <trim>:通过修剪 SQL 语句的开头和结尾来动态生成 SQL 片段。它可以用于去除不必要的 SQL 关键字或条件语句,并提供了一些属性来定义修剪规则。
  • <where>:用于在生成的 SQL 语句中添加 WHERE 子句。它可以自动处理条件语句的前缀,并在有条件语句存在时添加 WHERE 关键字。而且会去除sql的第一个and标签。
  • <set>:用于在生成的 SQL 语句中添加 SET 子句。它主要用于更新操作,可以根据条件来动态生成需要更新的列。
  • <foreach>:用于在生成的 SQL 语句中进行循环操作。它可以遍历集合或数组,并根据指定的模板将集合元素或数组元素插入到 SQL 语句中。
  • <if>:用于在生成的 SQL 语句中添加条件判断。可以根据指定的条件决定是否包含某个 SQL 语句片段。
  • <choose>:类似于 Java 中的 switch 语句,根据条件选择执行不同的 SQL 语句片段。它可以包含多个 <when> 和一个可选的 <otherwise> 标签。
  • <when>:用于在 <choose> 标签中定义条件分支。可以根据指定的条件判断是否执行特定的 SQL 语句片段。
  • <otherwise>:在 <choose> 标签中可选的标签,用于定义当没有任何 <when> 条件匹配时执行的 SQL 语句片段。

 这里我用到了where标签和if标签,where标签用于在生成的sql语句中添加where字句。并在有条件语句存在时添加where关键字,而且会去除sql的第一个and标签。

 

<foreach>标签通常用来执行某些批量操作。例如批量增加,批量删除。

这里我进行了批量删除的操作, collection属性表是接收传递的集合参数,item为集合下的每个数据别名,open表示在整个集合循环中的开始添加的内容,close表示在整个集合循环中结束添加的内容,separator表示集合循环时每个数据用什么分隔

 

这里我又进行了批量增加的操作

 

 <choose><when>和<otherwise>类似于java中的switch语句,它只会执行其中一个<when>标签里的内容。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐