ssh基础概念及实战

1、Hibernate入门

1.1、理解类和表的映射关系

ORM(对象关系映射)

1.1.1、Hibernate的优点

  1. 简化了JDBC 繁琐的编码
  2. 对面向对象特性支持良好
  3. 可移植性好

1.1.2、Hibernate的缺点

  1. 不适合需要使用数据库的特定优化机制的情况
  2. 不适合大规模的批量数据处理

1.1.3、和 MyBatis的区别

/MyBatisHibernate
映射ORMSQL-Mapping对象状态管理、级联操作
/需要关注SQL的生成完全面向对象,语句与数据库无关
/灵活数据库移植性好

1.1.4、使用hibernate的步骤

  1. 下载并部署jar文件
  2. 编写hibernate配置文件
  3. 创建持久化类和映射文件
  4. 使用hibernate API
1.1.4.1、配置文件

hibernate.cfg.xml配置文件

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!--数据库URL -->
		<property name="connection.url">
		<!-- 如果用MySQL的则把oracle改掉,@127.0.0.1:也可以写localhost或者别的 ,1521是oracle的端口号,MySQL是3306-->
			jdbc:oracle:thin:@127.0.0.1:1521:orcl
		</property>
		<!--数据库用户 -->
		<property name="connection.username">scott</property>
		<!--数据库用户密码 -->
		<property name="connection.password">tiger</property>
		<!--数据库JDBC驱动 ,在安装里找jar包-->
		<property name="connection.driver_class">
			oracle.jdbc.driver.OracleDriver
		</property>
		
		<!--每个数据库都有其对应的Dialect(方言),说明白用哪种数据库,以匹配其平台特性 -->
		<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
		<!--指定当前session范围和上下文 会话是线程级的(当前会话)-->
		<property name="current_session_context_class">thread</property>
		<!--是否将运行期生成的SQL输出到日志以供调试,默认控制台 -->
		<property name="show_sql">true</property>
		<!--是否格式化SQL -->
		<property name="format_sql">true</property>
		
		<mapping resource="cn/st/hibernatedemo/entity/Department.hbm.xml"/>
	</session-factory>

</hibernate-configuration>

连接数据库的jar,到自己安装oracle里的文件夹里找
在这里插入图片描述

1.1.4.2、创建持久化类和映射文件

实体类Department.java

package cn.st.hibernatedemo.entity;
import java.io.Serializable;
public class Department implements Serializable{
	private static final long serialVersionUID = 1L;
	public Department() {
	}
	public Department(Integer deptNo, String deptName, String location) {
		super();
		this.deptNo = deptNo;
		this.deptName = deptName;
		this.location = location;
	}
	private Integer deptNo;
	private String deptName;
	private String location;
	
	public Integer getDeptNo() {
		return deptNo;
	}
	public void setDeptNo(Integer deptNo) {
		this.deptNo = deptNo;
	}
	public String getDeptName() {
		return deptName;
	}
	public void setDeptName(String deptName) {
		this.deptName = deptName;
	}
	public String getLocation() {
		return location;
	}
	public void setLocation(String location) {
		this.location = location;
	}
}

映射文件Department.hbm.xml
一个实体类对应一个实体文件

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<!-- 完整的包名和类型,table="`关联的数据库的表`” ,`波浪线`-->
    <class name="cn.st.hibernatedemo.entity.Department" table="`DEPT`">
    <!-- 类里的属性,name=“实体类的属性名”type="属性的类型" column="`对应的列`" -->
    	<id name="deptNo" type="java.lang.Integer" column="`DEPTNO`">
    	<!--生成器,assigned表示不是自动生成,要手动输入  -->
    		<generator class="assigned"/>
    	</id>
    	<property name="deptName" type="java.lang.String" column="`DNAME`"/>
    	<property name="location" type="java.lang.String" column="`LOC`"/>
    </class>
</hibernate-mapping>

注意Date类型<property name="hiredate" type="java.util.Date" column="HIREDATE"/>

然后在配置文件添加映射
修改hibernate.cfg.xml配置文件

		<mapping resource="cn/st/hibernatedemo/entity/Department.hbm.xml"/>
