03.Hibernate一对多关联
前言:在域模型中,类与类之间最普遍的关系就是关联关系,在UML语言中关联关系是有方向的。在数据库中表与表之间也会有关联关系,本节介绍通过Hibernate映射一对多的关联关系,这是一种最普遍的关联关系。
1.数据库表的一对多关联关系
CREATE TABLE tb_class
(
id bigint NOT NULL auto_increment COMMENT 'ID',
no varchar(10) NOT NULL COMMENT '班级编号',
name varchar(50) NOT NULL COMMENT '班级名称',
PRIMARY KEY (id)
) COMMENT '班级信息表';
CREATE TABLE tb_student
(
id bigint NOT NULL auto_increment COMMENT 'ID',
no varchar(10) NOT NULL COMMENT '学号',
name varchar(50) NOT NULL COMMENT '姓名',
sex char(1) NOT NULL COMMENT '性别',
birthday datetime COMMENT '出生日期',
class_id bigint NOT NULL COMMENT '班级ID',
PRIMARY KEY (id)
) COMMENT = '学生信息表';
ALTER TABLE tb_student ADD CONSTRAINT fk_tb_student_tb_class_1 FOREIGN KEY (class_id) REFERENCES tb_class (id);
package model;
public class ClassInfo
{
private Long id;
private String no;
private String name;
private List<Student> students = new ArrayList<Student>();
//省略setter、getter、toString...
}
package model;
import java.sql.Date;
public class Student
{
private Long id;
private String no;
private String name;
private String sex;
private Date birthday;
private ClassInfo classInfo;
//省略setter、getter、toString...
}
2.建立多对一的单向关联关系
- <hibernate-mapping package="model">
<class name="ClassInfo" table="tb_class">
<id name="id">
<generator class="native"></generator>
</id>
<property name="no" column="no"/>
<property name="name" column="name"/>
</class>
</hibernate-mapping>
<hibernate-mapping package="model">
<class name="Student" table="tb_student">
<id name="id">
<generator class="native"></generator>
</id>
<property name="no" column="no"/>
<property name="name" column="name"/>
<property name="sex" column="sex"/>
<property name="birthday" column="birthday"/>
<many-to-one name="classInfo" column="class_id" class="model.ClassInfo" lazy="false"/>
</class>
</hibernate-mapping>
- name:设置需要映射的实体类属性名。
- column:设置和实体类的属性对应的表的外键。注意:Hibernate默认此外键参照的是对应实体类的主键,在这里即是class_id参照classInfo实体类的id。
- class:设置需要映射的实体类属性的类型。
- lazy:是否使用懒加载,使用懒加载Hibernate会在你第一次访问关联的对象时才会去数据库取数据,不会立即去数据库检索与此对象关联的所有数据。
public static void main(String[] args)
{
Student student;
Configuration cfg = new Configuration();
cfg.configure();
ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();
SessionFactory sf = cfg.buildSessionFactory(sr);
System.out.println("连接数据库");
Session session = sf.openSession();
student=(Student) session.get(Student.class, new Long(1));
System.out.println(student);
System.out.println(student.getClassInfo());
session.close();
System.out.println("关闭数据库");
System.exit(0);
}
<hibernate-configuration>
<session-factory>
<!-- 省略其他...,设置实体类到数据库的映射文件 -->
<mapping resource="model/ClassInfo.hbm.xml"/>
<mapping resource="model/Student.hbm.xml"/>
</session-factory>
</hibernate-configuration>
连接数据库
Hibernate:
select
student0_.id as id1_2_0_,
student0_.no as no2_2_0_,
student0_.name as name3_2_0_,
student0_.sex as sex4_2_0_,
student0_.birthday as birthday5_2_0_,
student0_.class_id as class_id6_2_0_
from
tb_student student0_
where
student0_.id=?
Hibernate:
select
classinfo0_.id as id1_1_0_,
classinfo0_.no as no2_1_0_,
classinfo0_.name as name3_1_0_
from
tb_class classinfo0_
where
classinfo0_.id=?
Student [id=1, no=000001, name=学生1, sex=男, birthday=2015-01-27]
ClassInfo [id=22, no=000022, name=班级22]
关闭数据库
3.建立一对多的单向关联关系
<hibernate-mapping package="model">
<class name="Student" table="tb_student">
<id name="id">
<generator class="native"></generator>
</id>
<property name="no" column="no"/>
<property name="name" column="name"/>
<property name="sex" column="sex"/>
<property name="birthday" column="birthday"/>
</class>
</hibernate-mapping>
<hibernate-mapping package="model">
<class name="ClassInfo" table="tb_class">
<id name="id">
<generator class="native"></generator>
</id>
<property name="no" column="no"/>
<property name="name" column="name"/>
<bag name="students">
<key column="class_id"/>
<one-to-many class="model.Student"/>
</bag>
</class>
</hibernate-mapping>
- bag name:设置需要映射的实体类属性名。
- key column:设置和实体类的属性对应的表的外键。注意:Hibernate默认此外键参照的是对应实体类的主键,在这里即是class_id参照ClassInfo实体类的id。
- one-to-many class:设置需要映射的实体类属性的类型。
public static void main(String[] args)
{
ClassInfo classInfo;
Configuration cfg = new Configuration();
cfg.configure();
ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();
SessionFactory sf = cfg.buildSessionFactory(sr);
System.out.println("连接数据库");
Session session = sf.openSession();
classInfo =(ClassInfo) session.get(ClassInfo.class, new Long(1));
System.out.println(classInfo);
System.out.println(classInfo.getStudents().size());
System.out.println(classInfo.getStudents().get(0));
session.close();
System.out.println("关闭数据库");
System.exit(0);
}
连接数据库
Hibernate:
select
classinfo0_.id as id1_1_0_,
classinfo0_.no as no2_1_0_,
classinfo0_.name as name3_1_0_
from
tb_class classinfo0_
where
classinfo0_.id=?
ClassInfo [id=1, no=000001, name=班级1]
Hibernate:
select
students0_.class_id as class_id6_1_0_,
students0_.id as id1_2_0_,
students0_.id as id1_2_1_,
students0_.no as no2_2_1_,
students0_.name as name3_2_1_,
students0_.sex as sex4_2_1_,
students0_.birthday as birthday5_2_1_,
students0_.class_id as class_id6_2_1_
from
tb_student students0_
where
students0_.class_id=?
35
Student [id=24, no=000024, name=学生24, sex=女, birthday=2015-01-27]
关闭数据库
4.建立一对多的双向关联关系
<hibernate-mapping package="model">
<class name="Student" table="tb_student">
<id name="id">
<generator class="native"></generator>
</id>
<property name="no" column="no"/>
<property name="name" column="name"/>
<property name="sex" column="sex"/>
<property name="birthday" column="birthday"/>
<many-to-one name="classInfo" column="class_id" class="model.ClassInfo" lazy="false"/>
</class>
</hibernate-mapping>
<hibernate-mapping package="model">
<class name="ClassInfo" table="tb_class">
<id name="id">
<generator class="native"></generator>
</id>
<property name="no" column="no"/>
<property name="name" column="name"/>
<bag name="students" inverse="false" cascade="none" lazy="false">
<key column="class_id"/>
<one-to-many class="model.Student"/>
</bag>
</class>
</hibernate-mapping>
public static void main(String[] args)
{
Student student;
Configuration cfg = new Configuration();
cfg.configure();
ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();
SessionFactory sf = cfg.buildSessionFactory(sr);
System.out.println("连接数据库");
Session session = sf.openSession();
student=(Student) session.get(Student.class, new Long(1));
System.out.println(student);
System.out.println(student.getClassInfo());
System.out.println(student.getClassInfo().getStudents().size());
session.close();
System.out.println("关闭数据库");
System.exit(0);
}
连接数据库
Hibernate:
select
student0_.id as id1_2_0_,
student0_.no as no2_2_0_,
student0_.name as name3_2_0_,
student0_.sex as sex4_2_0_,
student0_.birthday as birthday5_2_0_,
student0_.class_id as class_id6_2_0_
from
tb_student student0_
where
student0_.id=?
Hibernate:
select
classinfo0_.id as id1_1_0_,
classinfo0_.no as no2_1_0_,
classinfo0_.name as name3_1_0_
from
tb_class classinfo0_
where
classinfo0_.id=?
Hibernate:
select
students0_.class_id as class_id6_1_0_,
students0_.id as id1_2_0_,
students0_.id as id1_2_1_,
students0_.no as no2_2_1_,
students0_.name as name3_2_1_,
students0_.sex as sex4_2_1_,
students0_.birthday as birthday5_2_1_,
students0_.class_id as class_id6_2_1_
from
tb_student students0_
where
students0_.class_id=?
Student [id=1, no=000001, name=学生1, sex=男, birthday=2015-01-27]
ClassInfo [id=22, no=000022, name=班级22]
38
关闭数据库
public static void main(String[] args)
{
ClassInfo classInfoNew;
ClassInfo classInfo;
Student studentNew;
Student student;
Configuration cfg = new Configuration();
cfg.configure();
ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();
SessionFactory sf = cfg.buildSessionFactory(sr);
System.out.println("连接数据库");
Session session = sf.openSession();
Transaction transaction = session.beginTransaction();
try
{
classInfoNew = new ClassInfo();
classInfoNew.setName("测试Class");
classInfoNew.setNo("000");
studentNew = new Student();
studentNew.setName("测试Student");
studentNew.setNo("000");
studentNew.setSex("男");
studentNew.setBirthday(new Date(1993, 6, 11));
classInfoNew.getStudents().add(studentNew);
studentNew.setClassInfo(classInfoNew);
session.save(classInfoNew);//一定要先保存classInfo不然会报错,因为数据库约束了class_id为NOT NULL
session.save(studentNew);
student = (Student) session.get(Student.class, new Long(1));
student.setClassInfo(classInfoNew);//执行update维护关系
classInfoNew.getStudents().add(student);//执行update维护关系,update语句数受关联对象数影响,此处的update会有重复!
transaction.commit();
}
catch (Exception e)
{
transaction.rollback();
System.out.println("错误:" + e);
}
finally
{
session.close();
System.out.println("关闭数据库");
}
System.exit(0);
}
连接数据库
Hibernate:
insert into tb_class (no, name) values (?, ?)Hibernate:
insert into tb_student (no, name, sex, birthday, class_id) values (?, ?, ?, ?, ?)Hibernate:
- ........ 省略若干获取关联对象的查询语句
Hibernate:
update tb_student set no=?, name=?, sex=?, birthday=?, class_id=? where id=?Hibernate:
update tb_student set class_id=? where id=?Hibernate:
update tb_student set class_id=? where id=?关闭数据库
- <bag name="students" lazy="false" inverse="true">
<key column="class_id"/>
<one-to-many class="model.Student"/>
</bag>
Hibernate:
update tb_student set no=?, name=?, sex=?, birthday=?, class_id=? where id=?
- 在映射一对多的双向关联关系时,应该在“one”放把bag元素的inverse属性设置为true,这样可以减少不必要的SQL执行,提高应用程序的性能。
- 在建立两个对象的双向关联时,应该同时修改关联两端对象的相应属性:student.setClassInfo(classInfoNew); classInfoNew.getStudents().add(student);
- <many-to-one name="classInfo" column="class_id" class="model.ClassInfo" lazy="false" cascade="save-update"/>
连接数据库
Hibernate:
insert into tb_class (no, name) values (?, ?)Hibernate:
insert into tb_student (no, name, sex, birthday, class_id) values (?, ?, ?, ?, ?)关闭数据库
<bag name="students" lazy="false" inverse="true" cascade="delete">
<key column="class_id"/>
<one-to-many class="model.Student" />
</bag>
Hibernate:
delete from tb_student where id=?Hibernate:
delete from tb_class where id=?
<bag name="students" lazy="false" inverse="true" cascade="all-delete-orphan">
<key column="class_id"/>
<one-to-many class="model.Student" />
</bag>
5.建立一对多的双向自身关联关系
CREATE TABLE tb_area
(
id bigint NOT NULL auto_increment COMMENT 'ID',
name varchar(50) NOT NULL COMMENT '地区名称',
parent_id bigint COMMENT '所属区域ID',
PRIMARY KEY (id)
) COMMENT = '区域信息表';
-- 外键约束可续选
ALTER TABLE tb_area ADD CONSTRAINT fk_tb_area_1 FOREIGN KEY (parent_id) REFERENCES tb_area (id);
package model;
import java.util.Set;
public class Area
{
private Long id;
private String name;
private Area parentArea;
private Set<Area> childAreas = new HashSet<Area>();
// 省略setter、getter、toString...
}
<hibernate-mapping package="model">
<class name="Area" table="tb_area">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"/>
<many-to-one name="parentArea" column="parent_id" class="model.Area" cascade="save-update"/>
<set name="childAreas" inverse="true">
<key column="parent_id"/>
<one-to-many class="model.Area"/>
</set>
</class>
</hibernate-mapping>
public static void main(String[] args)
{
Configuration cfg = new Configuration();
cfg.configure();
ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();
SessionFactory sf = cfg.buildSessionFactory(sr);
System.out.println("连接数据库");
Session session = sf.openSession();
Transaction transaction = session.beginTransaction();
try
{
Area area1=new Area();
Area area2=new Area();
Area area3=new Area();
Area area4=new Area();
Area area5=new Area();
area1.setName("中国");
area2.setName("湖北省");
area3.setName("湖南省");
area4.setName("武汉市");
area5.setName("仙桃市");
area2.setParentArea(area1);
area3.setParentArea(area1);
area4.setParentArea(area2);
area5.setParentArea(area2);
session.save(area3);
session.save(area4);
session.save(area5);
transaction.commit();
}
catch (Exception e)
{
transaction.rollback();
System.out.println("错误:" + e);
}
finally
{
session.close();
System.out.println("关闭数据库");
}
System.exit(0);
}
连接数据库
Hibernate: insert into tb_area (name, parent_id) values (?, ?)
Hibernate: insert into tb_area (name, parent_id) values (?, ?)
Hibernate: insert into tb_area (name, parent_id) values (?, ?)
Hibernate: insert into tb_area (name, parent_id) values (?, ?)
Hibernate: insert into tb_area (name, parent_id) values (?, ?)
关闭数据库
6.改进持久化类
area1.setName("中国");
area2.setName("湖北省");
area2.setParentArea(area1);
area1.getChildAreas().add(area2);
public Area addChildArea(Area area)
{
if (area != null)
{
if (this.childAreas == null)
{
this.childAreas = new HashSet<Area>();
}
//删除原有的关系
if (area.getParentArea() != null)
{
area.getParentArea().getChildAreas().remove(area);
}
//设置当前关系
this.childAreas.add(area);
area.setParentArea(this);
}
return this;
}
area1.setName("中国");
area2.setName("湖北省");
area3.setName("湖南省");
area1.addChildArea(area2).addChildArea(area3);
7.一对多、多对一相关配置详细说明
<many-to-one name="PropertyName"
access="field|property"
column="TableColumn"
class="ClassName"
property-ref="PropertyNameFromAssociatedClass"
foreign-key="foreign-key"
formula="arbitrary SQL expression"
update="true|false"
insert="true|false"
not-null="true|false"
unique="true|false"
unique-key="unique-key"
index="index_name"
not-found="exception|ignore"
outer-join="true|false"
fetch="join|select"
lazy="true|false"
cascade="all|none|save-update|delete"
optimistic-lock="true|false"
embed-xml="true|false"
entity-name="EntityName"
node="element-name"/>
- name:实体类属性名。
- access:默认的实体类属性访问模式,取值为property表示访问getter、setter方法间接访问实体类字段,取值为field表示直接访问实体类字段(类成员变量)。
- column:对应的数据库字段名,此处的字段是外键字段。
- class:关联的类的名字,默认是通过反射得到属性类型。
- property-ref:指定关联类的一个属性,这个属性将会和本外键相对应。如果没有指定,会使用对方关联类的主键。
- foreign-key:关联的数据库外键名。
- formula:一个SQL表达式,定义了这个计算属性的值,计算属性没有和它对应的数据库字段。
- update:在update时是否含有此字段。
- insert:在insert时是否含有此字段。
- not-null:字段能否为空。
- unique:字段是否唯一。
- unique-key:为此字段创建唯一约束,属性值即为数据库唯一约束名,只影响自动生成的schema脚本。
- index:为此字段创建索引,属性值即为数据库索引名,只影响自动生成的schema脚本。
- not-found:指定外键引用的数据不存在时如何处理,ignore会将数据不存在作为关联到一个空对象(null)处理,默认为exception。
- outer-join:设置Hibernate是否使用外连接获取关联的数据,设置成true可以减少SQL语句的条数。
- fetch:参数指定了关联对象抓取的方式是select查询还是join查询,默认为select。fetch="join"等同于outer-join="true",fetch="select"等同于outer-join="false"。
- lazy:是否采用延迟加载策略。
- cascade:指明哪些操作会从父对象级联到关联的对象。
- optimistic-lock:指定这个属性在做更新时是否需要获得乐观锁定,默认为true。
- embed-xml:如果embed-xml="true",则对应于被关联实体或值类型的集合的XML树将直接嵌入拥有这些关联的实体的XML树中,默认值为true。
- entity-name:Hibernate3新增特性,用于动态模型(Dynamic Model)支持。Hibernate3允许一个类进行多次映射(前提是映射到不同的表)。
- node:配置说明。
<bag name="EntityClassName"
access="field|property|ClassName"
collection-type="collection-type"
schema="schema"
catalog="catalog"
check="arbitrary sql check condition"
table="TableName"
subselect="SQL expression"
where="arbitrary sql where condition"
optimistic-lock="false|true"
inverse="false|true"
fetch="join|select"
batch-size="5"
cascade="all|none|save-update|delete"
lazy="false|true"
mutable="false|true"
outer-join="false|true"
order-by="arbitrary sql order by condition"
embed-xml="false|true"
persister="PersisterClass"
node="element-name"/>
- name:实体类属性名。
- access:默认的实体类属性访问模式,取值为property表示访问getter、setter方法间接访问实体类字段,取值为field表示直接访问实体类字段(类成员变量)。
- collection-type:
- schema:数据库schema。
- catalog:数据库catalog。
- check:这是一个SQL表达式,用于为自动生成的schema添加多行约束检查。
- table:此集合里的实体类对应的数据库表名。
- subselect:一个SQL子查询,它将一个不可变并且只读的实体映射到一个数据库的子查询。
- where:一个SQL查询的where条件,获取这个关联类的对象时会一直增加这个条件。
- optimistic-lock:指定这个属性在做更新时是否需要获得乐观锁定,默认为true。
- inverse:当设置inverse="true"时,Hibernate将根此集合里的实体类类型的关联属性维护关联关系,默认值false。
- fetch:参数指定了关联对象抓取的方式是select查询还是join查询,默认为select。fetch="join"等同于outer-join="true",fetch="select"等同于outer-join="false"。
- batch-size:用于设置批次操作的SQL语句的数量,默认为1。
- cascade:指明哪些操作会从父对象级联到关联的对象。
- lazy:是否采用延迟加载策略。
- mutable:此集合里的实体类是否会发生改变,如果类实例对应的数据库表记录不会发生更新,可将其设为false,适用于单纯的Insert操作不使用update操作。
- outer-join:设置Hibernate是否使用外连接获取关联的数据,设置成true可以减少SQL语句的条数。
- order-by:一个SQL查询的order by条件,获取这个关联类的对象时会一直增加这个条件。
- embed-xml:如果embed-xml="true",则对应于被关联实体或值类型的集合的XML树将直接嵌入拥有这些关联的实体的XML树中,默认值为true。
- persister:指定持久化实现类,通过指定持久化类,我们可以实现自定义的持久化方法。持久化类为ClassPersister接口的实现。
- node:配置说明。
<one-to-many class="ClassName"
not-found="exception|ignore"
embed-xml="true|false"
entity-name="EntityName"
node="element-name" />
- class:关联的类的名字,默认是通过反射得到属性类型。
- not-found:指定外键引用的数据不存在时如何处理,ignore会将数据不存在作为关联到一个空对象(null)处理,默认为exception。
- embed-xml:如果embed-xml="true",则对应于被关联实体或值类型的集合的XML树将直接嵌入拥有这些关联的实体的XML树中,默认值为true。
- entity-name:Hibernate3新增特性,用于动态模型(Dynamic Model)支持。Hibernate3允许一个类进行多次映射(前提是映射到不同的表)。
- node:配置说明。
03.Hibernate一对多关联的更多相关文章
- hibernate一对多关联映射
一对多关联映射 映射原理 一对多关联映射和多对一关联映射的映射原理是一致的,都是在多的一端加入一个外键,指向一的一端.关联关系都是由多端维护,只是在写映射时发生了变化. 多对一和一对多的区别 多对一和 ...
- Hibernate一对多关联映射的配置及其级联删除问题
首先举一个简单的一对多双向关联的配置: 一的一端:QuestionType类 package com.exam.entity; import java.util.Set; public class Q ...
- 转Hibernate 一对多关联的CRUD__@ManyToOne(cascade=(CascadeType.ALL))
一:Group和Users两个类 假定一个组里有n多用户,但是一个用户只对应一个用户组. 1.所以Group对于Users是“一对多”的关联关系@OneToMany Users对于Group是“多对一 ...
- Hibernate一对多关联
一对多双向关联关系:(Dept/Emp的案例) 既可以根据在查找部门时根据部门去找该部门下的所有员工,又能在检索员工时获取某个员工所属的部门. 步骤如下: 1.构建实体类(部门实体类加set员工集合) ...
- hibernate 一对多关联
package com.bjsxt.hibernate; import java.util.HashSet; import java.util.Set; import javax.persistenc ...
- hibernate 一对多双向关联 详解
一.解析: 1. 一对多双向关联也就是说,在加载班级时,能够知道这个班级所有的学生. 同时,在加载学生时,也能够知道这个学生所在的班级. 2.我们知道,一对多关联映射和多对一关联映射是一样的,都是在 ...
- Hibernate一对多单向关联和双向关联映射方法及其优缺点 (待续)
一对多关联映射和多对一关联映射实现的基本原理都是一样的,既是在多的一端加入一个外键指向一的一端外键,而主要的区别就是维护端不同.它们的区别在于维护的关系不同: 一对多关联映射是指在加载一的一端数据的同 ...
- (Hibernate进阶)Hibernate映射——一对多关联映射(七)
一对多关联映射 映射原理 一对多关联映射和多对一关联映射的映射原理是一致的,都是在多的一端加入一个外键,指向一的一端.关联关系都是由多端维护,只是在写映射时发生了变化. 多对一和一对多的区别 多对一和 ...
- 【SSH系列】Hibernate映射 -- 一对多关联映射
映射原理 一对多关联映射和多对一关联映射的映射原理是一样一样的,所以说嘛,知识都是相通的,一通百通,为什么说一对多关联映射和多对一关联映射是一样的呢?因为她们都是在多的一端加入一个 ...
随机推荐
- Target Operator ID has No Access to Upgrade
If you are attempting to migrate a project between environments through application designer you mig ...
- Knockout.Js官网学习(数组observable)
前言 如果你要探测和响应一个对象的变化,你应该用observables. 如果你需要探测和响应一个集合对象的变化,你应该用observableArray . 在很多场景下,它都非常有用,比如你要在UI ...
- .Net 内存泄露
一.事件引起的内存泄露 1.不手动注销事件也不发生内存泄露的情况 我们经常会写EventHandler += AFunction; 如果没有手动注销这个Event handler类似:EventHan ...
- 火狐浏览器设置placeholder的时候记得改opacity
最近做项目的时候涉及到需要修改输入框的placeholder的字体颜色,我的CSS如下: ::-webkit-input-placeholder{ color: #c5c5c5;}::-moz-pla ...
- mysql批量修改表引擎
生成修改的语句 SELECT CONCAT('ALTER TABLE ',table_name,' ENGINE=InnoDB;') FROM information_schema.tables WH ...
- android sdk国内目录http://mirrors.neusoft.edu.cn/android/repository/
http://mirrors.neusoft.edu.cn/android/repository/
- SQL Server 基础之《学生表-教师表-课程表-选课表》
一.数据库表结构及数据 建表 CREATE TABLE Student ( S# INT, Sname ), Sage INT, Ssex ) ) CREATE TABLE Course ( C# I ...
- STM32F0xx_GPIO配置详细过程
前言 对于初学STM32的人来说,很多基础的知识没有掌握,这些基础知识就成为阻挡他们入门的门槛.因此,今天也把基础的知识分享出来,带领那些还没有迈过这个门槛的人入门. 今天总结“GPIO配置详细”,以 ...
- autolayout 总结
hasAmbiguousLayoutexerciseAmbiguityInLayout_autolayoutTracerecursiveDescription 第一步:更新约束,可以被认为是一个“计量 ...
- 【原创】可以换行的RadioGroup
0.效果截图: 以上两个RadioGroup均使用FNRadioGroup实现. 1.控件代码: public class FNRadioGroup extends ViewGroup { /** 没 ...