NoteBook / Spring Boot基础(4)

  1. JPA/Hibernate/Spring Data JPA概念
  2. Spring Data JPA访问数据库
  3. Spring Data Jdbc Template访问数据库
  4. Spring Boot集成MyBatis

Java访问数据库经历了几个阶段:

直接通过JDBC访问----ORM框架(如MyBatis、Hibernate)----Spring Data JPA(默认通过Hibernate实现)

  • JPA/Hibernate/Spring Data JPA概念

ORM:Object/Relation Mapping,对象/关系型数据库映射,完成面向对象的编程语言到关系型数据库的映射,可以把ORM当成应用程序和数据库的桥梁

最终面向对象数据库会取代关系型数据库,但是关系型数据库系统的某些优势是面向对象语言目前无法比拟的

只要依然采用面向对象程序设计语言,底层依然采用关系型数据库,中间就少不了ORM工具

ORM工具的唯一作用:把持久化对象的保存、修改、删除等操作,转换成对数据库的操作

ORM工具提供了持久化类数据表之间的映射关系:

数据表-映射-类:持久化类被映射到一个数据表

数据表的行-映射-对象(即实例):每个持久化对象对应数据表的一行记录

数据表的列(字段)-映射-对象的属性

CRUD:

create:增加、retrieve:读取、update:更新、delete:删除

流行的ORM框架:

持久化(Persistence):把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)

持久化的主要应用:将内存中的对象存储在数据库中,或者存储在磁盘文件、XML数据文件中等,JDBC就是一种持久化机制

JPA:Java Persistence API,官方提出的Java持久化规范

JPA的主要实现有:Hibernate、EclipseLink、OpenJPA等,遵循此规范设计

Spring Data:Spring的一个子项目,用于简化数据库访问

Spring Data JPA:Spring Data框架中的一个模块,为了简化JPA的写法


  • Spring Data JPA访问数据库

Spring Data:提供了访问操作数据的统一规范,该规范约束了对于关系型和非关系型数据库操作的统一标准,主要包含CRUD(增加、查询、修改、删除)操作、相关参数查询、分页操作、排序操作等

Spring Data通过提供Repository接口来约定数据访问的统一标准,包含如下常用子接口:

CrudRepository、PagingAndSortingRepository、JpaRepository

CrudRepository:提供最基本的对实体类的增删改查操作

1、修改pom.xml文件

//添加MySQL依赖
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
//添加Spring Data JPA依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

spring-boot-starter-data-jpa是Spring Boot项目访问数据库的核心依赖配置

2、在application.properties中配置数据源和JPA相关属性

//数据源信息配置
spring.datasource.url = jdbc:mysql://localhost:3306/springdatajpa
spring.datasource.username = root
spring.datasource.password = ****
spring.datasource.driverClassName = com.mysql.jdbc.Driver
……
//JPA持久化配置
spring.jpa.database = MySQL
#如果数据库中存在持久化类对应的表就不创建,不存在就创建对应的表
spring.jpa.hibernate.ddl-auto = update
……

3、创建持久化类User

新建4个包:bean(放置持久类)、controller(控制器)、repository(定义数据访问接口的包)、service(业务逻辑处理类)

@Entity:用于标记持久化类

@Id:指定主键

@GeneratedValue(strategy=GenerationType.IDENTITY):指定主键的生成策略,MySQL默认为自增长

4、定义数据访问层接口

public interface UserRepository extends CrudRepository<User,Integer>

第一个参数User:持久化对象,第二个参数Integer:指定ID的类型为整型

5、定义业务层

@Service

public class UserService {......}

//注入接口类UserRepository,将接口对应的实现类注入进来

@Resource

private UserRepository userRepository;

使用@Transaction进行事务的绑定:save、update、delete方法需要绑定事务

6、定义控制器类

在controller包下新建一个控制器类:UserController.java

@RestController

@RequestMapping("/user")

//注入UserService

@Resource

private UserService userService;

getAll()返回的是JSON格式的字符串

PagingAndSortingRepository:继承自CrudRepository接口,除了CrudRepository接口的功能之外,还提供了分页与排序功能

1、修改pom.xml文件(与CrudRepository接口访问数据相同)

2、在application.properties中配置数据源和JPA相关属性(与CrudRepository接口访问数据相同)

3、创建持久化类Article

4、定义数据访问层接口