关于Hibernate的Generator属性的常用class
identity用于MySql数据库递增:需在建表时对主键指定为auto_increment属性
assigned:用户自定义id手动输入
native:跨数据库时使用数据库决定用何种方式

Generator子元素的一些内置生成器的快捷名字:
increment(递增):用于为long, short或者int类型生成唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。 在集群下不要使用。

1.1.4.3、使用Hibernate API实现
package cn.st.hibernatedemo.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import cn.st.hibernatedemo.entity.Department;

public class Test {

	public static void main(String[] args) {

		//关键接口和类
		//使用一次就丢,可放在局部
		Configuration conf = null;
		SessionFactory factory = null;
		Session session = null;
		//事务管理
		Transaction tx = null;
		
		try {
			//1.读取配置文件
			conf=new Configuration().configure();
			//2.创建SessionFactory 
			factory=conf.buildSessionFactory();
			//3.打开session
			session=factory.getCurrentSession();
			//4.开始一个事务
			tx=session.beginTransaction();
			
			//使用构造方法新增一条数据
//			Department dt=new Department(50,"开发","xxxx");
			//5.持久化操作
//			session.save(dt);

			//6.提交或回滚事务
			tx.commit();
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
		}
	}
}

插入成功后,控制台会出现如图下
在这里插入图片描述

1.2、掌握单表的增删改

修改

			//修改
			//先获取一条记录
			Department dt=session.get(Department.class, 50);
			dt.setDeptName("生产部");;
			session.save(dt);

删除

			Department dt=session.get(Department.class, 50);
			session.delete(dt);

1.2、掌握按主键查询

loadget
session.load(Department.class, 50);session.get(Department.class, 50);
若数据不存在,使用时抛出ObjectNotFoundException若数据不存在,返回null

1.3、理解持久化对象的状态及其转换

瞬时状态(Transient)持久状态(Persistent)游离状态(Detached)
new一个实体类对象,和数据库没有关联使用save保存,则数据库多一条记录,对象和记录关联会话结束,连接断开,但曾经关联过commit

在这里插入图片描述

1.4、脏检查与刷新缓存

  1. 当刷新缓存(调用Session的flush()方法)时,Hiberante会对Session中持久状态的对象进行检测,判断对象的数据是否发生了改变(修改)
    commit()方法会首先刷新缓存,没提交没更新,但是标记这个对象已经脏了,但是判断到缓存不是脏的,就不同步

  2. 刷新缓存就是将数据库同步为与Session缓存一致
    刷新缓存时会执行脏检查

  3. Session会在以下时间点刷新缓存
    调用Session的flush()方法
    调用Transaction的commit()方法

1.4.1更新数据的方法

update()、save方法
saveOrUpdate()方法(保存或者更新)
merge():merge方法在执行前回去缓存中找是不是有相应的记录,可以解决在一个session里有不同的两个对象但有相同标识的问题
在这里插入图片描述

2、HQL基础

2.1、Hibernate支持的查询方式

2.1.1、HQL查询(对对象的查询)

HQL是Hibernate查询语言(Hibernate Query Language)是面向对象的查询语句
区分大小写

			//1、创建hql语句,Department实体类名
			String hql="from Department";
			//String hql="from Department where deptName like '%s%'";
			//2、得到一个查询的query接口对象
			Query<Department> query = session.createQuery(hql);
			List<Department> list=query.list();
			for (Department department : list) {
				System.out.println(department.getDeptNo()+"/"+department.getDeptName());
			}

导包注意import org.hibernate.query.Query;

query.list()query.iterate()
立即执行延迟加载
List empList = query.list();Iterator empIterator = query.iterate();
在这里插入图片描述、、、、、、、、、、、、、

延迟加载:
代理对象:除了主键其余值为空
通过代理对象再查询其余的值,一条记录一条记录的查询

			Iterator<Department> it =query.iterate();
			while(it.hasNext()) {
				Department department = new Department();
				System.out.println(department.getDeptNo()+"/"+department.getDeptName());
			}	

模糊查询

			String hql="from Department where deptName like '%S%'";
			Query<Department> query = session.createQuery(hql);
			List<Department> list=query.list();
			for (Department department : list) {
				System.out.println(department.getDeptNo()+"/"+department.getDeptName());
			}

