【翻译】(29)访问资源
see
http://developer.android.com/guide/topics/resources/accessing-resources.html
原文见
http://developer.android.com/guide/topics/resources/accessing-resources.html
-------------------------------
Accessing Resources
访问资源
-------------------------------
Quickview
快速概览
* Resources can be referenced from code using integers from R.java, such as R.drawable.myimage
* 资源可以从代码中被引用,使用来自R.java的整型,诸如R.drawable.myimage
* Resources can be referenced from resources using a special XML syntax, such as @drawable/myimage
* 资源可以从资源中被引用,使用特殊XML语法,诸如@drawable/myimage
* You can also access your app resources with methods in Resources
* 你还可以使用Resources的方法访问你的应用资源
Key classes
关键类
Resources
In this document
本文目录
* Accessing Resources from Code 从代码中访问资源
* Accessing Resources from XML 从XML中访问资源
* Referencing style attributes 引用样式属性
* Accessing Platform Resources 访问平台资源
See also
另见
Providing Resources 提供资源
Resource Types 资源类型
-------------------------------
Once you provide a resource in your application (discussed in Providing Resources), you can apply it by referencing its resource ID. All resource IDs are defined in your project's R class, which the aapt tool automatically generates.
一旦你在你的应用程序中提供一个资源(在提供资源中讨论),你可以通过引用它的引用ID来应用它。所有引用ID被定义在你的工程的R类中,它是aapt工具自动生成的。
When your application is compiled, aapt generates the R class, which contains resource IDs for all the resources in your res/ directory. For each type of resource, there is an R subclass (for example, R.drawable for all drawable resources) and for each resource of that type, there is a static integer (for example, R.drawable.icon). This integer is the resource ID that you can use to retrieve your resource.
当你的应用程序被编译时,aapt生成R类,它包含用于你的res/目录中的所有资源的资源ID。对于每个类型的资源,有一个R子类(例如,R.drawable用于所有可绘画对象资源)并且对于那种类型的资源,有一个静态整型(例如,R.drawable.icon)。这个整型是你可以用来取出你的资源的资源ID。
Although the R class is where resource IDs are specified, you should never need to look there to discover a resource ID. A resource ID is always composed of:
虽然R类是资源ID被指定的地方,但是你应该从不需要看那里来发现资源ID。资源ID总是包含:(注:这里的ID是指变量名)
* The resource type: Each resource is grouped into a "type," such as string, drawable, and layout. For more about the different types, see Resource Types.
* 资源类型:每个资源被分组为一个“类型”,诸如字符串,可绘画对象,和布局,想获取关于不同类型的更多信息,请参见资源类型。
* The resource name, which is either: the filename, excluding the extension; or the value in the XML android:name attribute, if the resource is a simple value (such as a string).
* 资源名称,它是其中之一:文件名,不包括扩展名;或者XML中的android:name属性的值,如果资源是一个简单值(诸如一个字符串)。
There are two ways you can access a resource:
你可以用两种方式访问一个资源:
* In code: Using an static integer from a sub-class of your R class, such as:
* 在代码中:使用来自你的R类子类的一个静态整型,诸如:
R.string.hello
string is the resource type and hello is the resource name. There are many Android APIs that can access your resources when you provide a resource ID in this format. See Accessing Resources in Code.
string是资源类型,而hello是资源名称。当你以这种格式提供一个资源ID时,有许多Android API可以访问你的资源。参见在代码中访问资源。
* In XML: Using a special XML syntax that also corresponds to the resource ID defined in your R class, such as:
* 在XML中:使用一个特殊XML语法,它可以对应定义在你的R类中的资源ID,诸如:
@string/hello
string is the resource type and hello is the resource name. You can use this syntax in an XML resource any place where a value is expected that you provide in a resource. See Accessing Resources from XML.
string是资源类型,而hello是资源名称。你可以在一个XML资源中的任意地方使用这个语法,那里期待你在资源中提供一个值。见从XML中访问资源。
-------------------------------
Accessing Resources in Code
在代码中访问资源
You can use a resource in code by passing the resource ID as a method parameter. For example, you can set an ImageView to use the res/drawable/myimage.png resource using setImageResource():
你可以通过传递资源ID作为方法的参数,在代码中使用一个资源。例如,你可以使用setImageResource(),设置一个ImageView使用res/drawable/myimage.png资源。
-------------------------------
ImageView imageView = (ImageView) findViewById(R.id.myimageview);
imageView.setImageResource(R.drawable.myimage);
-------------------------------
You can also retrieve individual resources using methods in Resources, which you can get an instance of with getResources().
你还可以使用Resources中的方法取出单独的资源,你可以用getResources()取得它的一个实例。
-------------------------------
Access to Original Files
访问原始文件
While uncommon, you might need access your original files and directories. If you do, then saving your files in res/ won't work for you, because the only way to read a resource from res/ is with the resource ID. Instead, you can save your resources in the assets/ directory.
在罕见的情况下,你可能需要访问你的原始文件和目录。如果你要这样做,那么把你的文件保存在res/中对你来说没有用,因为从res/中读取资源的唯一方式是使用资源ID。取而代之,你可以保存你的资源在assets/目录中。
Files saved in the assets/ directory are not given a resource ID, so you can't reference them through the R class or from XML resources. Instead, you can query files in the assets/ directory like a normal file system and read raw data using AssetManager.
保存在assets/目录中的文件不会被指定资源ID,所以你不可以通过R类或从XML资源中引用它们。取而代之,你可以就像普通文件系统那样查询assets/目录中的文件并且使用AssetManager读取原始数据。(注:不知道为什么,Android文档中并没有专门提及file:///android_assets/的使用)
However, if all you require is the ability to read raw data (such as a video or audio file), then save the file in the res/raw/ directory and read a stream of bytes using openRawResource().
然而,如果所有你所需的是读取原始数据的功能(诸如一个视频或音频文件),那么保存文件在res/raw/目录中并且使用openRawResource()读取字节流。
-------------------------------
Syntax
语法
Here's the syntax to reference a resource in code:
这里是在代码中引用资源的语法:
-------------------------------
[<package_name>.]R.<resource_type>.<resource_name>
[<包名>.]R.<资源类型>.<资源名称>
-------------------------------
* <package_name> is the name of the package in which the resource is located (not required when referencing resources from your own package).
* <包名>是资源所在包的名称(当引用资源来自你自己的包时不需要)
* <resource_type> is the R subclass for the resource type.
* <资源类型>是用于资源类型的R子类。
* <resource_name> is either the resource filename without the extension or the android:name attribute value in the XML element (for simple values).
* <资源名称>是不带扩展名的资源文件名或在XML元素中android:name属性的值(用于简单值)。
See Resource Types for more information about each resource type and how to reference them.
参见资源类型以获取关于每个资源类型和如何引用它们的更多信息。
Use cases
用例
There are many methods that accept a resource ID parameter and you can retrieve resources using methods in Resources. You can get an instance of Resources with Context.getResources().
有许多接受资源ID参数的方法,而且你可以使用Resources中的方法取出资源。你可以用Context.getResources()获得Resources的一个实例。(注,Activity对象可以直接调用getText(),等效于getResources().getText())
Here are some examples of accessing resources in code:
有一些在代码中访问资源的例子:
-------------------------------
// Load a background for the current screen from a drawable resource
// 从一个可绘画资源中为当前屏幕加载一个背景图
getWindow().setBackgroundDrawableResource(R.drawable.my_background_image) ;
// Set the Activity title by getting a string from the Resources object, because
// this method requires a CharSequence rather than a resource ID
// 通过从Resources中得到一个字符串来设置Activity标题,
// 因为这个方法需要一个CharSequence而非资源ID
getWindow().setTitle(getResources().getText(R.string.main_title));
// Load a custom layout for the current screen
// 为当前屏幕加载一个自定义布局
setContentView(R.layout.main_screen);
// Set a slide in animation by getting an Animation from the Resources object
// 通过从Resources对象中得到一个Animation对象,把幻灯片设置为动画
mFlipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.hyperspace_in));
// Set the text on a TextView object using a resource ID
// 是哟个一个资源ID设置TextView对象上的文本
TextView msgTextView = (TextView) findViewById(R.id.msg);
msgTextView.setText(R.string.hello_message);
-------------------------------
-------------------------------
Caution: You should never modify the R.java file by hand—it is generated by the aapt tool when your project is compiled. Any changes are overridden next time you compile.
警告:你应该从不手动修改R.java——当你的工程被编译时它由aapt工具生成。任何改变在你下一次编译时被覆盖。
-------------------------------
-------------------------------
Accessing Resources from XML
从XML中访问资源
You can define values for some XML attributes and elements using a reference to an existing resource. You will often do this when creating layout files, to supply strings and images for your widgets.
你可以使用指向一个现存资源的引用,为一些XML属性和元素定义值。当创建布局文件时你将经常做这种事情,以为你的部件提供字符串和图片。
For example, if you add a Button to your layout, you should use a string resource for the button text:
例如,如果你添加一个Button到你的布局,那么你应该为按钮文本使用一个字符串资源:
-------------------------------
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/submit" />
Syntax
-------------------------------
Here is the syntax to reference a resource in an XML resource:
这里是引用XML资源内的资源的语法:
-------------------------------
@[<package_name>:]<resource_type>/<resource_name>
@[<包名>:]<资源类型>/<资源名称>
-------------------------------
* <package_name> is the name of the package in which the resource is located (not required when referencing resources from the same package)
* <包名>是资源所在包的名称(不需要,如果引用的资源来自同一个包)
* <resource_type> is the R subclass for the resource type
* <资源类型>是用于资源类型的R子类
* <resource_name> is either the resource filename without the extension or the android:name attribute value in the XML element (for simple values).
* <资源名称>是不带扩展名的资源文件名或XML元素中android:name属性的值(用于简单值)。
See Resource Types for more information about each resource type and how to reference them.
参见资源类型以获取关于每个资源类型和如何引用它们的更多信息。
Use cases
用例
In some cases you must use a resource for a value in XML (for example, to apply a drawable image to a widget), but you can also use a resource in XML any place that accepts a simple value. For example, if you have the following resource file that includes a color resource and a string resource:
在一些情况下你必须对XML中的值使用资源(例如,为了应用一个可绘画图片到一个部件),但你还可以把XML中的资源用在任意接受简单值的位置。例如,如果你有以下资源文件包含一个颜色资源和一个字符串资源:
-------------------------------
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="opaque_red">#f00</color>
<string name="hello">Hello!</string>
</resources>
-------------------------------
You can use these resources in the following layout file to set the text color and text string:
你可以在以下布局文件中使用这些资源以设置文本颜色和文本字符串:
-------------------------------
<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textColor="@color/opaque_red"
android:text="@string/hello" />
-------------------------------
In this case you don't need to specify the package name in the resource reference because the resources are from your own package. To reference a system resource, you would need to include the package name. For example:
在这种情况下你不需要在资源引用中指定包名,因为资源来自你自己的包。为了引用系统资源,你需要包含包名。例如:
-------------------------------
<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textColor="@android:color/secondary_text_dark"
android:text="@string/hello" />
-------------------------------
-------------------------------
Note: You should use string resources at all times, so that your application can be localized for other languages. For information about creating alternative resources (such as localized strings), see Providing Alternative Resources.
注意:你应该总是使用字符串资源,以使你的应用程序可以本地化为其它语言。想获取关于创建可选资源的信息(诸如本地化的字符串),请参见提供可选资源。
-------------------------------
You can even use resources in XML to create aliases. For example, you can create a drawable resource that is an alias for another drawable resource:
你甚至可以使用XML中的资源来创建别名。例如,你可以创建一个可绘画资源,它是一个指向另一个可绘画资源的别名:
-------------------------------
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="/blog_article/@drawable/other_drawable/index.html" />
-------------------------------
This sounds redundant, but can be very useful when using alternative resource. Read more about Creating alias resources.
这听起来有点冗余,但是在使用可选资源时可能非常有用。请阅读关于创建别名资源的更多信息。
Referencing style attributes
引用样式属性
A style attribute resource allows you to reference the value of an attribute in the currently-applied theme. Referencing a style attribute allows you to customize the look of UI elements by styling them to match standard variations supplied by the current theme, instead of supplying a hard-coded value. Referencing a style attribute essentially says, "use the style that is defined by this attribute, in the current theme."
一个样式属性资源允许你引用当前应用的主题中的一个属性的值。引用一个样式属性允许你自定义用户界面元素的外观,通过样式化它们以匹配当前主题提供的标准变化,而非提供硬编码的值。引用一个样式属性本质上是在说,“使用在当前主题中被这个属性定义的样式”。
To reference a style attribute, the name syntax is almost identical to the normal resource format, but instead of the at-symbol (@), use a question-mark (?), and the resource type portion is optional. For instance:
为了引用一个样式属性,名称语法几乎和普通资源格式相同,但不是用@号(@),而是用一个问号(?),而且资源的类型部分是可选的。例如:
-------------------------------
?[<package_name>:][<resource_type>/]<resource_name>
?[<包名>:][<资源类型>/]<资源名称>
-------------------------------
For example, here's how you can reference an attribute to set the text color to match the "primary" text color of the system theme:
例如,这里是你如何可以引用一个属性以设置文本颜色以匹配系统样式的“主”文本颜色:
-------------------------------
<EditText id="text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="?android:textColorSecondary"
android:text="@string/hello_world" />
-------------------------------
Here, the android:textColor attribute specifies the name of a style attribute in the current theme. Android now uses the value applied to the android:textColorSecondary style attribute as the value for android:textColor in this widget. Because the system resource tool knows that an attribute resource is expected in this context, you do not need to explicitly state the type (which would be ?android:attr/textColorSecondary)—you can exclude the attr type.
这里,android:textColor属性指定当前主题中一个样式属性的名称。Android现在使用应用到android:textColorSecondary样式属性的值作为这个部件中android:textColor的值。因为系统资源工具知道在这个上下文中期待一个属性资源,所以你不需要显式地声明类型(它将是?android:attr/textColorSecondary)——你可以不包含attr类型。
-------------------------------
Accessing Platform Resources
访问平台资源
Android contains a number of standard resources, such as styles, themes, and layouts. To access these resource, qualify your resource reference with the android package name. For example, Android provides a layout resource you can use for list items in a ListAdapter:
Android包含一些标准资源,诸如样式、主题,以及布局。为了访问这些资源,用android包名修饰你的资源引用。例如,Android提供一个布局资源,你可以用于ListAdapter中的列表条目:
-------------------------------
setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myarray));
-------------------------------
In this example, simple_list_item_1 is a layout resource defined by the platform for items in a ListView. You can use this instead of creating your own layout for list items. (For more about using ListView, see the List View Tutorial.)
在这个示例中,simple_list_item_1是一个由平台定义的布局资源用于ListView中的条目。你可以使用它而非为列表条目创建你自己的布局。(想获取关于ListView的更多信息,请参见列表视图教程。)
Except as noted, this content is licensed under Apache 2.0. For details and restrictions, see the Content License.
除特别说明外,本文在Apache 2.0下许可。细节和限制请参考内容许可证。
Android 4.0 r1 - 04 Jan 2012 0:53
-------------------------------
Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.
(此页部分内容基于Android开源项目,以及使用根据创作公共2.5来源许可证描述的条款进行修改)
(本人翻译质量欠佳,请以官方最新内容为准,或者参考其它翻译版本:
* ソフトウェア技術ドキュメントを勝手に翻訳
http://www.techdoctranslator.com/android
* Ley's Blog
http://leybreeze.com/blog/
* 农民伯伯
http://www.cnblogs.com/over140/
* Android中文翻译组
http://androidbox.sinaapp.com/
)
Table用来定义entity主表的name,catalog,schema等属性。
元数据属性说明:
- name: 表名
- catalog: 对应关系数据库中的catalog
- schema:对应关系数据库中的schema
- UniqueConstraints:定义一个UniqueConstraint数组,指定需要建唯一约束的列
@Entity @Table(name="CUST") public class Customer { ... }
一个entity class可以映射到多表,SecondaryTable用来定义单个从表的名字,主键名字等属性。
元数据属性说明:
- name: 表名
- catalog: 对应关系数据库中的catalog
- schema:对应关系数据库中的schema
- pkJoin: 定义一个PrimaryKeyJoinColumn数组,指定从表的主键列
- UniqueConstraints:定义一个UniqueConstraint数组,指定需要建唯一约束的列
下面的代码说明Customer类映射到两个表,主表名是CUSTOMER,从表名是CUST_DETAIL,从表的主键列和主表的主键列类型相同,列名为CUST_ID。
@Entity @Table(name="CUSTOMER") @SecondaryTable(name="CUST_DETAIL",pkJoin=@PrimaryKeyJoinColumn(name="CUST_ID")) public class Customer { ... }
当一个entity class映射到一个主表和多个从表时,用SecondaryTables来定义各个从表的属性。
元数据属性说明:
- value: 定义一个SecondaryTable数组,指定每个从表的属性。
@Table(name = "CUSTOMER") @SecondaryTables( value = { @SecondaryTable(name = "CUST_NAME", pkJoin = { @PrimaryKeyJoinColumn(name = "STMO_ID", referencedColumnName = "id") }), @SecondaryTable(name = "CUST_ADDRESS", pkJoin = { @PrimaryKeyJoinColumn(name = "STMO_ID", referencedColumnName = "id") }) }) public class Customer {}
UniqueConstraint定义在Table或SecondaryTable元数据里,用来指定建表时需要建唯一约束的列。
元数据属性说明:
- columnNames:定义一个字符串数组,指定要建唯一约束的列名。
@Entity @Table(name="EMPLOYEE", uniqueConstraints={@UniqueConstraint(columnNames={"EMP_ID", "EMP_NAME"})} ) public class Employee { ... }
Column元数据定义了映射到数据库的列的所有属性:列名,是否唯一,是否允许为空,是否允许更新等。
元数据属性说明:
- name:列名。
- unique: 是否唯一
- nullable: 是否允许为空
- insertable: 是否允许插入
- updatable: 是否允许更新
- columnDefinition: 定义建表时创建此列的DDL
- secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字。
public class Person { @Column(name = "PERSONNAME", unique = true, nullable = false, updatable = true) private String name; @Column(name = "PHOTO", columnDefinition = "BLOB NOT NULL", secondaryTable="PER_PHOTO") private byte[] picture;
如果在entity class的field上定义了关系(one2one或one2many等),我们通过JoinColumn来定义关系的属性。JoinColumn的大部分属性和Column类似。
元数据属性说明:
- name:列名。
- referencedColumnName:该列指向列的列名(建表时该列作为外键列指向关系另一端的指定列)
- unique: 是否唯一
- nullable: 是否允许为空
- insertable: 是否允许插入
- updatable: 是否允许更新
- columnDefinition: 定义建表时创建此列的DDL
- secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字。
下面的代码说明Custom和Order是一对一关系。在Order对应的映射表建一个名为CUST_ID的列,该列作为外键指向Custom对应表中名为ID的列。
public class Custom { @OneToOne @JoinColumn( name="CUST_ID", referencedColumnName="ID", unique=true, nullable=true, updatable=true) public Order getOrder() { return order; }
如果在entity class的field上定义了关系(one2one或one2many等),并且关系存在多个JoinColumn,用JoinColumns定义多个JoinColumn的属性。
元数据属性说明:
- value: 定义JoinColumn数组,指定每个JoinColumn的属性。
下面的代码说明Custom和Order是一对一关系。在Order对应的映射表建两列,一列名为CUST_ID,该列作为外键指向Custom对应表中名为ID的列,另一列名为CUST_NAME,该列作为外键指向Custom对应表中名为NAME的列。
public class Custom { @OneToOne @JoinColumns({ @JoinColumn(name="CUST_ID", referencedColumnName="ID"), @JoinColumn(name="CUST_NAME", referencedColumnName="NAME") }) public Order getOrder() { return order; }
声明当前field为映射表中的主键列。id值的获取方式有五种:TABLE, SEQUENCE, IDENTITY, AUTO, NONE。Oracle和DB2支持SEQUENCE,SQL Server和Sybase支持IDENTITY,mysql支持AUTO。所有的数据库都可以指定为AUTO,我们会根据不同数据库做转换。NONE (默认)需要用户自己指定Id的值。元数据属性说明:
- generate():主键值的获取类型
- generator():TableGenerator的名字(当generate=GeneratorType.TABLE才需要指定该属性)
下面的代码声明Task的主键列id是自动增长的。(Oracle和DB2从默认的SEQUENCE取值,SQL Server和Sybase该列建成IDENTITY,mysql该列建成auto increment。)
@Entity @Table(name = "OTASK") public class Task { @Id(generate = GeneratorType.AUTO) public Integer getId() { return id; } }
当entity class使用复合主键时,需要定义一个类作为id class。id class必须符合以下要求:类必须声明为public,并提供一个声明为public的空构造函数。必须实现Serializable接,覆写 equals()和hashCode()方法。entity class的所有id field在id class都要定义,且类型一样。
元数据属性说明:
- value: id class的类名
public class EmployeePK implements java.io.Serializable{
String empName;
Integer empAge;
public EmployeePK(){}
public boolean equals(Object obj){ ......}
public int hashCode(){......}
}
@IdClass(value=com.acme.EmployeePK.class)
@Entity(access=FIELD)
public class Employee {
@Id String empName;
@Id Integer empAge;
}
在一对多,多对多关系中,我们可以用Map来保存集合对象。默认用主键值做key,如果使用复合主键,则用id class的实例做key,如果指定了name属性,就用指定的field的值做key。
元数据属性说明:
- name: 用来做key的field名字
下面的代码说明Person和Book之间是一对多关系。Person的books字段是Map类型,用Book的isbn字段的值作为Map的key。
@Table(name = "PERSON") public class Person { @OneToMany(targetEntity = Book.class, cascade = CascadeType.ALL, mappedBy = "person") @MapKey(name = "isbn") private Map books = new HashMap(); }
在一对多,多对多关系中,有时我们希望从数据库加载出来的集合对象是按一定方式排序的,这可以通过OrderBy来实现,默认是按对象的主键升序排列。
元数据属性说明:
- value: 字符串类型,指定排序方式。格式为"fieldName1 [ASC|DESC],fieldName2 [ASC|DESC],......",排序类型可以不指定,默认是ASC。
下面的代码说明Person和Book之间是一对多关系。集合books按照Book的isbn升序,name降序排列。
@Table(name = "MAPKEY_PERSON") public class Person { @OneToMany(targetEntity = Book.class, cascade = CascadeType.ALL, mappedBy = "person") @OrderBy(name = "isbn ASC, name DESC") private List books = new ArrayList(); }
在三种情况下会用到PrimaryKeyJoinColumn。
- 继承。
- entity class映射到一个或多个从表。从表根据主表的主键列(列名为referencedColumnName值的列),建立一个类型一样的主键列,列名由name属性定义。
- one2one关系,关系维护端的主键作为外键指向关系被维护端的主键,不再新建一个外键列。
元数据属性说明:
- name:列名。
- referencedColumnName:该列引用列的列名
- columnDefinition: 定义建表时创建此列的DDL
下面的代码说明Customer映射到两个表,主表CUSTOMER,从表CUST_DETAIL,从表需要建立主键列CUST_ID,该列和主表的主键列id除了列名不同,其他定义一样。
@Entity @Table(name="CUSTOMER") @SecondaryTable(name="CUST_DETAIL",pkJoin=@PrimaryKeyJoinColumn(name="CUST_ID",referencedColumnName="id")) public class Customer { @Id(generate = GeneratorType.AUTO) public Integer getId() { return id; } }
下面的代码说明Employee和EmployeeInfo是一对一关系,Employee的主键列id作为外键指向EmployeeInfo的主键列INFO_ID。
@Table(name = "Employee") public class Employee { @OneToOne @PrimaryKeyJoinColumn(name = "id", referencedColumnName="INFO_ID") EmployeeInfo info; }
如果entity class使用了复合主键,指定单个PrimaryKeyJoinColumn不能满足要求时,可以用PrimaryKeyJoinColumns来定义多个PrimaryKeyJoinColumn。
元数据属性说明:
- value: 一个PrimaryKeyJoinColumn数组,包含所有PrimaryKeyJoinColumn。
下面的代码说明了Employee和EmployeeInfo是一对一关系。他们都使用复合主键,建表时需要在Employee表建立一个外键,从Employee的主键列id,name指向EmployeeInfo的主键列INFO_ID和INFO_NAME.
@Entity @IdClass(EmpPK.class) @Table(name = "EMPLOYEE") public class Employee { private int id; private String name; private String address; @OneToOne(cascade = CascadeType.ALL) @PrimaryKeyJoinColumns({ @PrimaryKeyJoinColumn(name="id", referencedColumnName="INFO_ID"), @PrimaryKeyJoinColumn(name="name" , referencedColumnName="INFO_NAME")}) EmployeeInfo info; } @Entity @IdClass(EmpPK.class) @Table(name = "EMPLOYEE_INFO") public class EmployeeInfo { @Id @Column(name = "INFO_ID") private int id; @Id @Column(name = "INFO_NAME") private String name; }
Transient用来注释entity的属性,指定的这些属性不会被持久化,也不会为这些属性建表。
@Transient private String name;
Version指定实体类在乐观事务中的version属性。在实体类重新由EntityManager管理并且加入到乐观事务中时,保证完整性。每一个类只能有一个属性被指定为version,version属性应该映射到实体类的主表上。
下面的代码说明versionNum属性作为这个类的version,映射到数据库中主表的列名是OPTLOCK。
@Version @Column("OPTLOCK") protected int getVersionNum() { return versionNum; }
Lob指定一个属性作为数据库支持的大对象类型在数据库中存储。使用LobType这个枚举来定义Lob是二进制类型还是字符类型。
LobType枚举类型说明:
- BLOB 二进制大对象,Byte[]或者Serializable的类型可以指定为BLOB。
- CLOB 字符型大对象,char[]、Character[]或String类型可以指定为CLOB。
元数据属性说明:
- fetch: 定义这个字段是lazy loaded还是eagerly fetched。数据类型是FetchType枚举,默认为LAZY,即lazy loaded.
- type: 定义这个字段在数据库中的JDBC数据类型。数据类型是LobType枚举,默认为BLOB。
下面的代码定义了一个BLOB类型的属性和一个CLOB类型的属性。
@Lob @Column(name="PHOTO" columnDefinition="BLOB NOT NULL") protected JPEGImage picture; @Lob(fetch=EAGER, type=CLOB) @Column(name="REPORT") protected String report;
JoinTable在many-to-many关系的所有者一边定义。如果没有定义JoinTable,使用JoinTable的默认值。
元数据属性说明:
- table:这个join table的Table定义。
- joinColumns:定义指向所有者主表的外键列,数据类型是JoinColumn数组。
- inverseJoinColumns:定义指向非所有者主表的外键列,数据类型是JoinColumn数组。
下面的代码定义了一个连接表CUST和PHONE的join table。join table的表名是CUST_PHONE,包含两个外键,一个外键是CUST_ID,指向表CUST的主键ID,另一个外键是PHONE_ID,指向表PHONE的主键ID。
@JoinTable( table=@Table(name=CUST_PHONE), joinColumns=@JoinColumn(name="CUST_ID", referencedColumnName="ID"), inverseJoinColumns=@JoinColumn(name="PHONE_ID", referencedColumnName="ID") )
TableGenerator定义一个主键值生成器,在Id这个元数据的generate=TABLE时,generator属性中可以使用生成器的名字。生成器可以在类、方法或者属性上定义。
生成器是为多个实体类提供连续的ID值的表,每一行为一个类提供ID值,ID值通常是整数。
元数据属性说明:
- name:生成器的唯一名字,可以被Id元数据使用。
- table:生成器用来存储id值的Table定义。
- pkColumnName:生成器表的主键名称。
- valueColumnName:生成器表的ID值的列名称。
- pkColumnValue:生成器表中的一行数据的主键值。
- initialValue:id值的初始值。
- allocationSize:id值的增量。
下面的代码定义了两个生成器empGen和addressGen,生成器的表是ID_GEN。
@Entity public class Employee { ... @TableGenerator(name="empGen", table=@Table(name="ID_GEN"), pkColumnName="GEN_KEY", valueColumnName="GEN_VALUE", pkColumnValue="EMP_ID", allocationSize=1) @Id(generate=TABLE, generator="empGen") public int id; ... } @Entity public class Address { ... @TableGenerator(name="addressGen", table=@Table(name="ID_GEN"), pkColumnValue="ADDR_ID") @Id(generate=TABLE, generator="addressGen") public int id; ... }
SequenceGenerator定义一个主键值生成器,在Id这个元数据的generator属性中可以使用生成器的名字。生成器可以在类、方法或者属性上定义。生成器是数据库支持的sequence对象。
元数据属性说明:
- name:生成器的唯一名字,可以被Id元数据使用。
- sequenceName:数据库中,sequence对象的名称。如果不指定,会使用提供商指定的默认名称。
- initialValue:id值的初始值。
- allocationSize:id值的增量。
下面的代码定义了一个使用提供商默认名称的sequence生成器。
@SequenceGenerator(name="EMP_SEQ", allocationSize=25)
DiscriminatorColumn定义在使用SINGLE_TABLE或JOINED继承策略的表中区别不继承层次的列。
元数据属性说明:
- name:column的名字。默认值为TYPE。
- columnDefinition:生成DDL的sql片断。
- length:String类型的column的长度,其他类型使用默认值10。
下面的代码定义了一个列名为DISC,长度为20的String类型的区别列。
@Entity @Table(name="CUST") @Inheritance(strategy=SINGLE_TABLE, discriminatorType=STRING, discriminatorValue="CUSTOMER") @DiscriminatorColumn(name="DISC", length=20) public class Customer { ... }
安装GTK环境只要安装一个libgtk2.0-dev就可以了,而安装gnome开发环境的话,需要装gnome-core-devel,它包含GTK开发包。
但在一般情况下,我们需要有一个ide开发环境,需要帮助文件,于是我们安装
sudo apt-get install gnome-devel gnome-devel-docs
安装完成后我们也同样做个测试程序
#include<gtk/gtk.h> void hello(GtkWidget *widget,gpointer data) { g_print("Hello Ubuntu!\n"); } gint delete_event(GtkWidget *widget,GdkEvent *event,gpointer data) { g_print ("delete event occurred\n"); return(TRUE); } void destroy(GtkWidget *widget,gpointer data) { gtk_main_quit(); } int main( int argc, char *argv[] ) { GtkWidget *window; GtkWidget *button; gtk_init (&argc, &argv); window=gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_signal_connect (GTK_OBJECT(window),"delete_event",GTK_SIGNAL_FUNC(delete_event),NULL); gtk_signal_connect (GTK_OBJECT (window), "destroy",GTK_SIGNAL_FUNC (destroy), NULL); gtk_container_set_border_width (GTK_CONTAINER (window), 10); button = gtk_button_new_with_label ("Hello Ubuntu!"); gtk_signal_connect (GTK_OBJECT (button), "clicked",GTK_SIGNAL_FUNC (hello), NULL); gtk_signal_connect_object (GTK_OBJECT (button), "clicked",GTK_SIGNAL_FUNC (gtk_widget_destroy),GTK_OBJECT (window)); gtk_container_add (GTK_CONTAINER (window), button); gtk_widget_show (button); gtk_widget_show (window); /*显示一个窗口*/ gtk_main(); /*进入主循环*/ return(0); }
用下面命令编译运行
$ gcc `pkg-config --cflags --libs gtk+-2.0` gtktest.c -o gtktest
$ ./gtktest
会显示一个带有一个按钮的窗口,点击按钮以后窗口关闭,命令行显示Hello Ubuntu!
有时候运行可能会提示警告:
Gtk-WARNING **: 无法在模块路径中找到主题引擎:“pixmap”。运行下边的apt代码安装就可以了。
sudo apt-get install gtk2-engines-pixbuf