Java与数据库

转载自  天问雪狼

文档参考:

JPA之@Generated注解            jpa 表生成器@ TableGenerato

oracle 自增序列实现 可作为主键              Orcle 主键自增(序列sequence、触发器trigger、主键primary)

Spring data 简介          spring data jpa使用详解

Hibernate 实体类 表关系 注解 大全      Spring注解之实体类常用注解

SpringDataJpa——JpaRepository增删改查

1.id的两种增长方式 

自增主键:    mysql的auto_increment      SQLServer的identity

序列:    oracle的sequence

    自增主键是数据插入的时候自动生成主键数值

    按照序列自增,需要创建序列,将序列设为主键后,才能向表内插入数据

2.框架实现自增主键

    使用 JDBC需要拼SQL语句

    PerparedStatement不能直接存一个对象,只能把对象里面的每个字段拿出来拼到SQL里面

    引入框架hibernate,可以直接操作对象,而不是拼SQL语句了(拼SQL语句这件事hibernate已经帮你做掉了)

    java操作的是对象,数据库里面存的是实体和实体之间的关系,hibernate把这两者的关系做了一个映射,即对象(object)-关系(relationship)映射(mapping),所以hibernate或者其他类似的框架(mybatis)也叫ORM框架  

    以hibernate的API为蓝本推出的一套接口标准叫JPA(默认的实现就是hibernate)

    但是写这个JPA也不是很方便,于是spring也加入进来了,spring的作用,有人叫胶水,把各种东西整合起来让别人能更方便地使用(比如spring mvc),于是数据库操作这个部分就叫做spring data(pom.xml)


	org.springframework.boot
	spring-boot-starter-data-jpa

3.Spring data 实现自增主键步骤

实体类的配置:

    第一步:建一个实体类(比如User),给属性加上get set方法

    第二步:给类加上@Entity和@Table注解

             前者表示这是一个被jpa管理的实体类,后者表示这个实体类对应一张数据库表

    第三步:给主键对应的属性加上@Id注解

             @Id注解放在属性和get方法上面都可以,但是大部分框架找字段找的不是属性,而是get方法

    第四步:给主键列加上@GeneratedValue 和某些限制(比如非空@NotNull,这类注解都是javax.persistence包下面)

    第五步:如果有实体之间的关系,给相关的列上加关系相关的注解

             @OneToOne    @ManyToOne    @ManyToMany

public class UserBean {

	private Long id;
	private String username;
	private String password;
	private LocalDateTime registerTime;
	private UserInfoBean info;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)   //提供了主键的生成策略
	public Long getId() {
		return id;
	}

	public void setId(Long 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;
	}

	@JsonSerialize(using = LocalDateTimeSerializer.class)
	@JsonDeserialize(using = LocalDateTimeDeserializer.class)
	public LocalDateTime getRegisterTime() {
		return registerTime;
	}

	public void setRegisterTime(LocalDateTime registerTime) {
		this.registerTime = registerTime;
	}

	@OneToOne
	public UserInfoBean getInfo() {
		return info;
	}

	public void setInfo(UserInfoBean info) {
		this.info = info;
	}

}

数据库操作的配置:

    操作数据库的类称为Data Access Object(DAO)(现在依然可以这么叫,只不过实现方式变了)

    第一步:建接口XXXDAO,继承JPA提供的一些接口(比如 JpaRepository CrudRepository

    第二步:继承JpaRepository接口,它继承了其它所有接口,功能是最全的,包括增删改查,分页等等

             JpaRepository接口带泛型,有两个参数(第一个,由它负责操作的实体类,第二个,这个实体类的主键的类型)

    第三步:加上@Repository注解,springboot会自动扫描所有这种注解,然后把它加到容器里面,就可以在其他地方用这个DAO了

@Repository
public interface UserDAO extends JpaRepository {  //实体类为UserBean,主键属性为Long
}

XXXDAO使用:JPA提供的基本操作

    比如在Controller或者Service里面用@Autowired注入

    insert和update操作用的都是save方法,XXXDAO.save(XXX),执行完save之后,自动生成的主键会被填入到该对象中(如果此时主键是null,并且是自增主键,会执行insert)

就是说

user.getId() //null
userDAO.save(user);
user.getId(); //自动生成的主键
课后练习:主键是不是null,是不是自动生成的主键,什么情况是update 什么情况是insert 什么情况会报错?

    delete操作方法名就是delete

    select操作方法名是find开头,特殊的比如select count(*)方法名就是count

进阶操作:根据指定的字段查找 更新 删除

功能1:查找username是xxx的用户

    在XXXDAO接口里面加一个方法

public UserBean findByUsername(String username);   
//然后在外面直接userDAO.findByUsername("xxx")就可以了

框架会自动解析你的方法名,发现是find,就知道要做select操作;find可以换成get)

    有By关键字,就知道要加where;

    条件字段是Username,就知道是where username = xxx

功能2:符合条件查询

public UserBean findByUsernameAndPassword(String username, String password);

    生成出来的SQL语句:select xxx from xxx where username = xxx and password = xxx

    只要你的方法名符合框架指定的命名规则,它就能直接转换成SQL语句,具体规则很多

功能3:自己写SQL语句

    如果你觉得命名规则也不能满足你的需求,那么你可以自己写SQL语句

    比如: @Query注解(方法名无所谓

@Query(value = "select * from tb_user t1 left join tb_user_info t2 on t1.info_id = t2.id where t2.nickname like ?1 or t2.name like ?1", nativeQuery = true)

 nativeQuery表示原生SQL,不加的话要写JPQL,或者叫面向对象的查询语言吧

  JPQL大概是select * from UserBean u where u.id = xxx(操作的不是表而是Java对象,或者说JPA管理的Entity)


4.@GeneratedValue注解

@GeneratedValue注解有两个属性:strategy和generator

@GeneratedValue(strategy=GenerationType.TABLE , generator="TableGeneratorname")

@Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "roleSeq")
    @TableGenerator(name = "roleSeq", allocationSize = 1, table = "seq_table", pkColumnName = "seq_id", valueColumnName = "seq_count")
    public Long getId() {
  return id;
 }

@GeneratedValue(strategy=GenerationType.SEQUENCE , generator="SequenceGeneratorname")

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "menuSeq")
    @SequenceGenerator(name = "menuSeq", initialValue = 1, allocationSize = 1, sequenceName = "MENU_SEQUENCE")
    public Long getId() {
          return id;
 }

以上这两个都便于移植到各种环境

@GeneratedValue(strategy = GenerationType.IDENTITY)   只适用于有自增主键功能的数据库(MySQL)

 @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
          return id;
 }

@GeneratedValue(strategy = GenerationType.AUTO)  可以写为@GeneratedValue
以上这两个方法移植性较差

 @GeneratedValue(strategy = GenerationType.AUTO)    //或者 @GeneratedValue
 public Long getId() {
          return id;
 }



你可能感兴趣的:(java)