2.2、理解并使用动态参数绑定实现数据查询

2.2.1、使用字符串拼接查询条件

"from User where name = '" + name + "'"
存在各种弊端、性能低、不安全

DepartmentDao.java

List<Department> select(String deptName);

DepartmentDaoImpl.java

	@Override
	public List<Department> select(String deptName) {
		return this.currentSession().createQuery("from Department where deptName='"+deptName+"'").list();
	}

DepartmentService.java

List<Department> list(String deptName);
@Override
	public List<Department> list(String deptName) {
		Transaction tx = null;
		List<Department> list = null;
		try {
			tx=HibernateUtil.CurrentSession().beginTransaction();
			//搜索的部门名称要传递过去
			list = dao.select(deptName);
			tx.commit();
			
		} catch (Exception e) {
			tx.rollback(); 
		}
		return list;
	}

测试类

package cn.st.hibernatedemo.test;
import java.util.List;

import cn.st.hibernatedemo.entity.Department;
import cn.st.hibernatedemo.service.DepartmentService;
import cn.st.hibernatedemo.service.impl.DepartmentServiceImpl;

public class Test1 {
	public static void main(String[] args) {
		DepartmentService di = new DepartmentServiceImpl();
		List<Department> list = di.list("开发");
		for (Department department : list) {
			System.out.println(department.getDeptNo()+"、"+department.getDeptName());
		}
	}
}

在这里插入图片描述

2.2.2、使用占位符

2.2.2.1、按参数位置绑定

下标从0开始from User where name = ?
DaoImple.java

	@Override
	public List<Department> select(String deptName) {

	Query<Department> query = this.currentSession().createQuery("from Department where deptName=?0");
	query.setString(0, deptName);
	return query.list();
	}
2.2.2.2、按参数名称绑定

可读性好,易维护,推荐使用from User where name = :name

	@Override
	public List<Department> select(String deptName) {
	
	Query<Department> query = this.currentSession().createQuery("from Department where deptName=:deptName");
	//注意key值要“”
	query.setString("deptName", deptName);
	return query.list();
	}

2.2.3、为参数赋值

setXXX():针对具体数据类型setParameter():任意类型参数setProperties():专为命名参数定制
setXXX( int position, XXX value)setParameter( int position, Object value)setProperties():专为命名参数定制
setXXX( String name, XXX value)setParameter( String name, Object value)/

