企业级应用开发SSM(Mybatis)

目录

一,框架的概念,以及为什么使用框架?

二,MyBatis框架 (半自动化ORM框架)

 2.1什么是ORM?(Object Relational Mapper 对象关系映射)

2.2MyBatis概念及优点特性

2.2.1MyBatis简介

2.2.2MyBatis特性

2.3MyBatis的环境搭建及核心API建立(不容易)

第一步:下载MyBatis jar包并导入工程

​编辑

 第二步:编写MyBatis核心配置文件

 第三步:测试是否连接到数据库(以下步骤是MyBatis的核心,掌握)

 第四步.创建实体类

第五步.便写DAO层-SQL映射文件(mapper.xml)

 抽取工具类:

2.4理解核心类的作用域与生命周期

SqlSessionFactoryBuilder

SqlSessionFactory (**最重要**)

SqlSession

 2.5  SELECT(查询)

        2.5.1 基本查询

        2.5.2 模糊查询(模糊查询比较推荐第二种,第一种可能会出现SQL注入问题。 )

        2.5.3   多个参数查询     

        2.5.4 对象查询 VS map查询

2.6 增删改



一,框架的概念,以及为什么使用框架?

1.框架的进程

SSH(最早)Struts(JSP MVC) 能够简化JSP开发 Spring  Hibernate (全自动化ORM框架 , 并发量小,不用太过于关注SQL,自动生成sql语句)

|

SSH2 :Struts2

|

SSM :Spring SpringMVC Mybatis(半自动化ORM框架,需要用户自己写sql语句)

2.为什么使用框架:

       框架(Framework)是一个框子——指其约束性,也是一个架子——指其支撑性。是一个基本概念上的结构,用于去解决或者处理复杂的问题。框架这个广泛的定义使用的十分流行,尤其在软件概念。
        框架(Framework)是构成一类特定软件可复用设计的一组相互协作的类。框架规定了你的用的体系结构。它定义了整体结构,类和对象的分割,各部分的主要责任,类和对象怎么协作,以及控制流程。框架预定义了这些设计参数,以便于应用设计者或实现者能集中精力于应用本身的特定细节。如果将开发完成的软件比作是一套已经装修完毕的新房,那框架就好比是一套已经修建好的毛坯房。用户直接购买毛坯房,建筑质量和户型合理有保证,还省去了自己建造房屋的时间,一举多得。在开发过程是使用框架,同样可以保证减少开发时间、降低开 发难度,并且还保证设计质量。好比和世界上最优秀的软件工程师是一个项目的,并且他们完成的还是基础、全局的工作。

3.框架的概念:

  • 框架技术:

                是一个应用程序的半成品

                提供可从用的公共结构

                按一定规则组织一组组件

4.使用框架的优势分析

  1. 重用代码大大增加,软件生产效率和质量也得到了提高;
  2. 代码结构的规范化,降低程序员之间沟通以及日后维护的成本;
  3. 知识的积累,可以让那些经验丰富的人员去设计框架和领域构件,而不必限于低层编程;
  4. 软件设计人员要专注于对领域的了解,使需求分析更充分;
  5. 允许采用快速原型技术;有利于在一个项目内多人协同工作;
  6. 大粒度的重用使得平均开发费用降低,开发速度加快,开发人员减少,维护费用降低,而参数化框架使得适应性、灵活性增强。

二,MyBatis框架 (半自动化ORM框架)

 2.1什么是ORM?(Object Relational Mapper 对象关系映射)

了解ORM之前,先了解一下什么是持久化!

持久化:是程序数据在瞬时状态和持久状态间的转化的过程。

        比如我们程序在新建一个对象后,这个对象存储在内存当中,当我们电脑关机后,这个对象数据便不会存在,我们称之为瞬时状态。当我们将这个对象存储到U盘,本地文件下,我们称之为持久状态,永久的存储在某种介质当中。这个过程称之为持久化

ORM:比如下图内存中有个对象,通过JDBC将对象存储在数据库当中,这个过程称之为持久化。但是数据库中的表字段必须与内存中对象的字段逐个对应,否则存不进来。也就是对象里的字段和表里的字段一一映射,对象与表一一映射。这个状态称之为ORM

 ORM:

  •         编写程序时,以面向对象方式处理数据。
  •         保存数据时,却以关系型数据库的方式存储。

ORM解决方案包含下面四个部分

  1.         在持久化对象上执行基本的增,删,改,查操作。
  2.         对持久化对象提供一种查询语言或者API
  3.         对象关系映射工具
  4.         提供与事务对象交互,执行检查,延迟加载以及其他优化功能

