《Spring Boot2+Thymeleaf企业实战》读书笔记——数据库实战

不贴代码,仅作思路与要点记录,如果因为标题或关键词而点进来想要看代码解决实际问题的,建议右上角点× orz
以前老觉得应该看代码照抄代码,把代码找个地方复制粘贴保存起来以后需要的时候就Ctrl F一下就万事大吉,后来发现我不仅记不住原理和实际该怎么写,我连那些保存起来的代码放哪里了都不知道……于是就有了这个笔记。上次写笔记还是去年……想来我是生信既没学会多少,本职也给丢了个干净。这不太行,不,是很不行。

对应章节为《Spring Boot2+Thymeleaf企业实战》中第12章:数据库实战。
本章要点为:

  1. 介绍Spring Data
  2. Spring Data与JPA
  3. Spring Data与MongoDB
  4. Spring Data与Redis

以下为正经笔记

Spring Data 概述及其功能

为数据访问提供一个通用的模型,使不同类型的数据库可以通过同样的方式来访问和操作。在MVC三层架构里,直接对接的使DAO层,为其提供统一的数据访问模型。
它的功能主要是以下几个:

  1. 提供数据与对象映射的抽象层,同一个对象可以被映射成不同数据库的数据;
  2. 根据数据存储接口的方法名,自动实现数据查询;
  3. 为各个领域模型提供最基本的实现,例如普通的增删改查;
  4. 可在原有逻辑的基础上,实现自定义的数据库操作逻辑。

Spring Data 与JPA访问Mysql

大致步骤如下:

  1. 在pom.xml中引入spring-boot-starter-data-jpa的模块;
  2. 新建application.yml配置文件,以树形结构写入server/port,spring/datasource/driver-class-name、url、username、password等信息;
  3. 创建和表结构对应的实体类,使用 @Entity 注解和 @Table(name=“表名”) 注解。对id主键使用 @Id 和 @GeneratedValue(strategy=GenerationType.IDENTITY) 两个注解,getter和setter不要忘记生成;
  4. 新建一个接口继承JpaRepository<类名, Integer>;
  5. 新建一个Serveice业务逻辑类,在其中用 @Autowrited 注入前一步建立的接口;
  6. 写各种接口,比如get一个列表,就用这个注入的接口.findAll(),要保存数据就.save(对象);

到这一步,能实现都是因为Spring自动为这个继承了JpaRepository的接口生成了代理类,默认使用JDK动态代理。findAll()之类的都是原有的方法,这些自带的可以找文档查一查,或者这本书的这个章节里就有对应表格,在此不赘述。
如果要实现自己特殊的逻辑,就要按以下步骤:

  1. 新建一个接口,写一个任意命名的方法;
  2. 新建一个接口实现类,实现这个接口,并声明一个 EntityManager 类,给它加上 @PersistenceContext 注解;
  3. 在这个实现类里,重写接口里的方法,使用那个声明好的EntityManager实例,调用其createQuery(“sql语句里from及后面的部分”);
  4. 第三步执行出来的是Query对象,调用这个对象的getResultList()才是最终需要的结果。

这一步是以实现接口的方式完成的,所以对spring来说,他的自动扫描的就是被继承的接口名加上Impl后缀,如果扫描不到这样命名的类,就会将接口接口里的方法当作被查询表里的字段,然后就会喜闻乐见地报错。所以命名方式一定要遵守规则

同理,如果想根据任意一个字段做 from table where name= 这样的查询,可直接在接口里写一个与要查询字段同名的方法。甚至可以直接带一些and或者between之类的关键字做查找。这个也是有表格可循。估计在eclipse和IDEA这样的IDE里都会有提示吧。

再如果,以上仍不能满足需求——而这是经常发生的——那么就要用到 @Query 注解。用法是在接口方法上加 @Query(“sql句子”)
其中,变量以?代替,还要加上序号,如 @Query(“select p from Person p where p.name = ?1”) 此时该方法里这个name是第一个参数。书上说,该注解也支持原生的SQL查询,举例是 @Query(value = “SELECT * FROM CRA_PERSON WHERE NAME = ?1”, nativeQuery = true) 。两个句子有点小区别,不过私以为实体类一开始就设置为与表名一致就可以避免记混。

Spring Data 与 MongoDB

书里讲的很细致,从MongoDB的历史到安装流程,这里就不赘述了,后面可能会找一些靠谱的安装博客贴个链接过来做备注。
MongDB的一些概念和MySQL还是有不小的区别的,下面做一些记录:
database:数据库,这个与SQL相同;
collection:数据集合,相当于SQL的数据表table;
document:数据文档,详单与SQL的一条数据;
filed:数据域,可看作SQL的列column;
index:数据索引。
使用步骤如下:

  1. 在pom.xml文件中引入spring-boot-starter-data-mongdb
  2. 新建application.yml文件,写各种配置,和MySQL的配置写法差不多,url换成uri,不需要username和password
  3. 在实体类中使用 @Document(collection = “表名”) 的注解,主键使用@Id
  4. 新建接口继承MongoRepository<表名, String>
  5. 创建service业务逻辑类,注入新建的接口,调用的方法如 findAll() 等,与MySQL一致

