JPA的使用
什么是JPA;
JPA(Java Persistence API)是将实体对象持久化到数据库中的一种规范。JPA仅仅是一种规范,也就是说JPA仅仅定义了一些接口,而接口是需要实现才能工作的。所以底层需要某种实现,而Hibernate就是实现了JPA接口的ORM框架。spirng data jpa是spring提供的一套简化JPA开发的框架,按照约定好的【方法命名规则】写dao层接口,就可以在不写接口实现的情况下,实现对数据库的访问和操作。同时提供了很多除了CRUD之外的功能,如分页、排序、复杂查询等等,底层还是使用了 Hibernate 的 JPA 技术实现。
Jpa与Jdbc的关系;
相同点:
1.都跟操作数据库有关、JPA是JDBC的升级版
2.JDBC和JPA都是一组模范接口
3.都是由SUN官方推出
不同点:
1.JDBC是由各个关系型数据库实现的,JPA是由ORM框架实现(ORM:对象关系映射)
2.JDBC使用SQL语句和数据库通信,JPA面向对象,通过ORM框架来生成SQL进行操作
3.JAP是依赖于JDBC才能操作数据库的
JPA的对象分为四个状态 分别是;
**1.**临时状态:指对象刚刚创建出来,还没有与entityManager发生关系,没有持久化,可以理解为还为与数据库进行交互
**2.**持久状态:与entityManager发生关系,操作了数据库,已经被持久化,比如:查询出来的数据,添加数据,修改的数据
**3.**删除状态:执行了remove方法但是还为提交事务
**4.**游离状态:数据提交到数据库,事务commit后,此时再对数据进行操作也不会同步到数据库
首先导入依赖;
代码如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
配置文件yml;
配置之前先加入Mysql依赖:
代码如下:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
配置好依赖以后其次配置application.yml:
代码如下:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://localhost:3306/users_test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
jpa:
show-sql: true
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL5Dialect
# dialect: org.hibernate.dialect.MySQLDialect
format_sql: true
hibernate:
ddl-auto: update
# ddl-auto: create
原则;
**1.**使用第一个注释(dialect: org.hibernate.dialect.MySQLDialect),可能会在由实体类生成数据库表的时候报错(Error executing DDL),DDL是数据定义语言(Data Definition Language),用来创建数据库表和更新数据库表结构的。
**2.**使用第二个注释(ddl-auto: create),会把数据库中的所有表和数据都删除,然后再重新创建新表,所以要慎用!使用update就安全,也会创建表,更新表结构!为了安全起见,尽量避免使用ddl-auto: create。
**3.**serverTimezone=GMT%2B8,配置的是东八区。
**4.**format_sql: true,格式化显示sql,这个也很重要,方便查看sql的执行情况
继承(Jpa)UserRepository接口
代码如下:
@Repository
public interface UserRepository extends JpaRepository<User,Integer> {
@Override
Page<User> findAll(Pageable pageable);
/*原生查询,列名和表名使用数据库中的字段和表名*/
@Query(value="select * from users where user_name like ? 1",
countQuery="select count (*) from users where user_name like ?1",nativeQuery = true)
Page<User>findByUserNameLike(String userName, Pageable pageable);
Object findByUserName(String river);
List findByUserNameEndsWith(String ver3);
ArrayList<User> findByUserNameStartsWith(String river);
List findByUserNameContains(String s);
List findByUserNameLike(String s);
ArrayList<User> findByUserNameNotIn(String[] userNames);
/*sql,列名和表名使用实体类的属性和类名,如果没有new User(),返回值List中是Object【】,而不是User实体类*/
// @Query(value="select new User (u.userName,u.password) from User u where u.userName like :userName and u.createTime >:createTime")
// List<User>findByUserNameLikeAndCreaTimeGreaterThan(@Param("userName")String userName, @Param("createTime")Date createTime);
}
原则:
1、JpaRepository<User,Integer>中,User是数据库对象的实体类,Integer是数据表的主键类型。
2、UserName为字段名,查询的时候,只要函数的命名符合jpa的规则,则不需要实现的方法体,这里是列举的几个常用的查询。
3、jpa实现分页的方式是使用Pageable接口。
4、可以使用原生查询和hql语句查询。其中hql中,需要注意的是new User(),描述在注释中写了。
创建一个(User)实体类;
代码如下:
@Entity
@Table(name = "userd")
public class User {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name="id")
private int id;
@Column(name="name")
private String username;
@Column(name="password")
private String password;
@Column(name="create_time")
private Date createTime;
@Column(name="update_time")
private Date updateTime;
public User(String username, String password) {
this.username = username;
this.password = password;
}
public User(){
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}
编写测试类:DemoApplicationTests;
代码如下:
@SpringBootTest
class DemoApplicationTests {
@Autowired
private UserRepository userRepository;
private final static Logger log= LoggerFactory.getLogger(DemoApplicationTests.class);
@Test
void save() {
User user = new User("river","123456");
User user1 = userRepository.save(user);
log.info("id:{},userName:{},password:{}",user1.getId(),user1.getUsername(),user1.getPassword());
}
@Test
void findByUserName(){
User user = (User) userRepository.findByUserName("river");
assertNotEquals(user,null);
log.info(user.getPassword());
}
@Test
void update(){
User user= (User) userRepository.findByUserName("river");
user.setPassword("123456");
userRepository.save(user);
assertNotEquals(user,null);
log.info(user.getPassword());
}
@Test
void findByUserNameEndsWith(){
List userList = userRepository.findByUserNameEndsWith("ver3");
assertNotEquals(userList.size(),1);
}
@Test
void findByUserNameStartsWitgh(){
ArrayList<User> userList = userRepository.findByUserNameStartsWith("river");
assertNotEquals(userList.size(),0);
log.info(userList.get(0).getPassword());
}
@Test
void findByUserNameContains(){
List userList=userRepository.findByUserNameContains("3");
assertNotEquals(userList.size(),1);
//log.info(userList.get(0).getpassowrd());
}
@Test
void findByUserNameLike() {
List userList = (List) userRepository.findByUserNameLike("river%");
assertNotEquals(userList.size(), 0);
log.info("size:{}",userList.size());
userList = userRepository.findByUserNameLike("river_");
assertNotEquals(userList.size(), 0);
log.info("size:{}",userList.size());
}
说明:
1、save()方法,返回的User对象中,id是为0的。除非配置了@GeneratedValue。
2、createTime是不需要赋值的。配置数据库的时候,设置默认值为:CURRENT_TIMESTAMP。还需要在User实体类加上@DynamicInsert注解,这样插入的时候createTime就会被自动赋值。
3、updateTime也是不需要赋值的。设计数据表的使用,手动建表的话:update_time
timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP。如果是使用Navicat设计表的话,勾选“根据当前时间戳更新”。还需要在在User实体类加上@DynamicUpdate注解,这样当数据更新的时候,时间会自动更新到数据库中。
一堆报错还未解决 后续尽快待完成 !!!!!
使用:---------:
居中
使用:----------
居左
使用----------:
居右
第一列 | 第二列 | 第三列 |
---|---|---|
第一列文本居中 | 第二列文本居右 | 第三列文本居左 |
SmartyPants
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:
TYPE | ASCII | HTML |
---|---|---|
Single backticks | 'Isn't this fun?' | ‘Isn’t this fun?’ |
Quotes | "Isn't this fun?" | “Isn’t this fun?” |
Dashes | -- is en-dash, --- is em-dash | – is en-dash, — is em-dash |
创建一个自定义列表
-
Markdown
- Text-to- HTML conversion tool Authors
- John
- Luke
如何创建一个注脚
一个具有注脚的文本。1
注释也是必不可少的
Markdown将文本转换为 HTML。
KaTeX数学公式
您可以使用渲染LaTeX数学表达式 KaTeX:
Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n−1)!∀n∈N 是通过欧拉积分
Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=∫0∞tz−1e−tdt.
你可以找到更多关于的信息 LaTeX 数学表达式here.
新的甘特图功能,丰富你的文章
- 关于 甘特图 语法,参考 这儿,
UML 图表
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:
这将产生一个流程图。:
- 关于 Mermaid 语法,参考 这儿,
FLowchart流程图
我们依旧会支持flowchart的流程图:
- 关于 Flowchart流程图 语法,参考 这儿.
导出与导入
导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。
导入
如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。
注脚的解释 ↩︎