mybatis原生

目录

mybatis简介

为什么要用mybatis

创建一个原生的mybatis项目

导入依赖

添加mybatis的配置文件

新建表

新建和表对应的实体类

编写SQL映射文件

在mybatis的配置文件中添加SQL映射文件

进行单元测试

mybatis用到的类

mybatis增加Dao的写法改良

进行修改,创建dao类

修改SQL映射文件

修改测试类

注意事项

动态SQL

if标签

编写SQL映射XML文件

编写Dao

编写test

查看结果

where标签

改写SQL映射文件

set标签

编写SQL映射文件

编写Dao接口

编写测试类

运行测试

foreach标签

编写SQL映射文件

编写Dao

编写测试

查看结果

mybatis的延迟加载策略

mybatis的数据源

mybatis的缓存

缓存介绍

一级缓存

二级缓存

缓存查询策略

开启二级缓存

基于注解的mybatis

使用注解的原因

注解的使用


mybatis简介

首先介绍一下什么是mybatis,不谈它的历史,只大概介绍一下,mybatis是一个持久层框架,支持在XML中编写SQL语句,将java方法与SQL语句进行关联

为什么要用mybatis

在之前,我们可以用原生的JDBC去写,去操作数据库,流程大概是这样的

1、定义连接对象
2、预置对象语句
3、获取连接
4、准备SQL
5、执行SQL

这么写的话,我们的代码重复的地方会非常多,因为每次使用都需要这么写,而增删改的不同,无非在于SQL不同,SQL条件的参数不同,而增删改,映射到java,无非就是对象与数据库的增删改

创建一个原生的mybatis项目

导入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>study_mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.1.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

</project>

添加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"><!--引入dtd约束-->
<configuration><!--根标签-->
    <!--主要指定数据库连接-->
    <!-- 这个environment 的名字可以自定义>
    <environments default="mybatisstudy">
        <environment id="mybatisstudy">
            <transactionManager type="JDBC"/><!--配置事务管理器:固定值JDBC即可,mybatis采用JDBC的方式控制事务-->
            <dataSource type="POOLED"><!--配置数据源:固定值POOLED即可。pooled是带有连接池的数据源,是mybatis内置的-->
                <!--以下四个参数就是连接数据库的基本参数:注意,property的name取值不能随便写-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/user"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>

            </dataSource>
        </environment>
    </environments>
   

</configuration>

新建表

