Spring-SpringBoot-SpringMVC三大框架的学习

目录

一、介绍

二、学习Spring

1、两大核心

2、存和取对象

三、学习Mybaties

1、介绍

2、操作数据库的步骤

3、具体操作数据库的方法

第一种(注解):

查:

增:

删:

改:

要注意的问题:

第二种(XML):

查:

删:

改:

要注意的问题:

4、 #和$

1、 #和$分别代表的SQL是什么?

2、#和$的区别

3、#和$的用法

5、数据库连接池


一、介绍

这是三个框架。

Spring就是一个Ioc容器,帮助我们管理对象。

SpringBoot框架是为了简化Spring,集成了很多框架,能够让我们快速的开发出一个Spring程序。

SpringMVC又叫Spring Web MVC,是用于开发Web应用和网络接口的,所以它是一个Web框架。

二、学习Spring

Java程序的一个原则:高内聚低耦合

高内聚好比是一个班级内的同学们联系紧密,团结互助,一个模块内的程序紧密联系。

低耦合好比是一个年级内的各个班级,这个年纪要去比赛,但是有一个班级出问题了,时时不能参加,导致整个年级不能去参加,耽误整个年级的荣誉,也就是程序中的每个模块联系不能紧密,要分工干活。

为了能够实现高内聚低耦合,就要使用Spring框架。

1、两大核心

Spring的两大核心是IoC和DI。

        IoC的意思是控制权反转,原来逻辑是:谁用对象,谁就要去创建对象,现在权力反转了,不再需要自己去创建了,Spring会帮助创建好对象,只要有谁需要用到,就会给谁。这个操作实现了高内聚低耦合,不再因为仅仅要改一个小地方的代码,导致一连串的代码都需要改的这种问题。

        DI的意思是依赖注入,依赖的意思是对象,谁需要对象,就要把对象注入给谁。

2、存和取对象

那么它既然是一个管理对象的容器,就肯定要有存对象和取对象的功能。

存对象:使用五大类注解和@Bean。

        首先需要明白注解是干什么用的?我们要知道程序是为了解决生活中的问题的,那我们现在用的spring框架,它是可以管理我们程序的,那么使用注解,就是程序中的某一块代码在告诉spring,你去干什么干什么,怎么操作我。

取对象:三种注入方式。

三、学习Mybaties

1、介绍

Mybaties是一个持久层框架,是用来操作数据库的。

2、操作数据库的步骤

操作数据库要分为以下三步:

  • 1、导入Mybatis赖和MySQL驱动依赖。
<!--Mybatis 依赖包-->
 <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
   <version>2.3.1</version> 
 </dependency>

 <!--mysql驱动包-->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>
  • 2、在application.yml中配置数据库相关参数。
spring:
   datasource:
     url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
     username: root
     password: root
     driver-class-name: com.mysql.cj.jdbc.Driver
  • 3、在数据库中创建需要的表,并在idea中创建出对应的实体类,并加上@Data注解,表中的字段要与类中的属性名一 一对应。

  • 4、创建持久层接口:XxxInfoMapper,并加上@Mapper注解,在类中写出操作数据库的相关代码。

  • 5、最后可以使用idea创建测试类,加上@SpringBootTest注解,去加载Spring的运行环境,加上@Slf4j注解,可以在控制台打印出日志,最后再去测试写出的代码是否正确。

3、具体操作数据库的方法

两种:第一种:通过注解开发数据库;第二种:通过XML方式开发。

下面通过增删改查的操作去具体介绍两种方法。

第一种(注解):

查:

在XxxInfoMapper的类中,编写selectAll接口,使用@Select注解

@Select("select * from userinfo") //方法的实现
List<UserInfo> selectAll(); //方法的声明
 增:

        在XxxInfoMapper的类中,编写insert接口,使用@insert注解实现,看insert方法的参数,传递的一个对象,那么sql语句中,怎么接收到对象中的属性值呢?直接写出对象中的属性变量名即可,这也就要求了,必须要和实体类中的属性名要写的一模一样。

 //增
    //insert方法的实现
    @Insert(" insert into userinfo (username,password,age,gender,phone ) " +
            " values (#{username},#{password},#{age},#{gender},#{phone}) ")
    //方法的声明
    Integer insert(UserInfo userInfo);
删:
//方法实现
@Delete("delete from userinfo  where id = #{id} ")
//方法定义
Integer delete(Integer id);
改:
@Update("update userinfo set age=#{age} where id=#{id}")
Integer update(UserInfo userInfo);
要注意的问题:

1:传参问题

