SSM | Mybatis2(缺缓存部分)

本文详细介绍了Mybatis的日志配置,包括STDOUT_LOGGING和LOG4J的使用。接着讨论了分页查询的多种方式,如Limit分页和RowBounds分页。然后讲解了使用注解进行开发,包括面向接口编程、注解开发的步骤和CRUD示例。多表查询部分涵盖了多对一和一对多查询的实现。此外,还阐述了动态SQL的概念,如if、choose、trim和foreach语句。最后,文章提到了Mybatis的缓存机制和Lombok插件的使用。
摘要由CSDN通过智能技术生成

1.日志

1.1 日志工厂

如果一个数据库操作,出现了异常,我们需要排错。日志就是最好的助手。

曾经:sout 、debug

现在:日志工厂

使用方法:在setting里面设置使用的日志格式
在这里插入图片描述
重点学习LOG4JSTDOUT_LOGGING

1.2 STDOUT_LOGGING

STDOUT_LOGGING是标准日志输出,不用进行任何配置,可以直接使用。

在这里插入图片描述
在这里插入图片描述

1.3 LOG4J

简介

  • Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件
  • 我们也可以控制每一条日志的输出格式
  • 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程
  • 通过一个配置文件来灵活地进行配置,而不需要修改应用的代码

使用步骤

  1. 导入log4j的依赖包
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
  1. log4j.properties 【放在resources目录下】
#将等级为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=./log/kuang.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
  1. 配置log4j为日志的实现
<settings>
    <setting name="logImpl" value="LOG4J"/>
</settings>
  1. Log4j的使用:直接测试运行刚才的查询
    在这里插入图片描述

简单使用

  1. 在要使用Log4j 的类中,导入包 import org.apache.log4j.Logger (此处导包容易出错)
  2. 创建日志对象,参数为当前类的class(UserDaoTest.class)
static Logger logger = Logger.getLogger(UserDaoTest.class);
  1. 日志级别
logger.info("info:进入了testLog4j");
logger.debug("debug:进入了testLog4j");
logger.error("error:进入了testLog4j");

在这里插入图片描述

2.分页

思考:为什么要分页?

  • 减少数据的处理量

2.1 Limit分页

Limit分页语法

SELECT * from user limit startIndex,pageSize;
  1. 接口
	//分页
    List<User> getUserByLimit(Map<String,Integer> map);
  1. Mapper.xml
    <resultMap id="Usermap" type="com.young.pojo.User">
        <id column="pwd" property="password"/>
    </resultMap>

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

  1. 测试
    @Test
    public void getUserByLimit(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("startIndex",1);
        map.put("pageSize",2);
        List<User> list = mapper.getUserByLimit(map);

        for (User user : list) {
            System.out.println(user);
        }

        sqlSession.close();
    }

输出:
在这里插入图片描述

2.2 RowBounds分页

不再使用SQL实现分页,通过Java代码层面实现分页,即在测试代码中完成分页操作。

  1. 接口
	//分页2
    List<User> getUserByRowBounds(Map<String,Integer> map);
  1. mapper.xml
    <select id="getUserByRowBounds" parameterType="map" resultMap="Usermap">
        select * from mybatis.user
    </select>
  1. 通过Java代码层面实现分页 【重点】
	@Test
    public void getUserByRowBounds(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //RowBounds实现
        RowBounds rowBounds = new RowBounds(1, 2);

        //Java代码实现分页
        List<User> list = sqlSession.selectList("com.young.dao.UserMapper.getUserByRowBounds", null, rowBounds);
        for (User user : list) {
            System.out.println(user);
        }

        sqlSession.close();
    }

输出:
在这里插入图片描述

2.3 分页插件

在这里插入图片描述

3.使用注解开发

3.1 面向接口编程

  • 大家之前都学过面向对象编程,也学习过接口,但在真正的开发中,很多时候我们会选择面向接口编程

  • 根本原因 : 解耦 , 可拓展 , 提高复用 , 分层开发中 , 上层不用管具体的实现 , 大家都遵守共同的标准 , 使得开发变得容易 , 规范性更好

  • 在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部是如何实现自己的,对系统设计人员来讲就不那么重要了

  • 而各个对象之间的协作关系则成为系统设计的关键。小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主要工作内容。面向接口编程就是指按照这种思想来编程。