public interface ArticleRepository extends PagingAndSortingRepository<Article,Integer>

5、定义业务层

@Service

public class ArticleService {......}

@Resource

private ArticleRepository articleRepository;

6、定义控制器类

在controller包下新建一个控制器类:ArticleController.java

@RestController

@RequestMapping("/article")

//注入ArticleService

@Resource

private ArticleService articleService;

//根据id进行降序
Sort sort = new Sort(Sort.Direction.DESC,”id”);
//参数1:当前查询的是第几页,默认从0开始,0表示第1页
//参数2:每页展示多少数据
//参数3:封装排序对象
Pageable page = PageRequest.of(pageIndex-1,2,sort);
//分页
Page<Article> articleDatas = articleService.findAll(page);

http://127.0.0.1:8080/article/pager?pageIndex=1

数据以JSON格式返回浏览器

JpaRepository:继承了PagingAndSortingRepository接口,极大地减少了JPA作为数据访问的代码,是实现Spring Data JPA技术访问数据库的关键接口

①简单条件查询

查询的方法名称必须以find、get、read开头,条件属性的首字母必须大写

定义数据访问层接口StudentRepository

public interface StudentRepository extends JpaRepository<Student,Integer>{
    Student findByName(String name);
    List<Student> findByNameAndAddress(String name,String address);
    List<Student> findByNameLike(String name);
}

因为by是条件关键字,而name是条件属性,条件关键字和条件属性的首字母必须大写,所以上述方法名的定义即findByName

定义业务层StudentService

@Resource
private StudentRepository studentRepository;

@Transactional
public void saveAll(List<Student> students){
    studentRepository.saveAll(students);
}

public List<Student> getStusByNameLike(String name){
    return studentRepository.findByNameLike(“%”+name+”%”);
}
②关联查询和@Query查询

对于两个有关联关系的对象的查询,可以通过方法名中的“_”下划线来标识,Spring Data JPA还支持用@Query注解定义在数据访问层接口的方法上实现查询

创建持久化类Student.java和Clazz.java

Student.java:
//学生与班级是多对一的关系,这里配置的是双向关联
@ManyToOne(fetch=FetchType.LAZY,targetEntity=Clazz.class)
@JoinColumn(name=“clazzId”,referencedColumnName=“code”)
private Clazz clazz;

Clazz.java:
//班级与学生是一对多
@OneToMany(fetch=FetchType.LAZY,targetEntity=Student.class,mappedBy=“clazz”)
private Set<Student> students=new HashSet<>();

定义数据访问层接口ClazzRepository、StudentRepository

public interface ClazzRepository extends JpaRepository<Clazz,Integer>

public interface StudentRepository extends JpaRepository<Student,Integer>{
    List<Student> findByClazz_name(String clazzName);

    //Query写法,?1此处使用的是参数的位置,代表的是第一个参数
    @Query(“select s from Student s where s.clazz.name=?1”)
    List<Student> findStudentsByClazzName(String clazzName);
    
    //上面的方法用的是参数的位置来查询,Spring Data JPA中还支持用名称来匹配查询,使用格式“:参数名称”引用
    @Query(“select s.name from Student s where s.clazz.name=:clazzName and s.sex=:sex”)
    List<Student> findNameByClazzNameAndSex(@Param(“clazzName”) String clazzName,@Param(“sex”) char sex);

    //删除
    @Modifying
    @Query(“delete from Student s where s.name=?1”)
    int deleteStuByStuName(String stuName);
}

List<Student> findByClazz_name(String clazzName):是关联查询的方法,关联的属性可以用下划线“_”连接

@Query注解中可以直接定义JPQL语句进行数据的访问操作

返回多个字段:返回List<Map<String,Object>>对象

@Param注解用于声明参数的名称

Spring Data JPA支持使用@Modifying和@Query注解组合更新查询操作

③@NamedQuery查询

Spring Data JPA支持使用JPA的NameQuery定义查询操作,即一个名称映射一个查询语句

在Student.java中定义NameQuery查询

