Mybatis主要知识点回顾

Mybatis入门

定义,要背诵的

  • Mybatis是一款优秀的持久层框架
  • 它支持定制化SQL、存储过程以及高级映射。
  • Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。
  • 传统的jdbc操作 , 有很多重复代码块 .比如 : 数据取出时的封装 , 数据库的建立连接等等… , 通过框架可以减少重复代码,提高开发效率 .
  • MyBatis 是一个半自动化的ORM框架 (Object Relationship Mapping) —>对象关系映射
  • Mybatis可以使用简单的XML或注解来配置和映射原生类型、接口和Java的POJO(Plain Old Java Object,普通老式Java对象)为数据库中的记录。
  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
  • 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
  • 提供xml标签,支持编写动态sql。

关键字:持久化框架,避免了JDBC代码和手动设置参数以及获取结果集,半自动化的ORM框架

xml或者注解配置和映射原生类型、接口、java的pojo为数据库中的记录

sql写在xml里,提供DAO层,业务逻辑和数据访问逻辑分离

约定大于配置:

  1. 开发人员仅需规定应用中不符合约定的部分
  2. 在没有规定配置的地方,采用默认配置,以力求最简配置为核心思想

https://blog.csdn.net/xiao_jin_ling/article/details/121062608

持久化是将程序数据在持久状态和瞬时状态间转换的机制

参考例子:

搭建一个简单的mybatis程序:https://blog.csdn.net/s001125/article/details/114676985

比较详细的例子:https://zhuanlan.zhihu.com/p/351830443

程序示例

思路流程:搭建环境—>导入Mybatis—->编写代码—->测试

搭建实验数据库

引入mybatis相关jar包

(数据库驱动mysql、mybatis、junit(单元测试))

配置mybatis配置文件

三种配置文件:jdbc的配置文件、mybatis核心配置文件、mybatis映射文件

jdbc.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql:///school?characterEncoding=utf-8
username=lisir
password=123456

url:数据库连接字符串(jdbc:mysql://[服务器ip地址]/数据库名 ?编码方式)

mybatis.xml

注意:mybatis全局配置需按照配置文档的顺序进行配置,也就是按照properties(属性)、settings(设置)、typeAliases(类型别名)、environments(环境配置)、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="jdbc.properties"/>
    
    <!--开启驼峰映射,setting可以不写!!-->
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <!--起别名-->
    <typeAliases>
        <typeAlias type="com.mybatis.pojo.User" alias="user"/>
    </typeAliases>


    <!--MyBatis可以配置成适应多种环境,尽管可以配置多个环境,每个SqlSessionFactory实例只能选择其一。实际使用场景下一般使用spring来管理数据源,来做到环境的分离。 -->
    <environments default="development">
        <!--environment表示数据源配置标签, id是配置的唯一标识-->
        <environment id="development">            
            <!--事务管理前标签 type表示事务交给jdbc管理-->
            <transactionManager type="JDBC"/>
            <!--datasource表示数据源的意思,type="pooled"表示使用mybatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
        
    </environments>
    
    <!--将xml文件映射成pojo类-->
    <mappers>
       <!--mapper加载映射文件的标签, resource属性表示加载映射文件资源路径-->
       <!--<mapper resource="UMapper.xml"/>-->
       <mapper resource="com/mybatis/dao/UserMapper.xml"/>
    </mappers>


</configuration>

1、加载映射文件,关联UserMapper.java接口
2、加载接口,关联映射文件
条件:(1)接口名和映射文件名保持一致 (2)路径保持一致

mybatis映射文件

也就是mapper文件,见后续内容,主要是写增删改查等等等。

相关链接:

mybatis-config.xml MyBatis的全局配置文件

https://blog.csdn.net/weixin_43880289/article/details/109394301

讲了三个配置文件:

https://blog.csdn.net/weixin_40498531/article/details/89253662

mybatis工具类-MybatisUtils

参考的一个util,与下文列举的有些许不同:

1)在静态初始化块中加载mybatis配置文件一次

2)使用ThreadLocal对象让当前线程与SqlSession对象绑定在一起

