Mybatis的使用

本文深入介绍了MyBatis框架的使用,包括引入依赖、创建数据库和表、实体类、配置文件、DAO接口和映射文件。接着讨论了MyBatis的优化,如实体类别名、SQL日志、插件安装和Lombok应用。还涵盖了参数传递、主键返回、列名映射、动态SQL和分页插件PageHelper的使用。最后提到了逆向工程和MyBatis的缓存机制。
摘要由CSDN通过智能技术生成

目录

1. mybatis的介绍:

2. 为什么使用mybatis框架.

3. 如何使用mybatis.

3.1 引入mybatis和mysql的jar包

3.2 创建数据库和表

3.3 创建实体类

3.4 创建mybatis的配置文件

 3.5 创建一个dao接口并定义自己需要的方法。

3.6 创建mybatis和数据库的映射文件

3.7 测试mybatis

4. mybatis一些优化

4.1 为实体类起别名

4.2 添加sql日志

4.3 安装mybatis插件

4.4 lombok插件

5. 传递多个参数

6. 添加时如何返回递增的主键值

7. 解决列名和属性名不一致

8. 动态sql

 8.1 if标签--单条件判断

8.2 choose标签 多条件分支判断

8.3 where标签

8.4 set标签

8.5 foreach标签

8.6 sql片段

8.7 mybatis映射文件处理特殊字符

8.8 mybatis完成模糊查询

8.9 联表查询

9. 分页插件PageHelper

10. 逆向工程:mybatis的代码生成器--generator

11. mybatis的缓存



1. mybatis的介绍:

MyBatis 是一款优秀的持久层Dao框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis
 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XM
 L 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Java实体类)映射成数据库中的
 记录.

2. 为什么使用mybatis框架.

可以简化jdbc的操作以及占位符赋值以及查询结果集的封装。

3. 如何使用mybatis.

3.1 引入mybatis和mysql的jar包

  <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
​
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>

3.2 创建数据库和表