@NamedQuery(name=“Student.findStudentsByClazzName”,query=“select s from Student s where s.clazz.name=?1")

NameQuery语句应该放到要查询的实体上,并且名称是“实体的类名.方法名称”

定义数据访问层接口StudentRepository

public interface StudentRepository extends JpaRepository<Student,Integer>{
    List<Student> findStudentsByClazzName(String clazzName);
}

④Specification查询

JPA允许基于Criteria对象进行按条件查询,Specification接口封装了JPA的Criteria查询条件

public interface Specification<T>{
    Predicate toPredicate(Root<T> root,CriteriaQuery<?> query,CriteriaBuilder cb);
}

Specification接口提供了一个toPredicate方法用来构造查询条件,注意:如果自己定义的数据访问层接口希望使用Specification接口的规范,则必须实现JpaSpecificationExecutor接口

JpaSpecificationExecutor接口的源代码:略

定义数据访问层接口ClazzRepository、StudentRepository

public interface ClazzRepository extends JpaRepository<Clazz,Integer>,JpaSpecificationExecutor<Clazz>{}

public interface StudentRepository extends JpaRepository<Student,Integer>,JpaSpecificationExecutor<Student>{}

定义业务层类SchoolService.java

@SuppressWarnings(“serial”)
public List<Map<String,Object>> getStusBySex(char sex){
    List<Student> students=studentRepository.findAll(new Specification<Student>(){
        @Override
        public Predicate toPredicate(Root<Student> root,CriteriaQuery<?> query,CriteriaBuilder cb){
            Predicate p1=cb.equal(root.get(“sex”),sex);
            return p1;
        }        
    });
}

root.get(“sex”)表示获取sex这个字段名称,equal表示执行equal查询

封装多个查询条件:

List<Predicate> predicates = new ArrayList<Predicate>();

Root.join(“clazz”,JoinType.INNER);
Path<String> clazzName = root.get(“clazz”).get(“name”);

return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();

分页查询:

PageRequest.of(pageIndex-1,pageSize,sort)

定义分页的页面数据对象PageData.java

private List<Map<String,Object>> stuDatas = new ArrayList<>();

  • Spring Data Jdbc Template访问数据库

Jdbc Template:JDBC模板,为不同类型的JDBC操作提供模板方法,在Maven配置文件中,需要增加spring-boot-starter-jdbc模块

1、在pom.xml文件中增加依赖:

spring-boot-starter-web

spring-boot-starter-thymeleaf

mysql-connector-java

spring-boot-starter-jdbc

2、定义数据访问层接口UserRepository.java:

@Repository   //标注这是一个持久化操作对象

public class UserRepository {......}

@Resource

private JdbcTemplate jdbcTemplate;  //注入JdbcTemplate模板对象

String sql = “insert into tb_user(login_time,username,password) values (?,?,?),(?,?,?),(?,?,?)”
Object[] args = new Object[]{“swk”,”孙悟空”,”123456”,“zbj”,”猪八戒”,”123456”,“tsz”,”唐三藏”,”123456”}

return jdbcTemplate.update(sql,args);  //参数1:插入数据的SQL语句,参数2:对应SQL语句中占位符?的参数

定义一个RowMapper:

RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class);

执行查询方法:

User user = jdbcTemplate.queryForObject(sql,new Object[] {username},rowMapper);

UserRepository类需要通过@Repository注解声明这是一个数据访问层对象,这样在业务层就可以通过注解注入UserRepository对象了

数据库中创建tb_user表:

id INT PRIMARY KEY AUTO_INCREMENT   //主键,自增长


  • Spring Boot集成MyBatis

MyBatis是一个数据持久层(ORM)框架,在实体类和SQL语句之间建立了映射关系

1、在pom.xml文件中增加依赖:

spring-boot-starter-web

spring-boot-starter-thymeleaf

mysql-connector-java

mybatis-spring-boot-starter

2、定义数据访问层接口UserRepository.java:

public interface UserRepository {......}

@Insert (“insert into tb_user(login_name,username,password) values (#{loginName},#{username},#{password})”)
public int insertUser(User user);

@Select("select * from tb_user where username = #{username}")

@ResultMap("userResult")  //引用id="userResult"的@Results

public User selectByUsername(@Param("username") String username);

@Results用于映射对象属性和数据库列,常用于对象属性和数据库列不同名的情况

数据插入成功以后,MyBatis框架会将插入成功的数据主键存入user对象

3、启动类中指定数据访问层接口的包名

@MapperScan("org.fkit.springbootmybatistest.repository")  //该注解的参数是一个包名字符串

发布了20 篇原创文章 · 获赞 1 · 访问量 4898

猜你喜欢

转载自blog.csdn.net/piaoken5588/article/details/104741635
今日推荐