3)获取当前线程中的SqlSession对象,如果没有的话,从SqlSessionFactory对象中获取SqlSession对象

4)获取当前线程中的SqlSession对象,再将其关闭,释放其占用的资源

总结:静态初始化加载配置文件,获取sqlSession,提交释放资源,回滚释放资源

基本功能:

//加载mybatis配置文件

//创建sqlsessionfactory对象

//创建sqlsession连接对象

//创建关闭sqlsession连接对象

参考的链接:

https://blog.csdn.net/lierenbiji21/article/details/108217738

https://www.cnblogs.com/loaderman/p/10064317.html

//sqlSessionFactory -->SqlSession
public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            //使用Mybatis第一步: 获取sqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
    //sqlSession 完全包含了面向数据库执行SQL命令所需的所有方法
    public static SqlSession getSqlseesion() {
        // SqlSession sqlSession = sqlSessionFactory.openSession();
        return sqlSessionFactory.openSession();
    }
}

创建一个实体类

user class,包含参数 id、name、pwd。

编写mapper接口

import java.util.List;
public interface UserMapper {
   //查询全部用户
   List<User> getUserList();
}

编写mapper.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的接口-->
<mapper namespace="com.mybatis.dao.UserMapper">
  <select id="getUserList" resultType="com.mybatis.pojo.User">
        select * from mybatis.user
    </select>
</mapper>

编写测试类

 @Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlseesion();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = userMapper.getUserList();
        for(User user : userList){
            System.out.println(user);
        }
        sqlSession.close();
    }

**注意:**可能遇见资源无法导入的现象,(maven由于他的约定大于配置,可能遇到写的配置文件无法导出或生效的题),解决方案:

<!--在build中配置resource,来防止我们资源到处失败的问题-->
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <!--将我们的资源位置加进去,用得是相对位置-->
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

**namespace :**mybatis命名解析,全限定名,短限定名,如果有两个短名称,则必须使用全限定名。

<mapper namespace="com.mybatis.dao.UserMapper">
  <select id="getUserList" resultType="com.mybatis.pojo.User">
        select * from mybatis.user
    </select>
</mapper>

增删改查

namespace中的包名要和Dao/Mapper接口的包名一致!

注意:防止sql注入

参考链接:https://www.cnblogs.com/mmzs/p/8398405.html

1、#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。

2、$将传入的数据直接显示生成在sql中。

mybatis通过预编译的方法,防止sql注入,在SQL执行前,会先将上面的SQL发送给数据库进行编译;执行时,直接使用编译好的SQL,替换占位符“?”就可以了。因为SQL注入只能对编译过程起作用,所以这样的方式就很好地避免了SQL注入的问题。

#{}是经过预编译的,是安全的;${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入

使用${},必须手动处理过滤一下输入的内容,判断输入的参数长度是否正常,更精确的过滤则可以查询一下输入参数是否在预期的参数集合中。

公共部分

xml里的参数类型:

  • id : 就是对应的namespace中的方法名;
  • parameterType : 参数类型!
  • resultType:Sql语句执行的返回值!

编写接口

写一个mapper,mapper声明一些函数,getXXXX,addXXXX,updateXXX,deleteXXX。

select、insert、update、delete

测试函数

       @Test
       public void getUserById() {
           //获得sqlsession
           SqlSession sqlSession = MybatisUtils.getSqlSession();
           //映射mapper
           UserMapper mapper = sqlSession.getMapper(UserMapper.class);
           //使用mapper的查询函数
           User user = mapper.getUserById(1);
           System.out.println(user);
           //关闭sql
           sqlSession.close();
       }

增加,不需要返回值,只需要传入值。