2.2MyBatis概念及优点特性

2.2.1MyBatis简介

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL 、存储过程以及高级映射。 MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。 MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java POJOs(Plain Ordinary JavaObject, 普通的 Java 对象 ) 映射成数据库中的记录。简单的说: MyBatis 是一个半自动 ORM 框架,其本质是对 JDBC 的封装。使用 MyBatis 重点需要程序员编写 SQL 命令,不需要写一行 JDBC 代码。 MyBatis 具有封装少、映射多样化、支持存储过程、可以进行 SQL 语句优化等特点,符合互联网高并发、大 数据、高性能、高响应的要求,成为了国内 Java 互联网中首选的持久框架。

2.2.2MyBatis特性

2.3MyBatis的环境搭建及核心API建立(不容易)

MyBatis中文网https://mybatis.net.cn/

第一步:下载MyBatis jar包并导入工程

 第二步:编写MyBatis核心配置文件

 第三步:测试是否连接到数据库(以下步骤是MyBatis的核心,掌握)

  • 读取核心配置文件mybatis-config.xml
  • 创建SqlSessionFactory对象,读取配置文件
  • 创建SqlSession对象
  • 调用mapper文件进行数据操作

 第四步.创建实体类

@Data / @get / @set / @toString

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

编写domain类

第五步.便写DAO层-SQL映射文件(mapper.xml)

映射文件

 加载映射文件

 如果不添加映射文件,将会报如下错误

### Error querying database. Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.csi.smbms.domain.User.findByCount

### Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.csi.smbms.domain.User.findByCount

 抽取工具类:

package com.csi.smbms.utils;

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 java.io.IOException;
import java.io.InputStream;

public class MyBatisUtils {

    private  static SqlSessionFactory factory ;

    //本地线程,归属于当前用户,为了避免线程共享问题,担心出现数据污染
    private static  ThreadLocal<SqlSession> tl = new ThreadLocal<>() ;

