Spring boot 第3章预习

Spring boot 数据访问

1.spring boot 数据访问概述

spring boot 默认采用Spring Data 的方式统一处理数据访问层。

常见数据库依赖启动器

名称 对应数据库
spring-boot-start-data-jpa Spring Data JPA Hibernate
spring-boot-start-data-mongodb MongoDB , Spring Data MongoDB
spring-boot-start-data-neo4j Neo4j数据库, Spring Data Neo4j
spring-boot-start-data-redis Redis

2.Spring boot 整合Mybatis

  1. 准备工作

    • 创建数据库
    create database springbootdata;
    
    CREATE TABLE `t_article` (
      `id` int(20) NOT NULL AUTO_INCREMENT COMMENT '文章id',
      `title` varchar(200) DEFAULT NULL COMMENT '文章标题',
      `content` longtext COMMENT '文章内容',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
    
    
    INSERT INTO `t_article` VALUES ('1', 'Spring Boot基础入门', '从入门到精通讲解...');
    INSERT INTO `t_article` VALUES ('2', 'Spring Cloud基础入门', '从入门到精通讲解...');
    
    
      CREATE TABLE `t_comment` (
      `id` int(20) NOT NULL AUTO_INCREMENT COMMENT '评论id',
      `content` longtext COMMENT '评论内容',
      `author` varchar(200) DEFAULT NULL COMMENT '评论作者',
      `a_id` int(20) DEFAULT NULL COMMENT '关联的文章id',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
    
    
    INSERT INTO `t_comment` VALUES ('1', '很全、很详细', '狂奔的蜗牛', '1');
    INSERT INTO `t_comment` VALUES ('2', '赞一个', 'tom', '1');
    INSERT INTO `t_comment` VALUES ('3', '很详细', 'kitty', '1');
    INSERT INTO `t_comment` VALUES ('4', '很好,非常详细', '张三', '1');
    INSERT INTO `t_comment` VALUES ('5', '很不错', '张杨', '2');
    
    • 创建项目

使用Spring Initializr 方式创建项目,并勾选SQL 中的 Mybatis Framework 和 MySQL Driver

这样pom.xml 文件中就会自动添加了mybatis 的依赖 和mysql 的依赖

 <dependency>
     <groupId>org.mybatis.spring.boot</groupId>
     <artifactId>mybatis-spring-boot-starter</artifactId>
     <version>2.1.1</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
  • 创建实体类
package cn.edu.sjzc.chapter03.domain;

import java.util.List;

public class Article {

    private Integer id;
    private String title;
    private String content;
    private List<Comment> commentList;
}
    
   package cn.edu.sjzc.chapter03.domain;
   
   public class Comment {
   
       private Integer id;
       private String content;
       private String author;
       private Integer aId;
       
}
  • 添加alibaba 的druid 数据源依赖

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.10</version>
    </dependency>
    
  • 编写application.properties 配置文件

   # 数据库驱动类
   spring.datasource.driver-class-name=com.mysql.jdbc.Driver
   # 数据库地址
   spring.datasource.url=jdbc:mysql://localhost:3306/springbootdata?serverTimezone=UTC
   # 数据库用户名和密码
   spring.datasource.username=root
   spring.datasource.password=123456
   
   # 数据源的自定义配置,配置后将覆盖原有的默认配置
   # 数据库类型
   spring.datasource.type = com.alibaba.druid.pool.DruidDataSource
   # 初始化连接数
   spring.datasource.initialSize=20
   # 最小空闲连接数
   spring.datasource.minIdle=10
   # 最大连接数
spring.datasource.maxActive=100
  1. 整合

    • Mapper 接口方式整合(适用于简单的SQL 语句)

      1. 编写Mapper 接口

        package cn.edu.sjzc.chapter03.mapper;
        
        import cn.edu.sjzc.chapter03.domain.Comment;
        import org.apache.ibatis.annotations.*;
        
        @Mapper
        public interface CommentMapper {
        
            @Select("select * from t_comment where id = #{id}")
            public Comment findComment(Integer id);
        
            @Insert("insert into t_comment values (#{id},#{content},#{author},#{aId})")
            public void insertComment(Comment comment);
        
            @Update("update t_comment set comment=#{comment}")
            public void updateComment(Comment comment);
        
            @Delete("delete from t_comment where id=#{id}")
            public void deleteComment(Integer id);
        }
        
      2. 测试

        package cn.edu.sjzc.chapter03;
        
        @SpringBootTest
        class Chapter03ApplicationTests {
        
            @Autowired
            private CommentMapper commentMapper;
        
            @Test
            public void dbTest(){
                Comment comment = commentMapper.findComment(1);
                System.out.println(comment);
            }
        
        }
        

        输出结果:Comment{id=1, content=‘很全、很详细’, author=‘狂奔的蜗牛’, aId=null}

        注意 Comment类 的aId 属性为驼峰命名,数据库中t_comment 表对应的字段为a_id,类属性和字段没有对应上,所以打印出的aId 为null

        在application.properties 配置文件中加入以下配置,表示mybatis 开启驼峰命名

        
        

    开启驼峰命名规则

     mybatis.configuration.map-underscore-to-camel-case=true
     ```
       
     重新测试结果:Comment{id=1, content='很全、很详细', author='狂奔的蜗牛', aId=1}
    
  • 配置文件方式整合Mybatis(适用于复杂的SQL 语句)

    1. 创建Mapper 接口

      package cn.edu.sjzc.chapter03.mapper;
      
      import cn.edu.sjzc.chapter03.domain.Article;
      import org.apache.ibatis.annotations.Mapper;
      
      @Mapper
      public interface ArticleMapper {
          public Article selectArticle(Integer id);
      }
      
      
      
       
    
       
    2. 创建xxMapper.xml 映射配置文件
       
       ```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 namespace="cn.edu.sjzc.chapter03.mapper.ArticleMapper">
           
           <resultMap id="articleMap" type="cn.edu.sjzc.chapter03.domain.Article">
               <id property="id" column="id"></id>
               <result property="title" column="title"></result>
               <result property="content" column="content"></result>
               <collection property="commentList" ofType="Comment">
                   <id property="id" column="cid"></id>
                   <result property="content" column="content"></result>
                   <result property="author" column="author"></result>
                   <result property="aId" column="aId"></result>
               </collection>
           </resultMap>
           
           <select id="selectArticle" resultMap="articleMap" parameterType="Integer">
               select a.*,c.id cid,c.content,c.author,c.a_id from t_article a,t_comment c where a.id = c.a_id and a.id=#{id}
           </select>
       </mapper>
    
    
    1. 全局配置文件(application.properties)中配置 xxMapper.xml 的路径 和 配置实体类别名

      
      

    配置Mybatis 的xxMapper.xml文件路径

    mybatis.mapper-locations=classpath:mapper/ArticleMapper.xml

    配置xxMapper.xml 文件中实体类别名

    mybatis.type-aliases-package=cn.edu.sjzc.chapter03.domain

       
       
       
    4. 测试
    
       ```java
    package cn.edu.sjzc.chapter03;
       
       @SpringBootTest
       class Chapter03ApplicationTests {
           
           @Autowired
           private ArticleMapper articleMapper;
           @Test
           public void dbTest2(){
               Article article = articleMapper.selectArticle(1);
               System.out.println(article);
        }
     }
    
    

    输出结果:

    Article{id=1, title=‘Spring Boot基础入门’, content=‘从入门到精通讲解…’, commentList=[Comment{id=1, content=‘从入门到精通讲解…’, author=‘狂奔的蜗牛’, aId=null}, Comment{id=2, content=‘从入门到精通讲解…’, author=‘tom’, aId=null}, Comment{id=3, content=‘从入门到精通讲解…’, author=‘kitty’, aId=null}, Comment{id=4, content=‘从入门到精通讲解…’, author=‘张三’, aId=null}]}

3.spring boot 整合JPA

  1. <dependency>
        <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    
    
   
   
   
2. 创建ORM 实体类

   实体类的成员变量与表属性相对应

   @Entity(name="**xxx**") 注解加在类上,表示该**实体类**与**xxx表**对应,@Id 注解加在**主键**对应的**成员变量**上,@GeneratedValue (**strategy** = GenerationType.IDENTITY) 和@Id 注解一起使用,表示主键自增,@Column(name="**xxx**")  注解加在成员变量上,表示该**成员变量**与表中的**xxx**属性相对应。

   ```java
   package cn.edu.sjzc.chapter03.domain;
   
   import javax.persistence.*;
   
   @Entity(name="t_comment") // 表示实体类对应的表
   public class Discuss {
       @Id // 加载主键上
       @GeneratedValue(strategy = GenerationType.IDENTITY) // 表示主键自增
       private Integer id;
   
       @Column(name = "content")
       private String content;
       @Column(name = "author")
       private String author;
       @Column(name = "aId")
       private Integer aId;
       // 省略set 方法
       @Override
       public String toString() {
           return "Discuss{" +
                   "id=" + id +
                   ", content='" + content + '\'' +
                   ", author='" + author + '\'' +
                   ", aId=" + aId +
                   '}';
       }
   }

  1. 创建JpaRepository 接口的子接口

    自定义DiscussRepository 接口继承JpaRepository 接口,JpaRepository 接口包含了常用的CRUD(增删改查)方法,如果常用CRUD方法无法满足需要,可以在自定义接口中自定义方法,如下。

    @Query(value=“sql”) 注解加在自定义方法上,sql表示调用该方法所执行的sql语句,该sql语句中**?1**,表示该方法的第一个参数。@Transaction 注解加在有数据库变更的方法上,如果调用该方法的service 层已经添加了@Transaction 注解,则自定义接口中可以省略该注解,否则不能省略。@Modifying 注解加在有@Query 注解且有数据库变更的方法上。

    package cn.edu.sjzc.chapter03.repository;
    
    import cn.edu.sjzc.chapter03.domain.Discuss;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.jpa.repository.Modifying;
    import org.springframework.data.jpa.repository.Query;
    import org.springframework.transaction.annotation.Transactional;
    
    import java.awt.print.Pageable;
    import java.util.List;
    
    public interface DiscussRepository extends JpaRepository<Discuss,Integer> {
    
        // 查询author 非空的Discuss 集合
        public List<Discuss> findByAuthorNotNull();
    
        // 根据文章id 查询Discuss 集合
        @Query("select c from t_comment c where c.aId=?1")
        public List<Discuss> getDiscussPaged(Integer aid, Pageable pageable);
    
        @Query(value = "select c from t_comment c where c.aId=?1",nativeQuery = true)
        public List<Discuss> getDiscussPaged2(Integer aid, Pageable pageable);
    
        // 根据评论id 修改评论作者
        @Transactional
        @Modifying
        @Query("update t_comment c set author=?1 where id=?2")
        public int updateDiscuss(String author,Integer id);
    
        //根据评论id 删除评论
        @Transactional
        @Modifying
        @Query("delete from t_comment c where c.id=?1")
        public int deleteDiscussById (Integer id);
    
    }
    
    
    
  2. 测试

        @Autowired
        private DiscussRepository discussRepository;
        @Test
        public void jpaTest(){
            // 自定义方法
            List<Discuss> byAuthorNotNull = discussRepository.findByAuthorNotNull();
            for (Discuss discuss : byAuthorNotNull) {
                System.out.println(discuss);
            }
        }
    
        @Test
        public void jpaTest2(){
           // 父接口定义的方法
            List<Discuss> discusses = discussRepository.findAll();
            for (Discuss discuss : discusses) {
                System.out.println(discuss);
            }
        }
        @Test
        public void jpaTest3(){
            // 父接口中定义的方法
            Optional<Discuss> byId = discussRepository.findById(1);
            System.out.println(byId);
        }
        @Test
        public void jpaTest4(){
            //  自定义方法
            discussRepository.deleteDiscussById(4);
        }
    
    

4.spring boot 整合 redis

  1. 准备工作

    • 安装redis

      下载地址: https://github.com/MicrosoftArchive/redis/releases

    • 启动redis

    • 安装图形界面: https://www.jianshu.com/p/6895384d2b9e

  2. 整合

    • 添加依赖

      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-redis</artifactId>
      </dependency>
      
      
    • 创建实体类

      • Person 类

        package cn.edu.sjzc.chapter03.domain;
        
        import org.springframework.data.annotation.Id;
        import org.springframework.data.redis.core.RedisHash;
        import org.springframework.data.redis.core.index.Indexed;
        
        import java.util.List;
        
        @RedisHash("persons")
        public class Person {
            @Id
            private String id;
        
            @Indexed
            private String firstName;
            @Indexed
            private String lastName;
        
            private Address address;
            private List<Family> familyList;
        }
        
        
        
      • Address 类

        package cn.edu.sjzc.chapter03.domain;
        
        import org.springframework.data.redis.core.index.Indexed;
        
        public class Address {
            @Indexed
            private String city;
            @Indexed
            private String country;
        }
        
        
      • Family 类

        package cn.edu.sjzc.chapter03.domain;
        
        import org.springframework.data.redis.core.index.Indexed;
        
        public class Family {
            @Indexed
            private String type;
            @Indexed
            private String username;
        }
        
        
        
    • 创建自定义接口

      package cn.edu.sjzc.chapter03.repository;
      
      import cn.edu.sjzc.chapter03.domain.Person;
      import org.springframework.data.repository.CrudRepository;
      
      import java.awt.print.Pageable;
      import java.util.List;
      
      public interface PersonRepository extends CrudRepository<Person,String> {
          List<Person> findByLastName(String lastname);
          List<Person> findPersonByLastName(String lastname, Pageable pageable);
          List<Person> findByFirstNameAndLastName(String firstname,String lastname);
          List<Person> findByAddress_City(String city);
          List<Person> findByFamilyList_Username(String username);
      
      }
      
      
    • 测试

      package cn.edu.sjzc.chapter03;
      
      import ...
      
      @SpringBootTest
      class Chapter03ApplicationTests {
      
          // redis 测试
          @Autowired
          private PersonRepository personRepository;
      
          @Test
          void testRedis(){
              Person person = new Person();
      
              person.setFirstName("li");
              person.setLastName("ze");
      
              Address address = new Address();
              address.setCity("石家庄");
              address.setCountry("中国");
              person.setAddress(address);
      
              Family family = new Family();
              family.setType("爸爸");
              family.setUsername("li");
      
              Family family1 = new Family();
              family1.setType("妈妈");
              family1.setUsername("wang");
      
              List<Family> familyList = new ArrayList<>();
              familyList.add(family);
              familyList.add(family1);
      
              person.setFamilyList(familyList);
      
              personRepository.save(person);
          }
          
          @Test
          void testRedis2(){
              List<Person> personList = personRepository.findByLastName("ze");
              for (Person person : personList) {
                  System.out.println(person);
              }
          }
      }
      
      

      运行test1,打开redis 图形界面,发现已将person 对象存储到redis 数据库中

      运行test2,将redis 中的数据存储到java 对象中

发布了25 篇原创文章 · 获赞 0 · 访问量 1278

猜你喜欢

转载自blog.csdn.net/weixin_42059368/article/details/104541461