关于接口的理解

  • 接口从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离。
  • 接口的本身反映了系统设计人员对系统的抽象理解。
  • 接口应有两类:
    • 第一类是对一个个体的抽象,它可对应为一个抽象体(abstract class);
    • 第二类是对一个个体某一方面的抽象,即形成一个抽象面(interface);
  • 一个体有可能有多个抽象面。抽象体与抽象面是有区别的。

三个面向区别

  • 面向对象是指,我们考虑问题时,以对象为单位,考虑它的属性及方法 .
  • 面向过程是指,我们考虑问题时,以一个具体的流程(事务过程)为单位,考虑它的实现 .
  • 接口设计与非接口设计是针对复用技术而言的,与面向对象(过程)不是一个问题.更多的体现就是对系统整体的架构

3.2 使用注解开发

开发步骤:

  1. 注解在接口上实现
@Select("select * from user")
List<User> getUsers();
  1. 需要再核心配置文件中绑定接口
    <mappers>
        <mapper class="com.young.dao.UserMapper"/>
    </mappers>
  1. 测试

MyBatis源码分析

使用注解开发的本质是反射机制的实现,底层是动态代理

Mybatis架构简单架构图:
在这里插入图片描述
Mybatis架构与原理可以参考这篇博文: https://www.jianshu.com/p/15781ec742f2

动态代理示意图如下:
在这里插入图片描述

3.3 CRUD示例

我们可以在工具类创建的时候实现自动提交事务,只要在创建sqlSession时,加上参true即可。

public static SqlSession  getSqlSession(){
    return sqlSessionFactory.openSession(true);
}
  1. 在接口上实现注解
public interface UserMapper {

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

    // 方法存在多个参数,所有的参数前面必须加上 @Param("id")注解
    @Select("select * from user where id = #{id}")
    User getUserByID(@Param("id") int id);


    @Insert("insert into user(id,name,pwd) values (#{id},#{name},#{password})")
    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 = #{uid}")
    int deleteUser(@Param("uid") int id);
}
  1. 将接口绑定在配置文件中,由于没有.xml的“实现类”,所以只能用<mapper class=""/>的格式,不能用<mapper resource=""/>格式绑定。
    <mappers>
        <mapper class="com.young.dao.UserMapper"/>
    </mappers>
  1. 测试

关于@Param() 注解

  • 基本类型的参数或者String类型,需要加上
  • 引用类型不需要加
  • 如果只有一个基本类型的话,可以忽略,但是建议大家都加上!
  • 我们在SQL中引用的就是我们这里的 @Param() 中设定的属性名!

4.多表查询

多表查询即指数据库中多张表联合查询,与SQL语句相比,MyBatis中多表查询在.xml中完成,相对复杂。
在这里插入图片描述

  • 左侧多个学生,对应右侧一个老师
  • 对于学生这边而言, 关联 association … 多个学生,关联一个老师 【多对一】
  • 对于老师而言, 集合 collection , 一个老师,对应一个多个学生的集合【一对多】

4.1 多对一查询

查询所有学生的信息,并显示对应的老师信息。

测试环境搭建

  1. 导入lombok
  2. 新建实体类 Teacher,Student

Teacher :

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

Student:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private int id;
    private String name;
    private Teacher teacher;

}
  1. 建立Mapper接口
  2. 建立Mapper.XML文件
  3. 在核心配置文件中绑定注册我们的Mapper接口或者文件!(重点)
  4. 测试

4.1.1 按照查询嵌套

按照查询嵌套的方法与SQL中子查询的方法类似,使用两个SQL语句,中间用resultMap连接。