selectOne方法传了一个id值,如果只传一个值,就像现在这样,sql语句中接收id值的变量可以随意起名,但是一般要与方法中的形参保持一致。

@Select("select * from userinfo where id = #{id}")
UserInfo selectOne( Integer id);
//也可以对id重命名,使用@Param重命名
//UserInfo selectOne(@Param("useid") Integer id);

2:重命名问题

若此时对 对象重命名,注解中还能自动获取到对象中的值吗?答案是不能!,要采用对象名.属性名的方法获取。如下图所示:

 @Options(useGeneratedKeys = true,keyProperty = "id")
 @Insert(" insert into userinfo (username,password,age,gender,phone ) " +
      " values (#{userInfo.username},#{userInfo.password},#{userInfo.age},#{userInfo.gender},#{userInfo.phone}) ")
 Integer insert(@Param("userInfo")UserInfo userInfo);

3:获取自增ID问题

对于增 这一操作,如何获取自增ID呢,因为在实际操作中,后续可能会用到ID值去做一些事情。

如下图所示,使用@Options注解,两个参数,第一个参数的意思是:是否要获得并使用key值,第二个参数用来接收key值,此时赋值给了实体类中的id。

 @Options(useGeneratedKeys = true,keyProperty = "id")
 @Insert(" insert into userinfo (username,password,age,gender,phone ) " +
           " values (#{username},#{password},#{age},#{gender},#{phone}) ")
 Integer insert(UserInfo userInfo);

4:映射问题

对于查这一操作,是如何获取到数据库中的数据的呢? 通过Mybaties将数据库中的字段与实体类中的属性名进行映射,获得数据库中的想要的数据。这就要求字段名与属性名要一 一对应,但是若字段名与属性名不匹配怎么办?有以下三种解决办法:

  • 对字段起别名,起与属性名相同的名字
@Select("select username,password,age,gender,phone,delete_flag as deleteflag,create_time as createtime,update_time as updatetime from userinfo")
List<UserInfo> selectAll();
  • 利用映射规则,通过@Results注解告诉Mybaties如何进行映射

如下图所示:

 @Results(value = {
    @Result(column = "delete_flag",property = "deleteflag"),
    @Result(column = "create_time",property = "createtime"),
    @Result(column = "update_time",property = "updatetime")
 })
 @Select("select * from userinfo where id = #{useid}")
 UserInfo select1(@Param("useid") Integer id);

 如果其他的select方法也需要这种操作,要重写一遍这个注解吗?心中要有一个字:“懒”,只要给Results起个名即可。

 @Results(id = "Map", value = {
    @Result(column = "delete_flag",property = "deleteflag"),
    @Result(column = "create_time",property = "createtime"),
    @Result(column = "update_time",property = "updatetime")
 })
 @Select("select * from userinfo where id = #{useid}")
 UserInfo select1(@Param("useid") Integer id);
//在其他select方法处,使用@ResultMap方法,可以达成复用。
@ResultMap(value = "Map")
@Select("select * from userinfo where id = #{useid}")
UserInfo select2(@Param("useid") Integer id);
  • 开启驼峰命名

潜规则:字段名若有多个单词命名,用下横线间隔,而实体类中的属性名用小驼峰法命名。

那我现在不想手动操作了,Mybaties可以帮我将字段名自动转成小驼峰命名的名字吗?答案是可以!使用配置的方式。(在application.yml中)

mybatis:
 configuration:
 map-underscore-to-camel-case: true #配置驼峰⾃动转换

第二种(XML):

通过XML方式开发,与注解不同的是,不使用注解去实现操作数据库的方法,而是在xml文件中编写方法的实现。

步骤:

  • 编写xml文件

这是xml文件的声明,声明此文件是在实现哪个接口,要写出接口的全限定类名。(在XML中声明的)

声明的下面这个接口:

  • 指明xml文件所在的地址(在yml文件中写)