setParameter优点:查询语句有很多条件,但是也只需要传一个条件

	@Override
	public List<Department> select(String deptName) {
	Query<Department> query = this.currentSession().createQuery("from Department where deptName=:deptName");

	Department dept = new Department();
	dept.setDeptName(deptName);
	query.setProperties(dept);
	
	return query.list();

2.3、分页查询

Query接口的相关方法\
uniqueResult()获取唯一对象
setFirstResult()设置从第几条开始
setMaxResults()设置读取最大记录数

2.4、HQL投影查询

HQL投影查询是查询一个持久化类的一个或多个属性值,或者是通过表达式或聚合函数得到的值
对象不是持久化状态,仅用于封装结果

优点:效率更高,不需要维护对象,也不需要刷新缓存

查询结果的封装主要分三种情况
封装成Object对象List list = query.list();
封装成Object数组List<Object[]> list = query.list();
通过构造方法封装成实体类对象List list = query.list();

Object对象

			String hql = "select d.deptName,d.deptNo from Department d";
			Query query = session.createQuery(hql);
			List<Object[]> list = query.list();
			for (Object[] object : list) {
				//第一列和第二列
				System.out.println(object[0]+"\t"+object[1]);
			}

Object数组

			String hql = "select d.deptName,d.deptNo from Department d";
			Query query = session.createQuery(hql);
			List<Object[]> list = query.list();
			for (Object[] object : list) {
				//第一列和第二列
				System.out.println(object[0]+"\t"+object[1]);
			}

实体类对象
可以有不同的构造方法

			//实体类对象,但是这些对象都不是持久化对象
			String hql = "select new Department(d.deptNo,d.deptName) from Department d";
			Query query = session.createQuery(hql);
			List<Department> list = query.list();
			for (Department dept : list) {
				System.out.println(dept.getDeptNo()+"\t"+dept.getDeptName());
			}

在这里插入图片描述

3、映射

3.1、理解Hibernate的关联映射

表与表的关联关系:
单向关联、双向关联(根据主键外键来引用)

3.1.1、多对一关联

例:多个员工对应一个部门,一个部门有多个员工

在员工实体类里添加部门封装的属性和方法
注:不能两个列关联到一个属性上去,有部门对象就不能有部门编号

   private Department dept;
	public Department getDept() {
		return dept;
	}
	public void setDept(Department dept) {
		this.dept = dept;
	}

在Employee.hbm.xml添加
name是属性名,类名,对应的数据库列名

<many-to-one name="dept" class="cn.st.hibernatedemo.entity.Department" column="`DEPTNO`" />

test类

查询

	public static void main(String[] args) {
		Session session = null;
		Transaction tx = null;
		
		try {
			session = HibernateUtil.CurrentSession();
			tx = session.beginTransaction();
			
			Employee emp = session.get(Employee.class, 50);
			System.out.println(emp.getEmpName());
			
			tx.commit();
		}catch(Exception e){
			tx.rollback();
			e.printStackTrace();
		}
		HibernateUtil.factory.close();
	}

关联的添加,插入一条数据

	Department dept = new Department();
			dept.setDeptNo(10);
			Employee emp = new Employee();
			emp.setEmpNo(111);
			emp.setEmpName("kk");
			emp.setDept(dept);
			session.save(emp);

查询多条,查询属于部门编号20的所有元

		Department dept = session.get(Department.class, 20);
		Query<Employee> query = session.createQuery("from Employee where dept=:dept");	
		query.setParameter("dept", dept);
		List<Employee> list = query.list();
		for (Employee emp : list) {
	         System.out.println(emp.getDept().getDeptName()+"\t"+emp.getEmpNo()+"\t"+emp.getEmpName());
		}

优点:查询了员工,部门信息已经包含在里面
缺点:每个员工里面都包含了部门对象,查询了很多无用的数据,占据太多存储空间

3.1.2、一对多关联

//如果不new一个实例,将会空指针
	private Set<Employee> employees = new HashSet<Employee>();
	public Set<Employee> getEmployees() {
		return employees;
	}

	public void setEmployees(Set<Employee> employees) {
		this.employees = employees;
	}

Department.hbm.xml配置文件

    	<set name="employees">
    		<key column="`DEPTNO`" />
    		<one-to-many class="cn.st.hibernatedemo.entity.Employee" />
    	</set>

测试类

			Department dept = session.get(Department.class, 20);
			for (Employee emp : dept.getEmployees()) {
			System.out.println(emp.getEmpName());
		}

如果即配了多对一,又配了一对多,就是双向的一对多

3.2、级联cascade属性(级联属性)

cascade属性值/
none当Session操纵当前对象时,忽略其他关联的对象。它是cascade属性的默认值
save-update当通过Session的save()、update()及saveOrUpdate()方法来保存或更新当前对象时,级联保存所有关联的新建的瞬时状态的对象,并且级联更新所有关联的游离状态的对象
merge当通过Session的merge()方法来保存或更新当前对象时,对其关联对象也执行merge()方法
delete当通过Session的delete()方法删除当前对象时,会级联删除所有关联的对象
all包含所有的级联行为
			//级联保存
			Department dept = new Department(50,"开发部","深圳");
			Employee emp = new Employee();
			emp.setEmpName("kk");
			emp.setEmpNo(111);
			
			//双向的关联
			emp.setDept(dept);
			dept.getEmployees().add(emp);
			session.save(dept);
<set name="employees" cascade="save-update">
    		<key column="`DEPTNO`" />
    		<one-to-many class="cn.st.hibernatedemo.entity.Employee" />
</set>

级联删除

  			Department dept = session.get(Department.class, 50);
			session.delete(dept);
//也可以改成all
	<set name="employees" cascade="delete">
    		<key column="`DEPTNO`" />
    		<one-to-many class="cn.st.hibernatedemo.entity.Employee" />
    	</set>

级联更新

Department dept = session.get(Department.class, 20);
			Employee emp = session.get(Employee.class, 7369);			
			dept.setDeptName("开发部");
			
			emp.setDept(dept);
			dept.getEmployees().add(emp);
			session.update(dept);

3.3、inverse属性(维护关系控制权)

nverse属性指定了关联关系中的方向
inverse设置为false,则为主动方,由主动方负责维护关联关系,默认是false
inverse设置为true,不负责维护关联关系

通常set这边不维护关系,由对方维护

    	<set name="employees" cascade="delete" inverse="true">
    		<key column="`DEPTNO`" />
    		<one-to-many class="cn.st.hibernatedemo.entity.Employee" />
    	</set>
  1. 在建立两个对象的双向关联时,应该同时修改两个关联对象的相关属性
  2. 建议inverse设置为true

3.4、多对多映射

例:一个员工可以参加多个项目,一个项目可以有多个员工

要有一个关系表PROEMP
注:级联操作建议save-update,all或delete,删除员工同时也会删除项目

3.5、延迟加载

延迟加载(lazy load懒加载)是在真正需要数据时才执行SQL语句进行查询,避免了无谓的性能开销

多对一关联的查询策略/
类级别的查询策略true或false
一对多和多对多关联的查询策略/
延迟加载策略的设置分为延迟、延迟增强、不延迟

3.5.1、一对多和多对多关联的查询策略

lazy属性值加载策略
true(默认)延迟加载
false立即加载
extra增强延迟加载

只有执行到这个对象,如果dept..getDeptName()才会去查询这对象

Dep artment dept1 = session.load(Department.class, 50);
			System.out.println(dept1.getDeptName());

get没有调用对象也会去查询

Department dept = session.get(Department.class, 50);

如果想要取消掉延迟加载,但是又想用load方法
可以到配置文件关闭延迟加载(load默认延迟加载)

 <class name="cn.st.hibernatedemo.entity.Department" table="`DEPT`"  lazy="false">

查部门时把所有员工一起查出来
在这里插入图片描述

3.5.2、多对一关联查询策略

lazy属性值加载策略
proxy(默认)延迟加载
no-proxy无代理延迟加载
false立即加载
<many-to-one name="dept" class="cn.st.hibernatedemo.entity.Department" column="`DEPTNO`" lazy="proxy" />

4、HQL连接查询和注解

4.1、掌握Hibernate的连接查询

连接类型hql语法
内连接inner join 或 join
迫切内连接inner join fetch 或 join fetch
左外连接left outer join 或 left join
迫切左外连接left outer join fetch 或 left join fetch
右外连接right outer join 或 right join
  1. 延迟加载,返回的是数组类型
		//内连接
			String hql = "from Department d join d.employees";
			Query query = session.createQuery(hql);
			List<Object[]> list = query.list();
			for (Object[] obj : list) {
				Department dept = (Department)obj[0];
				System.out.println(dept.getDeptName());
				for (Employee emp : dept.getEmployees()) {
					System.out.println("\t"+emp.getEmpName());
				}
				System.out.println("-----------------------");
			}
  1. 立即加载,查询返回的结果是实体类型
//迫切内连接
			String hql = "select distinct d from Department d join fetch d.employees";
			Query<Department> query = session.createQuery(hql);
			List<Department> list = query.list();
			for (Department dept : list) {
				System.out.println(dept.getDeptName());
				for (Employee emp : dept.getEmployees()) {
					System.out.println("\t"+emp.getEmpName());
				}
				System.out.println("-----------------------");
			}
  1. 左外连接
    查询结果会包含没有员工的部门
			//左外连接
			String hql = "from Department d left join d.employees";
			Query query = session.createQuery(hql);
			List<Object[]> list = query.list();
			for (Object[] obj : list) {
				Department dept = (Department)obj[0];
				System.out.println(dept.getDeptName());
				for (Employee emp : dept.getEmployees()) {
					System.out.println("\t"+emp.getEmpName());
				}
				System.out.println("-----------------------");
			}
  1. 迫切左外连接
//			迫切内连接
			String hql = "select distinct d from Department d left join fetch d.employees";
			Query<Department> query = session.createQuery(hql);
			List<Department> list = query.list();
			for (Department dept : list) {
				System.out.println(dept.getDeptName());
				for (Employee emp : dept.getEmployees()) {
					System.out.println("\t"+emp.getEmpName());
				}
				System.out.println("-----------------------");
			}
  1. 右外连接
String hql = "from Department d right join d.employees";
			Query<Department> query = session.createQuery(hql);
			List<Department> list = query.list();
			for (Department dept : list) {
				System.out.println(dept.getDeptName());
				for (Employee emp : dept.getEmployees()) {
					System.out.println("\t"+emp.getEmpName());
				}
				System.out.println("-----------------------");
			}

区别

迫切不迫切
立即查询延迟加载
返回Object数组类型延返回实体类型

连接前提要求有关联
没有关联为等值连接

  1. 等值关联
    适用于两个类之间没有定义任何关联时
    在where子句中通过属性作为筛选条件

Hibernate会根据关联关系自动使用等值连接(等效于内连接)查询
允许以更加面向对象的方式编写HQL语句,更多地依据对象间的关系,而不必考虑数据库结构

//			//等值连接
			String hql = "from Department d ,Employee e where e.dept=d";
			Query query = session.createQuery(hql);
			List<Object[]> list = query.list();
			for (Object[] obj : list) {
				Department dept = (Department)obj[0];
				System.out.println(dept.getDeptName());
				for (Employee emp : dept.getEmployees()) {
					System.out.println("\t"+emp.getEmpName());
				}  
				System.out.println("-----------------------");
			}

隐式内连接

from  Emp e  where  e.dept.dname  = 'SALES'  -- 用于where子句
select empno, ename, dept.dname from Emp   -- 用于select子句

4.2、聚合函数

函数名称说明
count()统计记录条数
sum()求和
max()求最大值
min()求最小值
avg()求平均值

在这里插入图片描述

4.3、分组查询、子查询

关键字说明
all返回的所有记录
any返回的任意一条记录
some和“any”意思相同
in与“=any”意思相同
exists至少返回一条记录

大于小于(><)可以和all、any

比子查询的所有值都大
在这里插入图片描述

	String hql = "from Employee e " + 
					"where e.salary < any (select salary from Employee where job='CLERK')";
			Query<Employee> query = session.createQuery(hql);
			List<Employee> list = query.list();
			for(Employee emp : list) {
				System.out.println(emp.getEmpName());
			}

HQL提供了操作集合的函数或属性

函数或属性说明
size() 或size获取集合中元素的数目
minIndex()或minIndex对于建立了索引的集合,获得最小的索引
maxIndex()或maxIndex对于建立了索引的集合,获得最大的索引
minElement()或minElement对于包含基本类型元素的集合,获取最小值元素
maxElement()或maxElement对于包含基本类型元素的集合,获取最大值元素
elements()获取集合中的所有元素

在这里插入图片描述

4.4、查询性能优化

  1. Hibernate查询优化策略
    使用延迟加载等方式避免加载多余数据
    通过使用连接查询,配置二级缓存、查询缓存等方式减少select语句数目
    结合缓存机制,使用iterate()方法减少查询字段数及数据库访问次数
    对比list()方法和iterate()方法
  2. HQL优化
    注意避免or、not、like(避免使用前模糊)使用不当导致的索引失效
    注意避免having子句、distinct(尽量查询出结果就是没有重复的)导致的开销
    注意避免对索引字段使用函数或进行计算导致的索引失效

%a,a%(前面的确定,可以使用后模糊)

4.5、掌握注解

代替hbm.xml文件完成对象-关系映射
使用步骤如下:
使用注解配置持久化类以及对象关联关系
在Hibernate配置文件(hibernate.cfg.xml)中声明持久化类

注解含义和作用
@Entity将一个类声明为一个持久化类(实体类中加)
@Table为持久化类映射指定表
@Id声明了持久化类的标识属性(实体类的属性)
@GeneratedValue定义标识属性值的生成策略
@SequenceGenerator定义序列生产器
@Column将属性映射到列(字段)(实体列的属性中对应的列名)
@Transient将忽略这些属性

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值