CREATE TABLE `usermessage` (
  `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `id` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

新建和表对应的实体类

package own.study.vo;

public class User {

    private String username;
    private String password;
    private int id;

    public String getUsername() {
        return username;
    }

    public void setUsrname(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

编写SQL映射文件

<?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"><!--引入映射文件的约束-->
<!--mybatis中的映射文件必须指定namespace(名称空间),类似java的包一样,可以自定义 -->
<mapper namespace="own.study">
    <!--insert:插入数据
            id:取值在当前xml文档中要保证唯一(就像在同一个包中,类名要唯一是一样的)
            parameterType:指定参数的类型。(要写java实体类的全名称)。此属性可以省略不写
        SQL语句:mybatis中的sql语句中的占位符是使用#{number}表示的。注意,不要用${},存在SQL注入问题,表示获取parameterType指定的对象的属性的取值(即mybatis会调用User的getId()获取值,设置为参数)
    -->
    <insert id="saveUser" parameterType="own.study.vo.User">
        insert into usermessage (username,password,id) values(#{username},#{password},#{id});
    </insert>
</mapper>

在mybatis的配置文件中添加SQL映射文件

<?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"><!--引入dtd约束-->
<configuration><!--根标签-->
    <!--主要指定数据库连接-->
    <environments default="mybatisstudy">
        <environment id="mybatisstudy">
            <transactionManager type="JDBC"/><!--配置事务管理器:固定值JDBC即可,mybatis采用JDBC的方式控制事务-->
            <dataSource type="POOLED"><!--配置数据源:固定值POOLED即可。pooled是带有连接池的数据源,是mybatis内置的-->
                <!--以下四个参数就是连接数据库的基本参数:注意,property的name取值不能随便写-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/user"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>

            </dataSource>
        </environment>
    </environments>

    <mappers>
<!--         这儿是用来映射,哪些文件是有SQL的,代码是通过这些SQL文件的namespace加上SQl文件的自定义id去获取的-->
        <mapper resource="sql.xml"></mapper>
    </mappers>

</configuration>

进行单元测试

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import own.study.vo.User;

import java.io.IOException;
import java.io.InputStream;

public class Test {

    @org.junit.Test
    public void testInsert () throws IOException {
        User user = new User();
        user.setId(1);
        user.setUsrname("root");
        user.setPassword("123456");
        //        1、读取mybatis的主配置文件
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");//读取mybatis的主配置文件,构建输入流
//        2、获取SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//        3、获取SqlSessioinFactory对象
        SqlSessionFactory sessionFactory = builder.build(in);
//        4、获取SqlSession对象
        SqlSession sqlSession = sessionFactory.openSession();
//        5、调用SqlSession的API保存数据
        int num = sqlSession.insert("own.study.saveUser",user);//第一个参数:指定sql语句的位置,就是SQL映射文件中的namespace+id来确定;第二个参数是实体对象
        System.out.println("影响到的行数:"+num);
//        6、提交事务:默认情况下,mybaits的事务不是自动提交的
        sqlSession.commit();
//        7、释放SqlSession占用的资源
        sqlSession.close();
    }

}

mybatis用到的类

Resources:是MyBatis提供的工具类,能够从classpath或其他路径加载mybatis的配置文件

SqlSessionFactoryBuilder:根据xml配置文件中的内容构建SqlSessionFactory对象。一旦创建了 SqlSessionFactory,就不再需要它了,就没用了。

SqlSessionFactory:mybatis中最为重要的一个对象,包含了所有配置内容, 一般一个项目就一个,一旦创建了,就应该在项目正常运行期间,保持存在,不应该毁灭或者创建另外一个,factory是一个重量级的对象,创建非常耗费时间与资源,此factory的最佳使用就是让它的作用域是全局,此factory是线程安全的,可以被n个线程共享

SqlSession:每个线程都有自己的sqlsession,sqlsession线程不安全,所以,建议用的时候去获取,不用就shutdown掉

mybatis增加Dao的写法改良

在上面的写法里,虽然可行,但是我们需要写很多麻烦的东西,能不能搞个类,让它自己去映射呢?

进行修改,创建dao类

package own.study.dao;


import own.study.vo.User;

public interface UserDao {

    public void saveUser(User user);

}

修改SQL映射文件

修改SQL的映射文件,保持namespace和Dao接口相同

<?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"><!--引入映射文件的约束-->
<!--mybatis中的映射文件必须指定namespace(名称空间),类似java的包一样-->
<mapper namespace="own.study.dao.UserDao">
    <!--insert:插入数据
            id:取值在当前xml文档中要保证唯一(在同一个包中,类名要唯一是一样的)
            parameterType:指定参数的类型。(目前要写java实体类的全名称)。此属性可以省略不写
        SQL语句:mybatis中的sql语句中的占位符是使用#{number}表示的。表示获取parameterType指定的
            对象的number属性的取值(即mybatis会调用Account的getNumber()获取账户,设置为参数)
    -->
    <insert id="saveUser" parameterType="own.study.vo.User">
        insert into usermessage (username,password,id) values(#{username},#{password},#{id});
    </insert>
</mapper>

修改测试类

    @org.junit.Test
    public void testDaoInsert () throws IOException {
        User user = new User();
        user.setId(2);
        user.setUsrname("root1");
        user.setPassword("123456");
        //        1、读取mybatis的主配置文件
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");//读取mybatis的主配置文件,构建输入流
//        2、获取SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//        3、获取SqlSessioinFactory对象
        SqlSessionFactory sessionFactory = builder.build(in);
//        4、获取SqlSession对象
        SqlSession sqlSession = sessionFactory.openSession();
//        5、动态代理,产生实现类
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        userDao.saveUser(user);

//        6、提交事务:默认情况下,mybaits的事务不是自动提交的
        sqlSession.commit();
//        7、释放SqlSession占用的资源
        sqlSession.close();
    }

注意事项

SQ映射文件的namespace一定要和Dao接口的路径一毛一样,下面的自定义ID,也一定要和Dao的方法名一毛一样

顺便说一嘴,如果要模糊查询,请不要用

like %${参数名}%

上面这种方式是字符串拼接,存在SQL注入问题,可以用mysql的函数 concat 解决

like concat('%', #{参数}, '%')

动态SQL

如同字面意思,这个SQL是动态的,也就是说,满足什么条件,用什么

mybatis支持动态SQL,提供了判断的标签 if ,格式化的标签 where 、set ,循环的标签 foreach

if标签

编写SQL映射XML文件

<select id="selectByid" parameterType="own.study.vo.User" resultType="own.study.vo.User">
        select * from usermessage where 1 = 1
        <if test="id %2 == 0">
            and id=#{id}
        </if>
    </select>

编写Dao

public User selectByid(User user);

编写test

 @org.junit.Test
    public void testSelectByid () throws IOException {
        User user = new User();
        user.setId(2);
        //        1、读取mybatis的主配置文件
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");//读取mybatis的主配置文件,构建输入流
//        2、获取SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//        3、获取SqlSessioinFactory对象
        SqlSessionFactory sessionFactory = builder.build(in);
//        4、获取SqlSession对象
        SqlSession sqlSession = sessionFactory.openSession();
//        5、动态代理,产生实现类
        UserDao userDao = sqlSession.getMapper(UserDao.class);
//        userDao.saveUser(user);
        User u = userDao.selectByid(user);
        System.out.println(u);

//        6、提交事务:默认情况下,mybaits的事务不是自动提交的
        sqlSession.commit();
//        7、释放SqlSession占用的资源
        sqlSession.close();
    }

查看结果

where标签

where标签用在最外层,作用是:如果where标签的内部,至少有一个if执行了,那就自动加上where关键字,删除第一个if的and关键字,如果where标签内部的所有if都没有被执行,那where标签就啥也不管,啥也不干

改写SQL映射文件

<select id="selectByid" parameterType="own.study.vo.User" resultType="own.study.vo.User">
        select * from usermessage
        <where>
            <if test="id %2 == 0">
                and id=#{id}
            </if>
        </where>
    </select>

查看运行结果

set标签

set标签的作用同where标签类似,如果执行了if,那就加上set关键字,并去掉最后一个逗号,如果没有if执行,那就啥也不干,你后边爱干啥干啥

编写SQL映射文件

<update id="updateUser" parameterType="own.study.vo.User">
        update usermessage
        <set>
            <if test="id != null">
                username = #{username},
            </if>
        </set>
        <where>
            <if test="id != null">
                id=#{id}
            </if>
        </where>
    </update>

编写Dao接口

public void updateUser(User user);

编写测试类

@org.junit.Test
    public void testUpdateUser() throws IOException {
        User user = new User();
        user.setId(2);
        user.setUsrname("admin");
        //        1、读取mybatis的主配置文件
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");//读取mybatis的主配置文件,构建输入流
//        2、获取SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//        3、获取SqlSessioinFactory对象
        SqlSessionFactory sessionFactory = builder.build(in);
//        4、获取SqlSession对象
        SqlSession sqlSession = sessionFactory.openSession();
//        5、动态代理,产生实现类
        UserDao userDao = sqlSession.getMapper(UserDao.class);

        userDao.updateUser(user);

//        6、提交事务:默认情况下,mybaits的事务不是自动提交的
        sqlSession.commit();
//        7、释放SqlSession占用的资源
        sqlSession.close();
    }

运行测试

foreach标签

循环处理,一般用在in条件的使用

编写SQL映射文件

 <select id="selectByList" resultType="own.study.vo.User">
        select * from usermessage where id in
        <foreach collection="idList" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </select>

编写Dao

public List<User> selectByList(@Param("idList") List list);

编写测试

    @org.junit.Test
    public void testSelectByList() throws IOException {
        //        1、读取mybatis的主配置文件
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");//读取mybatis的主配置文件,构建输入流
//        2、获取SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//        3、获取SqlSessioinFactory对象
        SqlSessionFactory sessionFactory = builder.build(in);
//        4、获取SqlSession对象
        SqlSession sqlSession = sessionFactory.openSession();
//        5、动态代理,产生实现类
        UserDao userDao = sqlSession.getMapper(UserDao.class);

        List idList = new ArrayList();
        idList.add(1);
        idList.add(2);
        for (User user : userDao.selectByList(idList)) {
            System.out.println(user);
        }


//        6、提交事务:默认情况下,mybaits的事务不是自动提交的
        sqlSession.commit();
//        7、释放SqlSession占用的资源
        sqlSession.close();
    }

查看结果

mybatis的延迟加载策略

mybatis有一个用法,叫延迟加载策略,延迟加载策略的意思也很简单,那就是等你用到了,我mybatis再去做相关操作

开启mybatis延迟加载策略的方式也很简单,更改mybatis的配置文件

    <settings>
        <!--打开全局延迟加载开关。默认是false。注意:参数名不能随便写-->
        <setting name="lazyLoadingEnabled" value="true"/>
    </settings>

mybatis的数据源

mybatis内置了三种数据源

POOLED:带有连接池的数据源。运行效率比较高

UNPOOLED:不带连接池的数据源

JNDI:javaEE的一种技术

mybatis的缓存

缓存介绍

对于变化不频繁的数据,如果我们每次使用都去查询数据库,那么会造成网络带宽的消耗以及数据库资源的占用,我们可以放在缓存里,内存里

一级缓存

一级缓存是sqlsession级别的缓存,只要这个sqlsession不关闭,这个缓存就有效

如果在这个sqlsession有效期间,执行了增、删、改的操作,为了保证数据的有效性,缓存也不会再存在

二级缓存

二级缓存是序列化的缓存,比如我们查询出来数据,将数据放到了一个对象里,二级缓存就是这个对象序列化后的结果,所以,要使用二级缓存,除了开启之外,还需要对象实体类去进行序列化,也就是实现Serializable接口

缓存查询策略

优先查询二级缓存,没有二级缓存,查询一级缓存,没有一级缓存,就查询数据库

开启二级缓存

修改mybatis的配置文件

添加

<setting name="cacheEnabled" value="true"/>

基于注解的mybatis

使用注解的原因

为什么要使用注解,这个原因其实很简单,注解的写法简单,开发效率高

注解的使用

在之前,我们要把SQL语句写到XML文件里,还要进行类型映射,很麻烦,但是使用注解不用,我们可以用@Insert @Update @Delete @Select 这四个注解,直接在Dao上进行SQL的编写及参数的传递

比如:

@Insert("insert into user values(null,#{username})")
    void saveUser(User user);

    @Update("update user set username=#{username} where id=#{id}")
    void updateUser(User user);

    @Delete("delete from user where id=#{id}")
    void deleteUser(Integer id);

    @Select("select * from user where id=#{id}")
    User findUserByUid(Integer id);

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值