SpringBoot 学习记录(三): jpa

来源:互联网 发布:淘宝客服的链接在哪里 编辑:程序博客网 时间:2024/05/16 18:05

上篇学习了mybaits的使用,既可以通过注解方式实现,也可以使用常见的xml配置方式实现

这篇我们继续学习数据库访问层jpa,集各家所长,各取所需吧

一,第一步当然还是引入相关依赖包,在pom.xml中继续添加:

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-data-jpa</artifactId></dependency>
二,jpa底层是由Hibernate来实现的,需要在application.properties中添加相关配置
#jpaspring.jpa.properties.hibernate.hbm2ddl.auto=updatespring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialectspring.jpa.show-sql= truespring.jackson.serialization.indent_output=true
这里说明一下:
hibernate.hbm2ddl.auto参数的作用主要用于:自动创建|更新|验证数据库表结构,有四个值:create: 每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。create-drop :每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。update:最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据 model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等 应用第一次运行起来后才会。validate :每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值另外新建sql脚本,命名schema.sql,并放在classpath下面,那么在应用启动的时候会在结束前读取脚本,执行命令
三,测试,我们新建实体类UserInfo,启动查看是否自动创建了table
package com.example.entity;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.Table;import javax.persistence.Transient;@Entity@Table(name="user_info")public class UserInfo {@Id@GeneratedValueprivate long id;private String name;private String gender;/** 不映射成数据表 */@Transientprivate String status;public long getId() {return id;}public void setId(long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getStatus() {return status;}public void setStatus(String status) {this.status = status;}}

四,启动查看,数据库创建了空的table,user_info

五,加入schema.sql脚本,重新启动

insert into user_info (name,gender) values('initname','M');

再查看数据库,此时已成功插入一条初始化数据,这里需要注意两点:

1,开始我引入的spring-boot-starter-parent版本是1.3.8的,前面都没问题,

引入jpa后项目就报错了,查看本地仓库,依赖包也下载下来了,不知道什么原因,

于是更改parent版本为1.3.6,成功启动

2,执行schema.sql脚本,前提是已经创建好了table,自动创建table是应用第一次启动结束后才会创建

而读取脚本文件是在应用启动结束前,如果没有创建table就加入脚本文件,会找不到table报错,另外每次重启都会执行一次。

六,创建UserInfoRepository 继承Repository接口,基本方法已经有实现,继承后能直接使用

这也是使用jpa的便利之处:

package com.example.repository;import org.springframework.data.jpa.repository.JpaRepository;import com.example.entity.UserInfo;public interface UserInfoRepository extends JpaRepository<UserInfo, Long>{}

七,创建UserController,这里简化了代码,没有使用service层,仅供测试用

package com.example.controller;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;import com.example.entity.UserInfo;import com.example.repository.UserInfoRepository;@RestControllerpublic class UserController {@Autowiredprivate UserInfoRepository userRepository;@RequestMapping(value="/user/save",method=RequestMethod.GET)public void save(){UserInfo user = new UserInfo();user.setGender("F");user.setName("wendy");userRepository.save(user);}}
八,查看控制台打印sql语句:
2017-04-07 17:09:01.728  INFO 516 --- [nio-8088-exec-1] o.a.c.c.C.[.[localhost].[/spring-boot]   : Initializing Spring FrameworkServlet 'dispatcherServlet'2017-04-07 17:09:01.729  INFO 516 --- [nio-8088-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started2017-04-07 17:09:01.761  INFO 516 --- [nio-8088-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 32 msHibernate: insert into user_info (gender, name) values (?, ?)
九,除了封装好的方法,我们也可以自定义查询,jpa会根据方法名自动创建sql语句

如,在UserInfoRepository中添加方法:

package com.example.repository;import org.springframework.data.jpa.repository.JpaRepository;import com.example.entity.UserInfo;public interface UserInfoRepository extends JpaRepository<UserInfo, Long>{UserInfo findById(long id);UserInfo findByName(String name);}
在UserController中新增测试方法:
@RequestMapping(value="/user/id",method=RequestMethod.GET)public UserInfo findById(long id){return userRepository.findById(id);}@RequestMapping(value="/user/name",method=RequestMethod.GET)public UserInfo findByName(String name){return userRepository.findByName(name);}

测试返回结果如下:


再查看控制台打印的sql语句:

Hibernate: select userinfo0_.id as id1_0_, userinfo0_.gender as gender2_0_, userinfo0_.name as name3_0_ from user_info userinfo0_ where userinfo0_.id=?Hibernate: select userinfo0_.id as id1_0_, userinfo0_.gender as gender2_0_, userinfo0_.name as name3_0_ from user_info userinfo0_ where userinfo0_.name=?

十,很多时候我们需要根据业务需求写sql语句,下面我们来看如何使用注解写sql语句

如,在UserInfoRepository中添加方法:

/** * 自定义查询语句 * @param id * @return */@Query("select gender from UserInfo where id=?1")String userGender(long id);/** * 自定义更新语句 * @param firstname * @param lastname * @return */@Transactional@Modifying @Query("update UserInfo set name =:name where id =:id")int updateName(@Param("name")String name,@Param("id")Long id);
这里需要注意:

1,查询表名UserInfo对应的是实体类名,不是数据库表名

2,更新数据库操作,需要添加事务注解@Transactional,否则会报错:

javax.persistence.TransactionRequiredException
3,其他用法可以参见博客:http://jishiweili.iteye.com/blog/2088265

在UserController中新增测试方法:

/** * 使用注解写查询语句 * @param id * @return */@RequestMapping(value="/gender",method=RequestMethod.GET)public String getGender(long id){return userRepository.userGender(id);}/** * 使用注解生成自定义方法 * @param id * @return */@RequestMapping(value="/update",method=RequestMethod.POST)public String update(@RequestBody UserInfo userInfo){String name = userInfo.getName();Long id = userInfo.getId();int count = userRepository.updateName(name,id);return "成功更新"+count+"条数据";}

启动测试:

http://localhost:8088/spring-boot/gender?id=1 ========== 返回结果:M

http://localhost:8088/spring-boot/update === params:{"name":"acc","id":"2"} ======= 返回结果:成功更新1条数据


===============================================================================================

jpa的使用就初步演示到这里,下篇我们继续学习日志框架,SpringBoot 学习记录(四): slf4j+logback



















0 0
原创粉丝点击