mybatis:
  configuration:
    # map-underscore-to-camel-case: true #配置驼峰自动转换
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印Sql语句
  mapper-locations: classpath:mapper/**Mapper.xml #指明xml文件所在地址
#配置的名字要与实现的xml文件的名字对应上
查:

id的名字要与要实现的方法的名字一模一样。

查询到的数据要返回给select方法,所以resultMap要等于要返回的数据的权限的类名。看下面第二个图,返回的数据的类型是UserInfo类。

<select id="selectAll" resultType="com.bite.demo.model.UserInfo">
   select * from userinfo
</select>

增:  (自增ID的获取方法与注解相同)

<insert id="insert" useGeneratedKeys="true" keyProperty="id">
  insert into userinfo(username,password,age,gender,phone)
  values(#{username},#{password},#{age},#{gender},#{phone})
</insert>
删:
<delete id="delete">
   delete from userinfo where id=#{id}
</delete>
改:
<update id="update">
    update userinfo set gender = #{gender}
    where id = #{id} 
</update>
要注意的问题:

1:插的重命名问题

Integer insert2(@Param("userInfo") UserInfo userInfo);

解决方法也是与注解类型:(通过对象名.属性名去获得)

 <insert id="insert2" useGeneratedKeys="true" keyProperty="id">
     insert into userinfo (username,password,age,gender,phone)
     values(#{userInfo.username},#{userInfo.password},
     #{userInfo.age},#{userInfo.gender},#{userInfo.phone})
</insert>

 2:查中的映射问题

由于数据库的字段名与实体类中的有的属性名不一致,映射不上,导致有的字段赋值不了属性,导致查出来的数据部分为默认值。

方法:(与注解相似,但是没有通过注解的方法(@Results))

  • 给字段起别名(与注解相同)
  • 通过在配置文件写上相应配置代码(与注解相同)
mybatis:
  configuration:
    # map-underscore-to-camel-case: true #配置驼峰自动转换
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印Sql语句
  mapper-locations: classpath:mapper/**Mapper.xml

  •  结果映射:使用ResultMap,先起个别名,随便起。type表示类型,想要通过数据库的字段映射成什么类型,就去写什么类型,不过一定要是全限定类名。
<resultMap id="XmlBaseMap" type="com.bite.demo.model.UserInfo">
  <id column="id" property="id"></id>
  <result column="delete_flag" property="deleteFlag"></result>
  <result column="create_time" property="createTime"></result>
  <result column="update_time" property="updateTime"></result>
</resultMap>

接着再写:

//这是原来的
<select id="selectAll" resultType="com.bite.demo.model.UserInfo">
   select * from userinfo
</select>
/*这是有了ResultMap之后。不用再写resultType了,
直接用上面写的resultMap,既成功映射了,又表示了要返回的数据的类型。*/
<select id="selectAll2" resultMap="XmlBaseMap"> 
//resultMap的名字要与上面写的resultMap的名字一样
   select * from userinfo
</select>

4、 #和$

1、 #和$分别代表的SQL是什么?

  • 使用#去赋值,输入参数给SQL语句后,不会去拼接到SQL中,而是用?这个符号去占位。

接口中:

测试类中(把1这个数字传给selectOne方法):

控制台:

所以#这种不用拼接的SQL叫做预编译SQL。

  • 换成$去赋值,再去编译:

测试类:

控制台:

此时1,直接拼接到SQL语句中了,并没有占位 ,这种SQL是即时SQL。

2、#和$的区别

他俩的区别就是预编译SQL与既是SQL的区别

首先先要了解SQL的执行过程:

第一步:语法编译,第二步:SQL优化,第三步:SQL执行。

预编译SQL在一次编译后会缓存这一条SQL语句,再一次编译时,不会执行前两步,直接执行第三步,也就是提前挖好坑一个坑,就等着参数传进去执行了,所以会提高效率。

而即时SQL每次都会执行这三步,不会挖坑。

所以区别就是:

预编译SQL性能高,且不存在SQL注入的问题。

SQL注入:给sql传进去的参数,改变了SQL的正常执行流程,导致出现错误。

例如:

使用这条SQL语句会从左到右拼接 ,导致会查出所有。

为什么即时SQL会出现SQL注入的问题?

因为会进行SQL拼接,导致SQL语句被改变。

3、#和$的用法

当使用#赋值时,若参数类型为String时,会自动给参数加上单引号,但有的时候,不需要加单引号,所以要用$赋值。

例如:进行排序操作,不能使用#;当表名,字段名作为参数时,也不能使用#。

这是一个排序操作,此时使用#的话,会给sort加上单引号,但是不用给它加,加了会报错的,#区分不了什么时候加,什么时候不加,太死心眼,遇到String类型的,就会无脑加。

在接口中:

有个例外:模糊查询,使用#会报错,使用$会造成SQL注入的问题,只能用内置函数concat()函数搭配#使用。

模糊查询:使用#

 报错:

使用$ :

没有报错

5、数据库连接池

项目要运行,要进行数据库的连接,过后,还要释放连接,但现在提前储存连接,需要的时候直接拿就可以,存放那些连接的地方就叫做连接池,这样做提高了效率。

  • 13
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值