DROP TABLE IF EXISTS `tbl_user`;
CREATE TABLE `tbl_user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255),
  `email` varchar(255)
);

3.3 创建实体类

package com.zpb.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private int id;
    private String name;
    private String email;
}

3.4 创建mybatis的配置文件

<?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" />
            <!--数据源的配置:name的值固定  value的值要根据客户自己修改-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver" />
                <property name="url"    value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>
     <!--注意:==把映射文件注册到配置文件上== mybatis.xml上-->
     <mappers>
        <!--resource:引用资源文中的映射文件 url:网络上的映射文件-->
         <mapper resource="mapper/UserMapper.xml" />
    </mappers>
</configuration>

 3.5 创建一个dao接口并定义自己需要的方法。

public interface UserDao {
    /**
     * 查询所有
     * @return
     */
    public List<User> findAll();
}

3.6 创建mybatis和数据库的映射文件

    <?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:命名空间
          企业开发模式命名要与dao的路径一致
    -->
    <mapper namespace="com.zpb.dao.UserDao">
        <!--查询 
              select标签用于查询的标签
                 id:标签的唯一标识, id和dao中的方法名必须一致
                 resultType: 定义返回的类型 把sql查询的结果封装到哪个实体类中
             #{id}===表示占位符等价于?  这是mybatis框架的语法
        -->
        <select id="findAll" resultType="com.zpb.entity.User">
            select * from tbl_user
        </select>
    </mapper>

3.7 测试mybatis

public class Test01 {
    public static void main(String[] args) throws Exception {
    @Test
    public void testFindAll()throws Exception{
        //1.读取mybatis配置文件的内容----未来不需要写tomcat 解析配置文件
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        //2. 获取SqlSessionFactory对象
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
        //3. 获取SqlSession对象----封装了对数据库操作的各种方法
        SqlSession session = sessionFactory.openSession();
        //4. 获取相应接口的代理对象
        UserDao userDao = session.getMapper(UserDao.class);
        List<User> list = userDao.findAll();
        System.out.println(list);
        session.close();
    }
}
​

4. mybatis一些优化

4.1 为实体类起别名

mybatis.xml配置文件

 <typeAliases>
        <!--单独为某个实体类起别名 -->
         <typeAlias type="com.zpb.entity.User" alias="u"/>
        <!--为指定包下的实体类起别名该别名就是实体类名-->
         <package name="com.zpb.entity"/>
    </typeAliases>

4.2 添加sql日志

(1)添加日志的jar.

 <!--log4f-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

(2) 添加日志的文件配置--log4j.properties

简略:

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

详细:

#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file
​
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
​
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=D:/qy151/log/qy151.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
​
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

4.3 安装mybatis插件

Free Mybatis Tool或者MybatisX

作用: 检查dao和映射文件是否匹配

4.4 lombok插件

在实体类中加入注释,它可以帮你生成实体类的get和set方法 而且可以帮你生成构造方法。重写toString方法

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private int id;
    private String name;
    private String email;
}

5. 传递多个参数

我们在dao接口中某些方法可能需要传递多个参数,譬如: 登录(username,password),我们需要在参数处使用@Param()为参数起名

    public User findByNameAndEmail(@Param("name")String username,@Param("email") String email);

6. 添加时如何返回递增的主键值

<!--添加用户
          useGeneratedKeys:设置使用生成的主键=true
          keyProperty: 赋值给哪个属性
    -->
    <insert id="addUser" parameterType="com.zpb.entity.User"
            useGeneratedKeys="true" keyProperty="userId">
          insert into tbl_user values(null,#{username},#{email})
    </insert>

7. 解决列名和属性名不一致

第一种: 为查询的列起别名,而别名和属性名一致。

<!--根据id查询学生信息-->
    <select id="findOne" resultType="com.zpb.entity.Student">
        select stu_id id,stu_name name,stu_age age from tb_stu where stu_id=#{id}
    </select>

第二种: 使用resultMap完成列和属性之间的映射关系。

   <resultMap id="resultMap" type="com.zpb.entity.Student">
         <!--主键的映射关系 column:列名 property:属性名-->
         <id column="stu_id" property="id"/>
         <!--普通列的映射关系-->
         <result column="stu_name" property="name"/>
         <result column="stu_age" property="age"/>
    </resultMap>
​
 <!--resultType和ResultMap二者只能用一个-->
    <select id="findOne" resultMap="resultMap">
        select * from tb_stu where stu_id=#{id}
    </select>

8. 动态sql

为什么要使用动态sql

传统jdbc⽅法中,在写组合的多表复杂sql语句时,需要去拼接sql语句,稍不注意少写⼀个空格或“”,就会导致报错。
这个Mybatis动态sql的功能,就拥有有效的解决了这个问题,Mybatis动态sql语⾔可以被⽤在任意的sql语句映射中。

mybatis中动态sql标签有哪些?

 8.1 if标签--单条件判断

//如果name和password都为null则查询所有
public List<People> findByContains(@Param("name")String name, @Param("password") String password);
<select id="findByContains" resultType="com.zpb.entity.People">
        select * from t_people where 1=1
        <if test="name!=null and name!=''">
            and name=#{name}
        </if>
        <if test="password!=null and password!=''">
            and password=#{password}
        </if>
    </select>

8.2 choose标签 多条件分支判断

    <select id="findByCondition" resultMap="com.zpb.entity.People">
        select * from t_people where 1=1
        <choose>
            <when test="name!=null and name!=''">
                and t_name=#{name}
            </when>
            <when test="age!=null and age!=''">
                and t_age=#{age}
            </when>
            <otherwise>
                and t_address="深圳"
            </otherwise>
        </choose>
    </select>

8.3 where标签

我们观察到上面的sql都加了 where 1=1 ,如果不使用where 1=1 那么你的动态sql可能会出错。 我们能不能不加where 1=1呢! 可以 那么我们就可以使用where标签,作用:可以自动为你添加where关键字,并且可以帮你去除第一个and |or

    <select id="findByCondition" resultMap="com.zpb.entity.People">
        select * from t_people
        <where>
            <choose>
                <when test="name!=null and name!=''">
                    and t_name=#{name}
                </when>
                <when test="age!=null and age!=''">
                    and t_age=#{age}
                </when>
                <otherwise>
                    and t_address="深圳"
                </otherwise>
            </choose>
        </where>
    </select>

8.4 set标签

这个配合if标签一起用,一般用在修改语句。如果传递的参数值为null,那么应该不修改该列的值。

<!--set:可以帮我们生成关键字 set 并且可以去除最后一个逗号-->
    <update id="update">
          update account
          <set>
             <if test="name!=null and name!=''">
                name=#{name},
             </if>
             <if test="money!=null">
                money=#{money},
             </if>
             <if test="isdeleted!=null">
                 isdeleted=#{isdeleted},
             </if>
             <if test="created!=null">
                  created=#{created},
             </if>
             <if test="updated!=null">
                  updated=#{updated},
             </if>
          </set>
          where id=#{id}
    </update>

8.5 foreach标签

查询:

<!-- select * from account where id in(2,3,5,7,0)
        如果你使用的为数组array  如果你使用的为集合 那么就用list
        collection:类型
        item:数组中每个元素赋值的变量名
        open: 以谁开始
        close:以谁结束
        separator:分割符
    -->
    <select id="findByIds" resultType="com.zpb.entity.Account">
        select * from account where id in
        <foreach collection="array" item="id" open="(" close=")" separator=",">
             #{id}
        </foreach>
    </select>

删除:

 <delete id="batchDelete">
        <foreach collection="array" item="id" open="delete from account where  id in(" close=")" separator=",">
            #{id}
        </foreach>
    </delete>

添加:

    <insert id="saveBatch">
        insert into account(name,isdeleted) values
        <foreach collection="list" item="acc" separator=",">
            (#{acc.name},#{acc.isdeleted})
        </foreach>
    </insert>

8.6 sql片段

在执行查询语句时不建议大家使用select *, 建议大家把查询的列写出。

//定义sql片段里面包含查询的列名
<sql id="baseColumn">
    id , name , mony , isdeleted , created , updated
</sql>
<select id="findBycondition" resultType="com.zpb.entity.Account">
    select
    <include refid="baseColumn"/>
    from account
    <where>
        <if test="name!=null and name!=''">
            and name=#{name}
        </if>
        <if test="money!=null">
            and money=#{money}
        </if>
        </where>
</select>

8.7 mybatis映射文件处理特殊字符

   <!--
       第一种:转义标签 &nbsp; &lt;  
       第二种: <![CDATA[sql]]>
    -->
    <select id="findByMaxMin" resultType="com.zpb.entity.Account">
           <![CDATA[select * from account where id >#{min} and id <#{max}]]>
    </select>

8.8 mybatis完成模糊查询

   (1)使用concat函数

//select * from 表名 where 列名 like '%a%'
//使用字符串concat函数完成拼接
<select id="findByLike" resultType="com.zpb.entity.Account">
    select * from account where name like concat('%',#{name},'%')
</select>

 (2)使用${},${}实际上是字符串拼接,它不能防止sql注入, 而#{}它是预编译,它可以防止sql注入问题,#{}实际使用的PreparedStatement.

<select id="findByLike" resultType="com.zpb.entity.Account">
    select * from account where name like '%${name}%'
</select>

8.9 联表查询

多对一:根据学生id查询学生信息并携带班级信息

实体类:

如何把连表查询体现在实体类上:创建班级实体类并在学生实体类中用班级类定义属性

package com.zpb.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Clazz {
    private Integer cid;
    private String cname;
}
package com.zpb.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private int id;
    private String name;
    private int age;
    private String sex;
    private Integer classId;

    private Clazz clazz;//学生所属的班级
}

 xml:

<resultMap id="baseMap" type="com.zpb.entity.Student">
            <id column="stu_id" property="id"/>
            <result column="stu_name" property="name"/>
            <result column="stu_age" property="age"/>
            <result column="sex" property="sex"/>
            <result column="class_id" property="classId"/>
            <!--association: 表示一的一方
                 property: 它表示属性名
                 javaType: 该属性名对应的数据类型
            -->
            <association property="clazz" javaType="com.zpb.entity.Clazz">
                <id column="cid" property="cid"/>
                <result column="cname" property="cname"/>
            </association>
</resultMap>
<select id="findStudentById" resultMap="baseMap">
    select * from tb_stu s join tb_class c on s.class_id=c.cid where stu_id=#{id}
</select>

9. 分页插件PageHelper

分页的sql语句:
page: 当前页码
pageSize: 每页显示的条数。

select * from 表名 [where 条件] limit (page-1)*pageSize, pageSize;

如何使用:

(1)引入依赖pagehelper

     <!--引入pageHelper-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.1.11</version>
        </dependency>

(2)在mybatis配置文件中设置pagehelper拦截器,注意标签的位置,要在environment标签前,在configuration标签的先后顺序错误了会报红

    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>

(3)使用pageHelper

//设置分页属性pageNum:显示第几页  PageSize:每页显示的条数
        PageHelper.startPage(3,4);
        List<User> list = userDao.findAll();
        //把查询的结果封装到PageInfo类中。
        PageInfo<User> pageInfo=new PageInfo<User>(list);
        System.out.println("总条数:"+pageInfo.getTotal());
        System.out.println("总页数:"+pageInfo.getPages());
        System.out.println("当前页码对应的数据:"+pageInfo.getList());

10. 逆向工程:mybatis的代码生成器--generator

mybatis官方提供了mapper自动生成工具mybatis-generator-core来针对单表,生成PO类,以及Mapper接口和mapper.xml映射文件。针对单表,可以不需要再手动编写xml配置文件和mapper接口文件了,非常方便。美中不足的是它不支持生成关联查询。一般做关联查询,就自己单独写SQL就好了。

generator网址:MyBatis Generator Core – Introduction to MyBatis Generator/

如何使用:

(1)引入mybatis-generator的依赖jar包。

<dependency>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-core</artifactId>
    <version>1.4.0</version>
</dependency>

(2)generator的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <!--找到你的mysql驱动jar的位置-->
    <classPathEntry location="D:\repMaven\mysql\mysql-connector-java\8.0.20\mysql-connector-java-8.0.20.jar" />

    <context id="DB2Tables" targetRuntime="MyBatis3">
        <!--去除自动生成注释-->
        <commentGenerator>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>

        <!--数据源的配置信息-->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai"
                        userId="root"
                        password="root">
        </jdbcConnection>

        <javaTypeResolver >
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!--java实体类的配置-->
        <javaModelGenerator targetPackage="com.aaa.entity" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator>

        <!--映射文件的配置-->
        <sqlMapGenerator targetPackage="mapper"  targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>

        <!--dao数据访问层的配置-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.aaa.dao"  targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>

        <!--数据库表和实体的映射关系
              schema:数据库名称
              tableName: 表名
              domainObjectName:实体类名

              enableUpdateByExample:是否生成复杂的修改操作
        -->
        <table schema="mybatis" tableName="tb_user" domainObjectName="User"
               enableUpdateByExample="false" enableSelectByExample="false" enableDeleteByExample="false" enableCountByExample="false">

        </table>

        <table schema="mybatis" tableName="tb_stu" domainObjectName="Student"
               enableUpdateByExample="false" enableSelectByExample="false" enableDeleteByExample="false" enableCountByExample="false">

        </table>

    </context>
</generatorConfiguration>

(3)运行你的配置文件

   List<String> warnings = new ArrayList<String>();
   boolean overwrite = true;
   File configFile = new File("generatorConfig.xml");
   ConfigurationParser cp = new ConfigurationParser(warnings);
   Configuration config = cp.parseConfiguration(configFile);
   DefaultShellCallback callback = new DefaultShellCallback(overwrite);
   MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
   myBatisGenerator.generate(null);

11. mybatis的缓存

(1)缓存是存放在内存中的临时数据。使用缓存的好处:减少与数据库的交互次数,提高执行效率。

(2)什么样的数据适合放入缓存?

经常变更的数据、数据的正确与否会对最终结果影响很大的数据不适合放入缓存,不经常改变的数据、数据的正确与否对最终结果影响很小的数据适合放入缓存。

(3)mybatis支持的缓存

a. 一级缓存----基于SqlSession级别的缓存。默认一级缓存是开启的,不能关闭。

b. 二级缓存--基于SqlSessionFactory级别的缓存,它可以做到多个SqlSession共享数据。默认它是关闭。需要手动开启。

(4)二级缓存

a. 开启二级缓存

    <settings>
        <!--开启二级缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>

b. 在映射文件中使用二级缓存

  <!--使用二级缓存 这里面的所有查询都使用了二级缓存-->
  <cache/>

禁止指定方法使用二级缓存,设置useCache为false。

<! --通过id查询用户-->
<select id="findUserById" parameterType="int" resultType="user" useCache="false">
    SELECT * FROM USER WHERE id = #{id}
</select>

c. 实体一定要实现序列化接口

public class Users implements Serializable{
    private Integer id;
    private String username;
    private String password;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值