<!--对象中的属性,可以直接取出来-->
    <insert id="addUser" parameterType="com.kuang.pojo.User">
        insert into mybatis.user (id, name, pwd) values (#{id},#{name},#{pwd});
    </insert>

删除带有条件

    <delete id="deleteUser" parameterType="int">
        delete from mybatis.user where id = #{id};
    </delete>

    <update id="updateUser" parameterType="com.kuang.pojo.User">
        update mybatis.user set name=#{name},pwd=#{pwd}  where id = #{id} ;
    </update>

   <select id="getUserById" parameterType="int" resultType="com.kuang.pojo.User">
           select * from mybatis.user where id = #{id}
   </select>

**注意:**增删改需要提交事务,事务分为手动提交和自动提交。

    sqlSession.commit();

在这里插入图片描述

万能map

参考:https://blog.csdn.net/chengqiuming/article/details/106790938

如果我们的实体类或者数据库中的表,字段或参数过多,可以考虑使用Map。

Map传递参数,直接在sql中取出key即可,根据key取出元素。

int addUser2(Map<String,Object> map);

xml中:

    <!--对象中的属性,可以直接取出来    传递map的key-->
    <insert id="addUser" parameterType="map">
        insert into mybatis.user (id, pwd) values (#{userid},#{passWord});
    </insert>

使用

    @Test
    public void addUser2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("userid",5);
        map.put("passWord","2222333");
        mapper.addUser2(map);
        sqlSession.close();
    }

多个参数用Map,或者注解!

模糊查询

1、java代码执行的时候,传递通配符%

List<User> userList = userDao.getUserLike("胡%");

2、在sql拼接中使用通配符

select * from mybatis.user where name like "%"#{value}"%"

作用域scope和生命周期

在这里插入图片描述

不同作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。

//sqlSessionFactory -->SqlSession
public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            //使用Mybatis第一步: 获取sqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
    //sqlSession 完全包含了面向数据库执行SQL命令所需的所有方法
    public static SqlSession getSqlseesion() {
        // SqlSession sqlSession = sqlSessionFactory.openSession();
        return sqlSessionFactory.openSession();
    }
}

SqlSessionFactoryBuilder

可以被实例化、使用和丢弃,一旦创建SqlSessionFactory,就不再需要它。因此它的最佳作用域是方法作用域(局部方法变量)。可以重用SqlSessionFactoryBuilder创建多个SqlSessionFactory实例,但最好不要一直保留它,以保证所有的xml解析资源可以被释放给更重要的事情。

  • 一旦创建 SqlSessionFactory,就不再需要它了
  • 局部变量
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSessionFactory

  • 可以想象为:数据库连接池
  • SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或者重新创建另一个实例
  • 因此 SqlSessionFactory 的最佳作用域是应用作用域
  • 最简单的就是使用单例模式或者静态单例模式

所以经常被声明为静态变量,只被创建一次。

private static SqlSessionFactory sqlSessionFactory;

SqlSession

  • 连接到连接池的一个请求!
  • SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域
  • 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。
  • 用完之后需要赶紧关闭,否则资源被占用!
try (SqlSession session = sqlSessionFactory.openSession()) {
  // 你的应用逻辑代码
}

如下所示,用完就close(),一般可以卸载finally块中。

    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    //你的应用逻辑代码
    sqlSession.close();

在这里插入图片描述

映射器实例

  • 映射器接口的实例是从 SqlSession 中获得的。
  • 映射器实例应该在调用它们的方法中被获取,使用完毕之后即可丢弃。 映射器实例并不需要被显式地关闭。
  • 最好将映射器放在方法作用域内
try (SqlSession session = sqlSessionFactory.openSession()) {
  BlogMapper mapper = session.getMapper(BlogMapper.class);
  // 你的应用逻辑代码
}

或者如上面的例子

  public void getUserById() {
       SqlSession sqlSession = MybatisUtils.getSqlSession();
       //映射mapper
       UserMapper mapper = sqlSession.getMapper(UserMapper.class);
      //。。。。。相关逻辑
       //关闭sql
       sqlSession.close();
   }

mybatis的流程

img

解决属性名和字段名不一样

数据库中字段:id、name、pwd

实体类中字段:id、name、password

1、sql语句改一下,起别名

<select id="getUserById" resultType="com.mybatis.pojo.User">
   select id,name,pwd as password from mybatis.user where id =#{id}
</select>

2、对结果集进行一下映射 resultmap

