Spring Boot数据访问
SpringBoot数据访问概述
1.创建数据库
create database springbootdata;
2.创建表
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;
3.向数据表t_article插入相关数据
INSERT INTO `t_article` VALUES('1','SpringBoot基础入门','从入门到荆同讲解......');
INSERT INTO `t_article` VALUES('2','SpringCloud基础入门','从入门到荆同讲解......');
4.创建数据表t_comment
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;
5.向数据表t_comment插入相关数据
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');
6.创建项目,引入MySQL和MyBatis的依赖启动器
7.编写实体类Comment和Article
实体类:Comment
public class Comment {
private Integer id;
private String content;
private String author;
private Integer aId;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Integer getaId() {
return aId;
}
public void setaId(Integer aId) {
this.aId = aId;
}
}
实体类:Article
import java.util.List;
public class Article {
private Integer id; //文章的id
private String title; //文章的标题
private String content; //文章的内容
private List<Comment> commentsList; //文章的评论
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public List<Comment> getCommentsList() {
return commentsList;
}
public void setCommentsList(List<Comment> commentsList) {
this.commentsList = commentsList;
}
}
8.编写配置文件
1.在全局配置文件中进行数据库连接配置
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
2.设置数据源类型配置(以阿里巴巴的Druid数据源为例)
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
9.在全局配置文件中设置属性
如果在开发过程中,需要对这些第三方Druid的运行参数进行重新设置,必须在application.properties配置文件中进行默认参数覆盖
#对数据源默认值进行了修改
#数据源类型
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#初始化连接数
spring.datasource.initialSize=20
#最小空闲数
spring.datasource.minIdle=10
#最大连接数
spring.datasource.maxActive=100
SpringBoot整合Mybatis
相比于传统的SSM整合Mybatis框架,SpringBoot更为快捷方便,,支持注解和配置两种方式的整合
第一种:使用注解方式整合MyBatis
1.创建Mapper接口文件
@Mapper //表示该类是一个mybatis接口文件,是需要被SpringBoot进行扫描的
public interface CommentMapper {
@Select("select * from t_comment where id = #{id}")
public Comment findById(Integer id);
@Insert("insert into t_comment values(#{id},#{content},#{author},#{aId})")
public void insertComment(Comment comment);
@Update("update t_comment set content = #{content} where id = #{id}")
public void updateComment(Comment comment);
@Delete("delete from t_comment where id = #{id}")
public void deleteComment(Integer id);
}
2.编写测试
@SpringBootTest
class Chapter03ApplicationTests {
@Autowired
private CommentMapper commentMapper;
@Test
public void MapperTest01(){
Comment byId = commentMapper.findById(1);
System.out.println(byId);
commentMapper.insertComment(new Comment(6,"入木三分","郭郭",2));
}
}
3.数据库中的字段名和实例对象中的属性名对应不上:可以在SpringBoot全局配置里面添加一个驼峰命名匹配的映射配置
#开启驼峰命名匹配映射
mybatis.configuration.map-underscore-to-camel-case=true
第二种:使用配置文件方式整合Mybatis
使用注解相对简单,但是对于复杂的操作(多表操作),使用注解的方式就相对比较麻烦了,对于数据操作比较复杂的,在开发中我们更倾向于使用配置文件
的方式,去整合Mybatis
1.创建Mapper接口文件:@Mapper
@Mapper
public interface ArticleMapper {
//根据id查询文章(包含对应的评论)(一篇文章对应多条评论多表查询)
public Article selectArticle(Integer id);
}
2.创建XML映射文件:编写对应的SQL语句
SQL语句多表查询中,多个表中的字段属性名相同时,在进行封装时不知道赋哪个字段属性封装到实体中的属性上(不能同时多个字段值对应一个实例的属性)
处理方法:对其中一个字段起别名
select a.*, c.id c_id, c.content c_content, c.author, c.a_id
from t_article a, t_comment c
where c.a_id = a.id and a.id=#{aid};
<?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="com.guo.mapper.ArticleMapper"> <!--namespace 配置对应接口的全路径-->
<!--配置映射关系-->
<resultMap id="ac" type="Article">
<id property="id" column="id"></id>
<result property="title" column="title"></result>
<result property="content" column="content"></result>
<collection property="commentList" ofType="com.guo.domain.Comment">
<id property="id" column="c_id"></id>
<result property="content" column="c_content"></result>
<result property="author" column="author"></result>
<result property="aId" column="aId"></result>
</collection>
</resultMap>
<!--查询操作-->
<select id="selectArticle" resultMap="ac" parameterType="int">
select a.*, c.id c_id, c.content c_content, c.author, c.a_id
from t_article a,
t_comment c
where c.a_id = a.id and a.id=#{aid};
</select>
</mapper>
3.在全局文件中配置XML映射文件路径以及实体类别名映射路径
#配置mybatis的xml配置文件路径
mybatis.mapper-locations=classpath:mapper/ArticleMapper.xml
#配置xml映射文件中指定的实体类别名路径
mybatis.type-aliases-package=com.guo.domain
4.编写测试方法进行接口方法测试及整个测试
@Autowired
private ArticleMapper articleMapper;
@Test
public void testArticle(){
Article article = articleMapper.selectArticle(2);
System.out.println(article);
}
结果:
Article{id=2, title=‘SpringCloud基础入门’, content=‘从入门到荆同讲解…’, commentsList=[Comment{id=5, content=‘很不错’, author=‘张扬’, aId=null}]}
如果数据库中多表查询时有多个字段名相同,没有用别名处理的话(我这里测试的是多表查询出来的相同字段的第一个字段值映射到实例属性上)
Article{id=2, title=‘SpringCloud基础入门’, content=‘从入门到荆同讲解…’, commentsList=[Comment{id=2, content=‘从入门到荆同讲解…’, author=‘张扬’, aId=null}]}
使用SpringBoot整合JPA
在pom文件中添加Spring Data JPA依赖启动器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Spring Data JPA的基本使用
第一步:编写ORM实体类:与表映射
@Entity(name = “t_comment”) //表示当前实体类是与表有映射关系的实体类
@Entity(name = "数据库表名")
@Id //表示配置该属性对应的字段为主键
@GeneratedValue(strategy = GenerationType.IDENTITY) //主键生成策略自增长
@Column(name = “content”) //@Column就是属性与字段的映射关系
@Column(name = "字段名")
package com.guo.domain;
import javax.persistence.*;
/**
* 编写实体类并创建映射关系
*/
@Entity(name = "t_comment") //表示当前实体类是与表有映射关系的实体类
public class Discuss {
@Id //表示配置该属性对应的字段为主键
@GeneratedValue(strategy = GenerationType.IDENTITY) //主键生成策略自增长
private Integer id;
@Column(name = "content") //@Column就是属性与字段的映射关系
private String content;
@Column(name = "author")
private String author;
@Column(name = "aId")
private Integer aId;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Integer getaId() {
return aId;
}
public void setaId(Integer aId) {
this.aId = aId;
}
@Override
public String toString() {
return "Discuss{" +
"id=" + id +
", content='" + content + '\'' +
", author='" + author + '\'' +
", aId=" + aId +
'}';
}
}
第二步:编写Repository接口DiscussRepository
-
满足JPA规范 ---->继承JpaRepository<当前操作的实体类,实体类中主键字段的数据类型>
-
继承后就具备了简单的
增删改查
的方法 -
使用了JPA查询的一种方式格式必须是findByXxxNotNull()
-
@Query(value = “select * from t_comment where a_Id=?1”,nativeQuery = true) //nativeQuery = true:表示SQL是原生的SQL语句 (使用原生的SQL语句必须加上)
-
修改删除操作要加上
@Transactional //进行事务控制
@Modifying //只要对数据库数据进行变更都需要添加上@Modfying
@Query(“update t_comment c set c.author = ?1 where c.id=?2”)
package com.guo.respoitory;
import com.guo.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;
//满足JPA规范 继承JpaRepository<当前操作的实体类,实体类中主键字段的数据类型>
//继承后就具备了简单的增删改查的方法
public interface DiscussRepository extends JpaRepository<Discuss,Integer> {
//1.查询author非空的Discuss评论集合
public List<Discuss> findByAuthorNotNull(); //使用了JPA查询的一种方式格式必须是findByXxxNotNull()
//2.根据文章的id分页查询Discuss评论集合
@Query("select c from t_comment c where c.aId = ?1") //jpql语句操作实体和属性,,SQL操作表和字段
public List<Discuss> getDiscussPaged(Integer aid, Pageable pageable);
//3.使用元素SQL语句,根据文章id分页查询Discuss评论集合
@Query(value = "select * from t_comment where a_Id=?1",nativeQuery = true) //nativeQuery = true:表示SQL是原生的SQL语句
public List<Discuss> getDiscussPaged2(Integer aid,Pageable pageable);
//4.根据评论id修改评论作者author
@Transactional //进行事务控制
@Modifying //只要对数据库数据进行变更都需要添加上@Modfying
@Query("update t_comment c set c.author = ?1 where c.id=?2")
public int updateDiscuss(String author,Integer id);
//5.根据评论id删除评论
@Transactional
@Modifying
@Query("delete from t_comment c where c.id = ?1")
public int deleteDiscuss(Integer id);
}
测试
package com.guo.chapter03;
import com.guo.domain.Article;
import com.guo.domain.Comment;
import com.guo.domain.Discuss;
import com.guo.mapper.ArticleMapper;
import com.guo.mapper.CommentMapper;
import com.guo.respoitory.DiscussRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
import java.util.Optional;
@SpringBootTest
class JpaTests {
@Autowired
private DiscussRepository discussRepository;
@Test
public void test01(){
List<Discuss> byAuthorNotNull = discussRepository.findByAuthorNotNull();
for (Discuss discuss : byAuthorNotNull) {
System.out.println(discuss);
}
System.out.println("*************************");
Optional<Discuss> byId = discussRepository.findById(1);
System.out.println(byId.get());
}
}
运行结果:
Discuss{id=1, content='很全,很详细', author='狂奔的蜗牛', aId=1}
Discuss{id=2, content='赞一个', author='tom', aId=1}
Discuss{id=3, content='很详细', author='kitty', aId=1}
Discuss{id=4, content='很好,非常详细', author='张三', aId=1}
Discuss{id=5, content='很不错', author='张扬', aId=2}
Discuss{id=6, content='入木三分', author='郭郭', aId=1}
*************************
Discuss{id=1, content='很全,很详细', author='狂奔的蜗牛', aId=1}
Redis介绍
Redis是一个开源
(BSD许可)的、内存中的数据结构
存储系统,它可以用作数据库
、缓存
和消息中间件
,并提供多种语言的API。
Redis优点
1.存取速度快
: Redis速度非常快,每秒可执行大约110000次的设值操
作,或者执行81000次的读取操作。
2.支持丰富的数据类型
: Redis支持开发人员常用的大多数数据类型,例
如列表、集合、排序集和散列等。
3.操作具有原子性
:所有Redis操作都是原子操作,这确保如果两个客户
端并发访问,Redis服务器能接收更新后的值。
4、提供多种功能
: Redis提供了多种功能特性,可用作非关系型数据库、
缓存中间件、消息中间件等。
Redis下载路径
下载解压目录下文件:
双击redis-server.exe即开启Redis服务,效果如下图
Redis可视化客户端工具安装连接
Redis解压目录下的redis-cli.exe指令用于开启客户端工具,不过双击这个指令打开的是终端操作界面,对于Redis 的可视化操作和查看并不理想。这里推荐一个Redis客户端可视化管理工具Redis Desktop Manager 连接Redis 服务进行管理,读者可以自行在官网:https://redisdesktop.com/download进行下载安装。下载并安装完Redis Desktop Manager工具后,打开并连接上对应的Redis 服务,操作示例如图3-10所示。
网盘下载
下载后双击:傻瓜式安装:Next >> I Agree >> Install >> Next >> Finish
SpringBoot整合Redis![在这里插入图片描述](https://img-blog.csdnimg.cn/189842f27345411fad77ae8e73c9f56a.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAODQ4Njk4MTE5,size_20,color_FFFFFF,t_70,g_se,x_16)
1.在pom文件中添加Spring Data Redis 依赖启动器
<dependency> <!--redis依赖启动器-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.编写实体类 Person Address Family
@RedisHash(“persons”) //在Redis中为我们开辟一块存储空间,空间的名称就叫persons
@Indexed() //用于标识该属性会在Redis数据库中生成二级索引
@Id //用于标识实体类主键
Person类
package com.guo.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") //在Redis中为我们开辟一块存储空间,空间的名称就叫persons
public class Person {
@Id //用于标识实体类主键
private String id;
@Indexed() //用于标识该属性会在Redis数据库中生成二级索引
private String firstname; //名字
private String lastname; //姓氏
private Address address; //家庭住址
private List<Family> familyList; //家庭成员
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public List<Family> getFamilyList() {
return familyList;
}
public void setFamilyList(List<Family> familyList) {
this.familyList = familyList;
}
@Override
public String toString() {
return "Person{" +
"id='" + id + '\'' +
", firstname='" + firstname + '\'' +
", lastname='" + lastname + '\'' +
", address=" + address +
", familyList=" + familyList +
'}';
}
}
Family类
package com.guo.domain;
import org.springframework.data.redis.core.index.Indexed;
public class Family {
@Indexed
private String type;
@Indexed
private String username;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String toString() {
return "Family{" +
"type='" + type + '\'' +
", username='" + username + '\'' +
'}';
}
}
Address 类
package com.guo.domain;
import org.springframework.data.redis.core.index.Indexed;
public class Address {
@Indexed
private String city;
@Indexed
private String country;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
@Override
public String toString() {
return "Address{" +
"city='" + city + '\'' +
", country='" + country + '\'' +
'}';
}
}
3.编写Repository接口
package com.guo.respoitory;
import com.guo.domain.Person;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
public interface PersonRepository extends CrudRepository<Person,String> {
List<Person> findByLastname(String lastname); //根据姓氏查询某人
Page<Person> findPersonByLastname(String lastname, Pageable page); //根据姓氏查询某人,加了分页查询
List<Person> findByFirstnameAndLastname(String firstname,String lastname); //根据姓和名组合一起来查询某人
List<Person> findByAddress_City(String city); //根据住址查询
List<Person> findByFamilyList_Username(String username); //根据名字查询家庭
}
4.在全局配置文件Application.properties中添加Redis数据库连接配置
#配置redis连接
#redis服务器地址
spring.redis.host=127.0.0.1
#Redis 连接端口
spring.redis.port=6379
#redis服务连接密码
spring.redis.password=
5.编写单元测试进行接口方法测试以及整合测试
package com.guo.chapter03;
import com.guo.domain.Address;
import com.guo.domain.Family;
import com.guo.domain.Person;
import com.guo.respoitory.PersonRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
@SpringBootTest
public class PersonTest {
@Autowired
private PersonRepository personRepository;
@Test
public void test01(){
Person person = new Person();
person.setFirstname("有才");
person.setLastname("张");
Address address = new Address();
address.setCity("北京");
person.setAddress(address);
Family family = new Family();
family.setType("父亲");
family.setUsername("张三");
Family family1 = new Family();
family1.setType("母亲");
family1.setUsername("张珊珊");
ArrayList<Family> families = new ArrayList<>();
families.add(family);
families.add(family1);
person.setFamilyList(families);
Person save = personRepository.save(person);
System.out.println(save);
}
}
数据已经保存到Redis中