<!--
    思路:
        1. 查询所有的学生信息
        2. 根据查询出来的学生的tid,寻找对应的老师!  子查询
    -->
    <select id="getStudent" resultMap="StudentTeacher">
      select * from student
    </select>

    <resultMap id="StudentTeacher" type="Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <!--复杂的属性,我们需要单独处理 对象: association 集合: collection -->
        <association property="teacher" column="tid" javaType="com.young.pojo.Teacher" select="getTeacher"/>
    </resultMap>

    <select id="getTeacher" resultType="Teacher">
        select * from teacher where id=#{tid}
    </select>

4.1.2 按照结果嵌套

按照结果嵌套的思路是:

  1. 写出完整的sql语句
  2. 在对应的resultMap中,对sql中的每一个字段进行“说明”,重点关注不在同一张表中的项的“描述”。
<!--按照结果嵌套处理-->
    <select id="getStudent2" resultMap="StudentTeacher2">
      select s.id sid,s.name sname,t.name tname
      from student s,teacher t
      where t.id=s.tid
    </select>

    <resultMap id="StudentTeacher2" type="Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname"/>
        </association>
    </resultMap>

4.2 一对多查询

要求:查询某个id对用的老师,对应的学生的集合。

测试环境搭建
基本步骤同4.1 多对一 查询,唯一不同的是学生和老师两个实体类:
Student:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private int id;
    private String name;
    private int tid;

}

Teacher:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Teacher {
    private int id;

    //一个老师对应一个学生集合
    private List<Student> students;
}

4.2.1 按照查询嵌套

    <select id="getStudent" resultMap="StudentTeacher">
      select * from student
    </select>

    <resultMap id="StudentTeacher" type="Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <association property="teacher" column="tid" javaType="com.young.pojo.Teacher" select="getTeacher"/>
    </resultMap>

    <select id="getTeacher" resultType="Teacher">
        select * from teacher where id=#{tid}
    </select>

4.2.2 按照结果嵌套

    <select id="getStudent2" resultMap="StudentTeacher2">
      select s.id sid,s.name sname,t.name tname
      from student s,teacher t
      where t.id=s.tid
    </select>

    <resultMap id="StudentTeacher2" type="Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname"/>
        </association>
    </resultMap>

4.3 小结

  1. 关联 - association 【多对一】
  2. 集合 - collection 【一对多】
  3. javaType & ofType
    1. JavaType 用来指定实体类中属性的类型
    2. ofType 用来指定映射到List或者集合中的 pojo类型,泛型中的约束类型

注意点:

  • 保证SQL的可读性,尽量保证通俗易懂
  • 注意一对多和多对一中,属性名和字段名不一致问题
  • 如果问题不好排查错误,可以使用日志 , 建议使用 Log4j

5.动态SQL

定义:动态SQL就是指根据不同的条件生成不同的SQL语句

搭建测试环境

CREATE TABLE `blog` (
  `id` varchar(50) NOT NULL COMMENT '博客id',
  `title` varchar(100) NOT NULL COMMENT '博客标题',
  `author` varchar(30) NOT NULL COMMENT '博客作者',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `views` int(30) NOT NULL COMMENT '浏览量'
) ENGINE=InnoDB DEFAULT CHARSET=utf8

创建一个基础工程

  1. 导包
  2. 编写配置文件
  3. 编写实体类
  4. 编写实体类对应Mapper接口 和 Mapper.XML文件

5.1 if语句

接口

  public Blog queryBolgIF(Map map);

mapper:

<select id="queryBolgIF" parameterType="map" resultType="blog">
        select * from blog where 1=1
        <if test="title != null">
            and title = #{title}
        </if>
        <if test="author != null">
            and author= #{author}
        </if>
    </select>

测试:

在这里插入图片描述

在这里插入图片描述

5.2 choose (when, otherwise)语句

choose语句的重点在于自动删除不合适位置处的and连接词。

接口

public Blog queryBolgChoose(Map map);

mapper:

    <select id="queryBolgChoose" parameterType="map" resultType="blog">
         select * from blog
         <where>
             <choose>
                 <when test="title!=null">
                     title = #{title}
                 </when>
                 <when test="author != null">
                      and author= #{author}
                 </when>
                 <otherwise>
                     and views=#{views}
                 </otherwise>
             </choose>
         </where>
    </select>