<!--结果集映射-->
   <resultMap id="UserMap" type="User">
    <!--column数据库中的字段,property实体类中的属性-->
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="pwd" property="password"/>
    </resultMap>
    
  <select id="getUserByid" resultMap="UserMap">
     select * from mybatis.user where id =#{id}
  <select>

分页

为什么要使用分页,减少数据的处理量。

使用limit分页

startIndex:从第几行开始 pageSize:取几条数据

select * from user limit startIndex, pageSize
select * from user limit 0,2

使用mybatis实现分页

1、接口

List<User> getUserByLimit(Map<String,Integer> map);

2、mapper.xml

<select id="getUserByLimit" parameterType="map" resultMap="UserMap">
    select * from mybatis.user limit #{startIndex},#{pageSize};
</select>

3、测试

@Test
public void getUserByLimit(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    HashMap<String, Integer> map = new HashMap<String, Integer>();
    map.put("startIndex",1);   //重点!!
    map.put("pageSize",2);
    List<User> userByLimit = mapper.getUserByLimit(map);
    for(User user:userByLimit){
        System.out.println(user);
    }
    sqlSession.close();
}

RowBounds分页

1、接口

List<User> getUserByRowBounds();

2、mapper.xml

<select id="getUserByRowBounds" resultMap="UserMap">
    select * from muser
</select>

3、测试

@Test
public void getUserByRowsBounds(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    RowBounds rowBounds = new RowBounds(1, 2);   //设置rowBounds对象,起始条,查询条数
    List<User> userList = sqlSession.selectList("com.susu.dao.UserMapper.getUserByRowBounds",null,rowBounds);
    for (User user : userList) {
        System.out.println(user);
    }
    sqlSession.close();
}

插件实现

pageHelper

具体教程:

https://pagehelper.github.io/docs/howtouse/

详细讲述分页:

具体参考环境:springboot、mybatis、pagehelper

使用步骤:

1、pom.xml引入依赖库

2、application.yml或者application.properties中添加分页配置

3、进行使用,在controller层或者service层使用

在这里插入图片描述

在这里插入图片描述

https://blog.csdn.net/Cs_hnu_scw/article/details/80718467

使用注解开发

面向接口编程,主要考虑对象之间的协作关系的设计。

面向对象:以对象为单位,考虑它的属性以及方法。

面向过程:以一个具体的流程(事务过程)为单位,考虑它的实现。

1、注解在接口上实现

这个文件是UserMapper.java

@Select("select * from muser")
List<User> getUsers();

2、需要在核心配置文件中绑定接口

<mappers>
    <mapper class="com.mybatis.dao.UserMapper"/>
</mappers>

3、测试

和上面的代码,步骤一样,getsqlsession,mapper.class,调用getUsers方法。

注解CRUD

1、mybatis util工具类创建的时候实现事务自动提交

public static SqlSession getSqlSession(){
    return sqlSessionFactory.openSession(true);
}

2、编写接口,增加注解

注解多个参数,用@Param(推荐),也可以使用map

https://blog.csdn.net/weixin_37139197/article/details/82975594

public interface UserMapper {
    @Select("select * from user")
    List<User> getUsers();
   
    @Select("select * from user where id = #{id}")
    User getUserById(@Param("id") int id);
    
    //方法存在多个参数,所有的参数前面必须加上@param("xxx")
    @Select("select * from user where id = #{id} and name = #{name}")
    User getUserById(@Param("id") int id,@Param("name") string name);
    
    //增加
    @Insert("insert into user(id,name,pwd) values(#{id},#{name},#{paswword})")
    int addUser(User user);
    //更新
    @Update("update user set name=#{name},pwd=#{password} where id=#{id}")
    int updateUser(User user);
    //改
    @Delete("delete from user where id=#{id}")
    int deleteUser(@Param("id") int id);
}

配置接口,在mybatis的核心配置文件中写上。

<mappers>
    <mapper class="com.mybatis.dao.UserMapper"/>
</mappers>

注意:@param注解

  • 基本类型的参数或者string类型,需要加上
  • 引用类型不需要加,(传递一个对象啥的)
  • 如果只有一个基本类型的话,可以忽略,但是建议加上!
  • 在sql中引用的就是这里的@param() 中的属性名!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值