同样的上面只是最基础的应用,若要自定义数据存储逻辑,步骤如下:

  1. 新建一个接q’r’wo’ripe’r’pure’o’q’e’o’i口,写一个自定义方法;
  2. 新建一个service业务逻辑类,实现第一步的接口,注入一个MongoTemplate对象;
  3. 重写该方法。
    这个重写略复杂,这里直接贴一下抄下来的代码
public class PersonRepImpl implements PersonRepCustom{
   
	@Autowrited
	private MongoTemplate mongoTemplate;
	public List<Person> myQuery(){
   
		List<Person> datas = mongoTemplate.execute(Person.class,
			new CollectionCallback<List<Person>>(){
   
				public List<Person> doInCollection(MongoCollection collection)throws MongoException, DataAccessException{
   
					//查询全部数据
					FindIterable fi = collection.find();
					MongoCursor<Document> cursor = fi.iterator();
					List<Person> result = new ArrayList<Person>();
					while (cursor.hasNext()){
   
						//获取源数据实例
						Document source = cursor.next();
						//转换为Person
						Person p = new Person();
						ObjectId objectId = (ObjectId)source.get("_Id");
						p.setId(objectId.toHexString());
						p.setAge((Integer)source.get("age"));
						p.setName((String)source.get("name"));
						p.setCompany((String)source.get("company"));
						result.add(p)
					}
					return result;
				}
			});
		return datas;
	}
}

书里对这一段的解释是这样的:

在自定义的 myQuery 方法中,使用 MongoTemplate 来执行数据查询。在调用 execute 方法时,实现一个 CollectionCallback 接口,这样的使用方式,接触过 Spring 和 Hibernate 的读者应该非常熟悉。在实现 CollectionCallback 接口时,使用 MongoDB 的 MongoCollection 对象进行数据查询,本例查询 MongoCollection 的全部数据,并封装为 Person 集合返回。

MongoDB模块同样支持 findByAgeLessThan(Integer age) 这样的方法名查询方法,关键字也都可自行查询资料。

需要注意的是,MongolianDB有自己独特的查询操作符,如$gt等,这些可以查阅MongolianDB文档进行了解。

使用 @Query 注解来定义查询条件时,可参考以下两段代码,需要注意的是,这里的 @Query 注解与 JPA 的 @Query 注解是完全不同的两个东西,务必区分开。

@Query("{ 'name' : ?0, 'age' : ?1}")
List<Person> finByNameAndAge(String name, Integer age);

//这里为@Query注解添加了fileds字段,表示最终查询出来的Person只有id、name、company属性,其他的属性值为null
@Query(value = "{'name' : ?0}", fileds = "{'name':1,'company':1}")
List<Person> findByName(String name);

Spring Data 与 Redis

Redis,大名鼎鼎,就不多介绍了。安装步骤同样省略。
Redis 的数据类型这里记录一下。
string:最基本的数据类型,可保存任何数据;
hash:一个键值对的集合,在集合中以字段名作为key,字段值作为value,主要用于保存对象;
list:字符串列表,可以往列表中添加元素;
set:无序的集合,集合内数据不能重复;
zset:有序的集合,集合内数据不能重复。
在进行数据存储时要注意使用的数据类型,例如保存时用的hash类型,则获取数据时也要使用hash类型。
如果需要保存一些不会重复的数据,例如UUID,使用set类型来保存会比较理想,如果保存的是 java 对象,使用hash类型保存比较合适。Spring Data 默认使用 Jedis 来操作 Redis 。

下面先记录的是 Jedis 如何使用 hash 和 set 类型的数据。

  1. 引入Jedis依赖:groupId=redis.client,artifactId=jedis;
  2. 分别读写 hash 和 set 类型的数据
public class JetisTest(){
   
	public static void main(String[] args){
   
		//登录本地Redis
		Jedis jedis = new Jedis("localhost");
		jedis.auth("123456");
		//将数据保存为hash类型;
		Map<String,String> data = new HashMap<String,String>();
		data.put("name","Angus");
		data.put("age","33");
		data.put("company","crazyit");
		jedis.hmset("person_test",data);
		//查询hash类型的数据
		List<String> dbDatas = jesid.hmget("person_test","name","age");
		for(String dbData : dbDatas){
   
			System.out.println(dbData);
		}
		
		//将数据保存为set类型
		jedis.sadd("person_test_ids","1","2");
		//查询数据
		Set<String> dbDataSet = jedis.smembers("person_test_ids");
		for(String dbData : dbDataSet){
   
			Sytem.out.println(dbData);
		}
	}
}

Spring Boot 同样提供了 Spring Data 与 Redis的依赖。使用步骤如下:

  1. 在pom文件中引入 spring-boot-starter-data-redis;
  2. 新建application.yml文件,配置 server/port 、 spring/redis/port、password、host(可改用 url:redis://ignore:123456@localhost:6379 的写法);
  3. 为项目建立controller、repository、service、entity包;
  4. 实体类中,在类外面加 @RedisHash(“类名”),这样就可以使这个类对象以 hash 类型被保存。对主键ID使用 @Id 注解,其会作为set类型被保存;对索引字段使用 @Indexed 注解;
  5. 接口与实现类的与前面 MySQL 和 Mongodb 的基本相同。不同的在于查询返回的对象是 Iterable 实例,需要便利后存到 List 中。
  6. 自定义数据存储逻辑也与前二者大同小异。
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务