测试:

在这里插入图片描述

在这里插入图片描述

5.3 trim (where,set)语句

set可以自动删除不合适的逗号

接口:

public int updateBlog(Map map);

mapper:

 <update id="updateBlog" parameterType="map">
        update blog
        <set>
            <if test="title!=null">
                title=#{title},
            </if>
            <if test="author!=null">
                author=#{author}
            </if>
        </set>
        where id=#{id}
    </update>

测试:

在这里插入图片描述
在这里插入图片描述

5.4 Foreach语句

在这里插入图片描述
接口:

    List<Blog> queryForeach(Map map);

mapper:

    <select id="queryForeach" parameterType="map" resultType="blog">
        select * from blog
        <where>
            <foreach collection="ids" item="id" open="and (" close=")" separator="or">
                id =#{id}
            </foreach>
        </where>
    </select>

测试:

在这里插入图片描述

5.5 SQL片段

有的时候,我们可能会将一些功能的部分抽取出来,方便复用

  1. 使用SQL标签抽取公共的部分

    <sql id="if-title-author">
        <if test="title != null">
            title = #{title}
        </if>
        <if test="author != null">
            and author = #{author}
        </if>
    </sql>
    
  2. 在需要使用的地方使用Include标签引用即可

    <select id="queryBlogIF" parameterType="map" resultType="blog">
        select * from mybatis.blog
        <where>
            <include refid="if-title-author"></include>
        </where>
    </select>
    

注意事项:

  • 最好基于单表来定义SQL片段
  • 不要存在where标签

5.6 小结

所谓的动态SQL,本质还是SQL语句 , 只是我们可以在SQL层面,去执行一个逻辑代码

现在Mysql中写出完整的SQL,再对应的去修改成为我们的动态SQL实现通用即可

6.缓存 (空)

6.1 简介

6.2 Mybatis缓存

6.3 一级缓存

6.4 二级缓存

6.5 自定义缓存

6.6 缓存原理

7.Lombok插件

使用步骤:

  1. 在IDEA中安装Lombok插件

  2. 在项目中导入lombok的jar包

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
    </dependency>
    
  3. 在实体类上加注解即可!

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    

@Data:无参构造,get、set、tostring、hashcode,equals
在这里插入图片描述
@AllArgsConstructor:有参构造
在这里插入图片描述
@NoArgsConstructor:无参构造
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园建设方案旨在通过信息化手段提升教育、管理和服务水平,实现资源数字化、工作流程化、管理高效化和决策智能化。方案包括智慧校园信息化平台和安防平台的建设,涉及教学、科研、管理和服务等多个方面,以满足现代教育和培训需求。 技术服务要求强调了统一支撑平台的建设,包括数据标准、接口标准、代码标准和用户信息标准的统一制定。平台需满足信创和X86交叉适配要求,确保安全自主可控的系统开发环境。此外,方案还涵盖了用户中心系统、统一认证授权中心、统一工作流中心、统一智能报表中心等多个模块,以及数据共享中心、语音识别、移动服务终端等功能,以实现校园内外部信息的互联互通和资源共享。 智慧校园信息化平台的建设还包括了对教学管理、人事管理、公文管理、档案管理、即时通讯、会议管理、督办工作、资产管理等方面的数字化和自动化升级。这些模块的集成旨在提高工作效率,优化资源配置,加强监督管理,并通过移动应用等技术手段,实现随时随地的信息访问和业务处理。 安防平台的建设则侧重于校园安全,包括停车场管理、人脸识别测温、访客自助登记、视频监控等多个系统。这些系统的集成旨在提高校园的安全管理水平,实现对校园内外人员和车辆的有效监控和管理,确保校园环境的安全稳定。 最后,方案还提到了对固定资产的管理,包括购置、使用、归还、报废等全生命周期的管理,以及对网络设备、安防设备、服务器等硬件设施的配置和管理。通过这些措施,智慧校园建设方案旨在为校园提供一个安全、高效、便捷的学习和工作环境。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值