    static {

        InputStream is = null;
        try {
            is = Resources.getResourceAsStream("mybatis-config.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }

        factory = new SqlSessionFactoryBuilder().build(is) ;

    }
    /**
     * 创建SqlSession对象
     */
    public static SqlSession getSqlSession(){

        SqlSession sqlSession = tl.get() ;

        if (sqlSession == null ){

            System.out.println("创建了SqlSession对象");

            sqlSession = factory.openSession();

            tl.set(sqlSession) ;

        }

        return sqlSession ;

    }

    /**
     * 资源关闭
     */

    public static  void close(){

        SqlSession sqlSession = tl.get();

        if (sqlSession!=null){

            System.out.println("关闭了SqlSession对象");

            sqlSession.close();

            tl.set(null);

        }

    }
}

2.4理解核心类的作用域与生命周期

SqlSessionFactoryBuilder

  1. 用过即丢,其生命周期只存在于方法体内
  2. 可重用其来创建多个 SqlSessionFactory 实例
  3. 负责构建SqlSessionFactory,并提供多个build方法的重载

SqlSessionFactory (**最重要**)

  • SqlSessionFactory是每个MyBatis应用的核心
  • 作用:创建SqlSession实例
  1. 在创建SqlSession的同时,能够将事务设置为手动的或者是自动的
  2. autoCommit:
  3. true|false
  • 作用域: Application
  • 生命周期与应用的生命周期相同
  • 单例

                 存在于整个应用运行时,并且同时只存在一个对象实例,所以在抽象工具类的时候,用到了ThreadLocal.

SqlSession

  • 包含了执行SQL所需的所有方法
  • 对应一次数据库会话,会话结束必须关闭
  • 线程级别,不能共享

  

 2.5  SELECT(查询)

        2.5.1 基本查询

  •         List: SelectList 查询所有(namespace+id,参数内容)
  •         SelectOne:查询一个,SelectOne(namespace+id,参数内容) ;

        2.5.2 模糊查询(模糊查询比较推荐第二种,第一种可能会出现SQL注入问题。 )

          解决方案

  • 使用字符串拼接形式 '%${变量名称}%'
  • 使用concat方式 concat('%',#{变量名称},'%')  (推荐

 $#之间的区别(**) 面试题

#{} 是预编译处理, ${} 是字符串替换。
Mybatis 在处理 #{} 时,会将 sql 中的 #{} 替换为 ? 号,调用 PreparedStatement set 方法来赋值;
Mybatis 在处理 ${} 时,就是把 ${} 替换成变量的值。
使用 #{} 可以有效的防止 SQL 注入,提高系统安全性。
<select id = "findByLike" resultType = "userinfo" parameterType = "string" >
        SELECT * FROM smbms_user WHERE userName LIKE '%${str}%'
</select>
<!-- 推荐的形式 -->
<select id = "findByLike" resultType = "User" parameterType = "String" >
        SELECT * FROM smbms_user WHERE userName LIKE CONCAT('%',#{userName},'%')
</select>

        2.5.3   多个参数查询     

        解决方案

  • 使用封装对象的形式传输内容(参数是同一个对象里的,将参数封装一个对象即可)
  • 通过map来进行封装传值(不同对象)

 User findByMap(Map<String,Object> map) ;

映射文件中的SQL语句和对象查一致

 

2.5.4 对象查询 VS map查询

        当查询的条件都是来自于同一张表,在前端,通过类似于Spring MVC的框架,能够自动实现数据的封装,此时利用对象封装参数查询就比较方便。
        当查询的条件都是来自于不同的表内容,那么此时,要么新建立一个临时对象用于作为查询的参数,最好的形式就是map 来实现该功能

2.6 增删改

        CUD:都需要使用commit提交,否则就会发生回滚情况,除非是,在初始化SqlSession对象时修改事物的提交方式。

//例子
    /**
     * 删除
     */
    @Test
    public void testDeleteById(){

        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        try {
            int i = userMapper.deleteById(16L);

            System.out.println(i);

            sqlSession.commit();
        } catch (Exception e) {
            sqlSession.rollback();
            e.printStackTrace();
        } finally {
            MyBatisUtils.close();
        }

    }

2.7 MyBatis 的分页查询

        使用RowBounds 进行分页,非常方便,不需要在 SQL 语句中写 limit ,即可完成分页功能。但是由于它是在 SQL 查询出所有结果的基础上截取数据的,所以在数据量大的 SQL
并不适用,它更适合在返回数据结果较少的查询中使用。性能极大降低,首先将所有的数据都查询出来,在进行分页,性能不太高,一个假分页。

2.8 主键值回填 。

        在数据库中插入数据时,有时我们是需要获取新数据的主键值。在Mybatis 中支持主键值回填,可以让我们更够更方便的获取新添加数据的主键值。
<!-- 添加用户获取主键值 [ 自增 ]-->
<insert id = "insertUsersGetKey" useGeneratedKeys = "true" keyProperty = "userid" >
        insert into users values(default,#{username},#{usersex})
</insert>
<settings>
<setting name = "useGeneratedKeys" value = "true" />
</settings>
<insertid = "insertUsersGetKey" keyProperty = "userid" >
insert into users values(default,#{username},#{usersex})
</insert>
void insertUsersGetKey ( Usersusers );
usersMapper . insertUsersGetKey ( users );
sqlSession . commit ();
System . out . println ( users . getUserid ());

 2.9 自动映射级别(autoMappingBehavior)

        指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示关闭自动映射; PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 FULL 会自动映射任何复杂的结果集(无论是否嵌套)。
<settings>
        <setting name="autoMappingBehavior" value="FULL"/>
</settings>

 

<resultMap id="userinfoList" type="userinfo">
        <!--代表主键
                property: 代表类中的字段
                column: 代表数据库查询回来字段
        -->
        <id property="id" column="id" />
        <result property="userCode" column="userCode" />
        <result property="userName" column="userName" />
        <result property="gender" column="gender" />
        <result property="phone" column="phone" />
        <result property="address" column="address" />
        <result property="roleName" column="roleName" />
        
  <!--多对一,以及一对一-->     
<association property="product" javaType="Product" select="com.csi.easybuy.mapper.ProductMapper.selectById2" column="pid" /
<!--一对多-->      
<collection property="product" ofType="Product" select="com.csi.easybuy.mapper.ProductMapper.selectById2" column="pid" />
</resultMap>
<select id="list" resultMap="userinfoList">
        SELECT
        su.*,roleName FROM
        smbms_user su,smbms_role sr
        WHERE
        su.userRole = sr.id
</select>

 三:动态SQL

3.1 if

SELECT * FROM dept where 1 = 1
< if test = "dname != null" >
dname = # { dname },
</ if >
< if test = "loc != null" >
and loc = # { loc }
</ if >

3.2  trim(whereset)

where 节点会自动为查询语句判断是否需要增加 where 子句,通过判断结果,自动生成 ” , 同时会自动处理 and 连接。多条件不能省去 and 关键字。
SELECT * FROM dept
< where >
        < if test = "dname != null" >
                dname = # { dname }
        </ if >
        < if test = "loc != null" >
                and loc = # { loc }
        </ if >
</ where >
update dept
< set >
        < if test = "dname != null" >
                dname = # { dname },
        </ if >
        < if test = "loc != null" >
                loc = # { loc },
        </ if >
</ set >
< where >
        deptno = # { deptNO }
</ where
update dept
< trim prefix = "set" suffixOverrides = "," >
        < if test = "dname != null" >
        dname = # { dname },
        </ if >
        < if test = "loc != null" >
        loc = # { loc },
        </ if >
</ trim >
< where >
        deptno = # { deptNO }
</ where >

 3.3 choose (when, otherwise)

otherwise 表示当没有对应选项时的处理方式,可选值。

3.4 foreach

collection: 集合
item: 集合中的选项值
open :开合的标识
close :关闭的表示
separator :分隔符
DELETE FROM emp
< where >
        empno in
        < foreach collection = "list" item = "item" open = "(" close = ")" separator = "," >
                # { item }
        </ foreach >
</ where >

 

 四:Mybatis缓存(了解)

        缓存是一般的ORM 框架都会提供的功能,目的就是提升查询的效率和减少数据库的压力,缓存的重要性是不言而喻的。 Mybatis 会将相同查询条件的 SQL 语句的查询结果存储
在内存或者某种缓存介质当中,当下次遇到相同的查询 SQL 时候不在执行该 SQL ,而是直接从缓存中获取结果,减少服务器的压力,尤其是在查询越多、缓存命中率越高的情况
下,使用缓存对性能的提高更明显。
        MyBatis缓存方式分为一级缓存和二级缓存,同时也可配置关于缓存设置。一级缓存是将结果缓存在 SqlSession 对象中,二级缓存是存储在 SqlSessionFactory 对象中。默认情
况下, MyBatis 开启一级缓存,没有开启二级缓存。当数据量大的时候可以借助一些第三方缓存技术来协助保存 Mybatis 的二级缓存数据。

4.1 一级缓存

        一级缓存也叫本地缓存,MyBatis 的一级缓存是在会话( SqlSession )层面进行缓存的。 MyBatis 的一级缓存是默认开启的,不需要任何的配置。     
     一级缓存的生命周期
        MyBatis在开启一个数据库会话时,会创建一个新的 SqlSession 对象, SqlSession 对象中会有一个新的 Executor 对象。 Executor 对象中持有一个新的 PerpetualCache 对象;当
会话结束时, SqlSession 对象及其内部的 Executor 对象还有 PerpetualCache 对象也一并释放掉。

 

如果 SqlSession 调用了 close() 方法,会释放掉一级缓存 PerpetualCache 对象,一级缓存将不可用。
如果 SqlSession 调用了 clearCache() ,会清空 PerpetualCache 对象中的数据,但是该对象仍可使用。
SqlSession 中执行了任何一个 update 操作 (update() delete() insert()) ,都会清空 PerpetualCache 对象的数据,但是该对象可以继续使用。

4.2  二级缓存

        MyBatis的二级缓存是 Application 级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能。二级缓存是 SqlSessionFactory 上的缓存,可以是由一个 SqlSessionFactory 创建的不同的 SqlSession 之间共享缓存数据。默认并不开启。

五: PageHelper分页插件(真分页)

PageHelper 是一款非常好用的开源免费的 Mybatis 第三方分页插件。它基于 plugin 的方式与 Mybatis 整合。通过 PageHelper 所提供的 API 完成对数据的分页查询。
  • 添加依赖:
pagehelper-5.1.11.jar
jsqlparser-3.1.jar
  • 配置插件
<plugins>
<plugin interceptor = "com.github.pagehelper.PageInterceptor" >
<!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL 六种数据库 -->
<property name = "helperDialect" value = "mysql" />
</plugin>
</plugins>
  • 分页查询API
PageHelper.startPage(intpageNum,intpageSize); 给定分页参数,该方法需要在执行查询之前调用
pageNum :起始的页数,从 1 开始计算。
pageSize :每页显示的条数。
PageInfo 对象,存放分页结果对象
pageInfo.getList() 获取分页查询结果。
pageInfo.getTotal() 获取查询总条数。
pageInfo.getPages() 获取总页数。
pageInfo.getPageNum() 获取当前页。
pageInfo.getSize() 获取每页显示的条数
  • pageHelper使用方式:
PageHelper . startPage ( 3 , 2 );
List < Users > list = usersMapper . selectByExample ( usersExample );

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

if else

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值