實(shí)際上以前的示例使用的就是這種方法,今天介紹它的另一種寫法。還是以教師映射為例,修改映射文件TeacherMapper.xml如下(點(diǎn)擊此處進(jìn)入嵌套resultMap形式的示例源碼下載頁面。注:本示例代碼是在修改本系列的上篇博文示例代碼的基礎(chǔ)上完成的,用到了MapperScannerConfigurer和注解等知識(shí)。對(duì)這些知識(shí)不熟悉的讀者,可參考上篇博文:http://legend2011.blog.51cto.com/3018495/980150):
<?xmlversion="1.0"encoding="utf8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--與以前一樣,namespace的值是對(duì)應(yīng)的映射器接口的完整名稱-->
<mappernamespace="com.abc.mapper.TeacherMapper">
<!--TeacherMapper接口中g(shù)etById方法對(duì)應(yīng)的SQL語句。
查詢教師及其指導(dǎo)的學(xué)生的信息。由于教師、學(xué)生都有
id、name、gender等屬性,因此給教師的字段都起了別名-->
<selectid="getById"parameterType="int"resultMap="supervisorResultMap">
select t.id t_id, t.name t_name, t.gender t_gender,
t.research_area t_research_area, t.title t_title,
s.id,s.name, s.gender,s.major,s.grade
from teacher t,student s where t.id=#{id}
and s.supervisor_id = t.id
</select>
<!--教師實(shí)體映射-->
<resultMapid="supervisorResultMap"type="Teacher">
<idproperty="id"column="t_id"/>
<resultproperty="name"column="t_name"/>
<resultproperty="gender"column="t_gender"/>
<resultproperty="researchArea"column="t_research_area"/>
<resultproperty="title"column="t_title"/>
<!--需要注意的是,上面的select語句中學(xué)生的字段名/別名應(yīng)與
下面的column屬性一致。ofType指collection包含的元素的類型,
此屬性不可少-->
<collectionproperty="supStudents"ofType="Student">
<idproperty="id"column="id"/>
<resultproperty="name"column="name"/>
<resultproperty="gender"column="gender"/>
<resultproperty="major"column="major"/>
<resultproperty="grade"column="grade"/>
<!--映射學(xué)生的指導(dǎo)教師屬性,用到了
supervisorResultMap本身-->
<associationproperty="supervisor"
resultMap="supervisorResultMap"/>
</collection>
</resultMap>
</mapper>
運(yùn)行程序結(jié)果如下:
與以前的寫法相比,這種寫法的缺點(diǎn)是學(xué)生實(shí)體映射被嵌入到教師實(shí)體映射中,因此學(xué)生實(shí)體映射不能被重用。
二、嵌套的select語句
這種方式是使用一條單獨(dú)的select語句來加載關(guān)聯(lián)的實(shí)體(在本例中就是學(xué)生實(shí)體),然后在collection元素中引用此select語句(注:此方法會(huì)產(chǎn)生N+1問題,關(guān)于這個(gè)問題可參考本系列博客中的“MyBatis中的N+1問題”)。首先修改TeacherMapper.xml如下(點(diǎn)擊此處進(jìn)入嵌套select語句形式示例源碼下載頁面):
<?xmlversion="1.0"encoding="utf8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--與以前一樣,namespace的值是對(duì)應(yīng)的映射器接口的完整名稱-->
<mappernamespace="com.abc.mapper.TeacherMapper">
<!--TeacherMapper接口中g(shù)etById方法對(duì)應(yīng)的SQL語句。
查詢教師的信息。-->
<selectid="getById"parameterType="int"resultMap="supervisorResultMap">
select * from teacher where id=#{id}
</select>
<!--教師實(shí)體映射-->
<resultMapid="supervisorResultMap"type="Teacher">
<idproperty="id"column="id"/>
<resultproperty="name"column="name"/>
<resultproperty="gender"column="gender"/>
<resultproperty="researchArea"column="research_area"/>
<resultproperty="title"column="title"/>
<!--ofType指collection包含的元素的類型,此屬性不可少。
column屬性指把上述的getById的select語句中的教師id列的值作為參數(shù)
傳遞給將要引用到的下述的getStudents的select語句,此屬性不可少。
引用的形式為:命名空間.select語句id-->
<collectionproperty="supStudents"column="id"ofType="Student"
select="com.abc.mapper.StudentMapper.getStudents"/>
</resultMap>
</mapper>
在這里把根據(jù)指導(dǎo)教師id查詢學(xué)生信息的SQL語句寫在StudentMapper.xml中,并引用其中的學(xué)生實(shí)體映射studentResultMap。修改StudentMapper.xml如下:
<?xmlversion="1.0"encoding="utf8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mappernamespace="com.abc.mapper.StudentMapper">
<resultMapid="studentResultMap"type="Student">
<idproperty="id"column="id"/>
<resultproperty="name"column="name"/>
<resultproperty="gender"column="gender"/>
<resultproperty="major"column="major"/>
<resultproperty="grade"column="grade"/>
<!--在這里引用supervisorResultMap和getById,亦采用
命名空間名.相關(guān)元素id的形式。column="supervisor_id"
屬性不可少-->
<associationproperty="supervisor"
resultMap="com.abc.mapper.TeacherMapper.supervisorResultMap"
select="com.abc.mapper.TeacherMapper.getById"column="supervisor_id"/>
</resultMap>
<!--根據(jù)指導(dǎo)教師id查詢學(xué)生信息-->
<selectid="getStudents"parameterType="int"
resultMap="studentResultMap">
select * from student where supervisor_id = #{id}
</select>
</mapper>
執(zhí)行結(jié)果如下:
最近在工作中遇到了一個(gè)需求
在執(zhí)行數(shù)據(jù)庫操作時(shí)需要先判斷指定的數(shù)據(jù)是否存在,如果不存在則插入,存在則更新
最開始使用的是三條SQL語句:
后來leader提示還有新的方法,一條SQL語句就能搞定:
后來在網(wǎng)上看到的,執(zhí)行update語句的條件是insert語句的執(zhí)行會(huì)造成唯一鍵的重復(fù)。
所以,在創(chuàng)建表的時(shí)候還要加上唯一鍵的約束:
這樣就能達(dá)到目的。
大家都在為項(xiàng)目開發(fā)成功而喜悅,但可不知成功的路上是會(huì)經(jīng)常出錯(cuò)的,下面是我碰到的一些錯(cuò)誤集合!
【錯(cuò)誤信息】
01-16 17:16:18.945: I/magh(979): org.apache.http.conn.HttpHostConnectException: Connection to http://127.0.0.1:8080 refused
在android模擬器連接本機(jī)訪問web時(shí)報(bào)這錯(cuò),把127.0.0.1改成localhost也是一樣的
原因:【錯(cuò)誤信息】
java.lang.IllegalArgumentException: The key must be an application-specific resource id.
原因及解決辦法:
mRadioButton.setTag(1,sQuestionItem.get(i).getToNext());//設(shè)置監(jiān)聽 ToNext:下 一題目mRadioButton.setTag(2,sQuestionItem.get(i).getToEnd());//設(shè)置監(jiān)聽 ToEnd: 是否終止 拋出IllegalArgumentException的原因就在于key不唯一,正確代碼如下:
mRadioButton.setTag(R.id.tag_tonext,sQuestionItem.get(i).getToNext());// 設(shè)置監(jiān)聽 ToNext:下一題目 mRadioButton.setTag(R.id.tag_toend,sQuestionItem.get(i).getToEnd());//設(shè)置 監(jiān)聽 ToEnd:是否終止
【錯(cuò)誤信息】
點(diǎn)擊Debug 運(yùn)行 結(jié)果模擬器總是會(huì)彈出Waiting for Debugger 然后程序又可以正常運(yùn)行
如果你想調(diào)試的時(shí)候去掉 Waiting for Debugger 提示
原因及解決辦法:
重啟啟動(dòng)機(jī)器就OK
本文出自 “java之路” 博客,請(qǐng)務(wù)必保留此出處http://2402766.blog.51cto.com/2392766/1102373
管理提醒: 本帖被 kasim 執(zhí)行置頂操作(2010-04-11)
管理提醒: 本帖被 kasim 執(zhí)行加亮操作(2010-04-11)
首先說一下Json數(shù)據(jù)的最基本的特點(diǎn),Json數(shù)據(jù)是一系列的鍵值對(duì)的集合,和XML數(shù)據(jù)來比,Json數(shù)據(jù)的體積更加小,傳輸效率高,易解析,不過可讀性不高;
因?yàn)檫@次要從服務(wù)器端得到Json數(shù)據(jù),并且通過解析之后把解析后的數(shù)據(jù)顯示在Android客戶端中,首先部署服務(wù)器端代碼(直接使用Jsp/Servlet):
構(gòu)造的Json數(shù)據(jù)如下:
[{"name":"張三","address":"北京","age":20},{"name":"李四","address":"上海","age":30},{"name":"王五","address":"深圳","age":35}]
[一]服務(wù)器端(Person.java省略):
①:數(shù)據(jù)構(gòu)造JsonService.java
main.xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ImageView
android:id="@+id/iv1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="@drawable/longshuai" <!-- longshuai.png為圖片的名稱,記在資源文件里頭,不用文件名后綴-->
/>
</LinearLayout>
注意:強(qiáng)調(diào)一下,資源文件的圖片命名規(guī)則比較嚴(yán)格,由[a-z]和數(shù)字和“_”組成,而且不能數(shù)字開頭,我就常犯傻,命名老是數(shù)字或者大寫字母開頭,這種錯(cuò)誤——囧。。
我們要把longshuai.png導(dǎo)入到res中,最簡單的方式就是直接找到這個(gè)文件夾,復(fù)制進(jìn)去
之后右鍵更新,我們就可以在res中看到自己的圖片了
不用寫代碼。。直接用自動(dòng)生成的代碼。。
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
效果如下:
2、加載本地圖片(其實(shí)主要是SdCard中圖片)
關(guān)于SdCard的使用,可以參見 http://longshuai2007.blog.163.com/blog/static/1420944142011611103950500/
xml文件同上面的是一樣的,并不需要修改
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView image1 = (ImageView) findViewById(R.id.iv1); //獲得ImageView對(duì)象
/*為什么圖片一定要轉(zhuǎn)化為 Bitmap格式的??! */
Bitmap bitmap = getLoacalBitmap("/sdcard/tubiao.jpg"); //從本地取圖片(在cdcard中獲取) //
image1 .setImageBitmap(bitmap); //設(shè)置Bitmap
}
/**
* 加載本地圖片
* @param url
* @return
*/
public static Bitmap getLoacalBitmap(String url) {
try {
FileInputStream fis = new FileInputStream(url);
return BitmapFactory.decodeStream(fis); ///把流轉(zhuǎn)化為Bitmap圖片
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
}
顯示效果如下:
android 完全退出應(yīng)用程序
android android 退出應(yīng)用程序, 單例模式管理Activity
引自:http://www.yoyong.com/archives/199
android 退出應(yīng)用程序會(huì)調(diào)用android.os.Process.killProcess(android.os.Process.myPid())
或是System.exit(0),這只是針對(duì)第一個(gè)Activity(也就是入口的Activity)時(shí)生效。如果有A,B,C
三個(gè)Activity,而想在B 或C 中Activity 退出,調(diào)用上面的方法,往往會(huì)銷毀當(dāng)前的Activity 返回上
一個(gè)Activity。當(dāng)然也可以逐個(gè)返回上一個(gè)Activity,直到跳轉(zhuǎn)到入口的Activity,最后退出應(yīng)用程
序。但這樣比較麻煩,而且逐個(gè)返回的體驗(yàn)并不友好。
網(wǎng)上比較流行的方法是定義棧,寫一個(gè)ExitApplication 類,利用單例模式管理Activity,在每個(gè)在
Activity 的onCreate()方法中調(diào)用ExitApplication.getInstance().addActivity(this)方法,在退
出時(shí)調(diào)用ExitApplication.getInstance().exit()方法,就可以完全退出應(yīng)用程序了。
ExitApplication 類
代碼如下:
view plaincopy to clipboardprint?
1 import java.util.LinkedList;
2 import java.util.List;
3
4 import android.app.Activity;
5 import android.app.Application;
6
7 public class ExitApplication extends Application {
9 private List<Activity> activityList=new LinkedList<Activity>();
10 private static ExitApplication instance;
11
12 private ExitApplication()
13 {
14 }
15 //單例模式中獲取唯一的ExitApplication 實(shí)例
16 public static ExitApplication getInstance()
17 {
18 if(null == instance)
19 {
20 instance = new ExitApplication();
21 }
22 return instance;
23
24 }
25 //添加Activity 到容器中
26 public void addActivity(Activity activity)
27 {
28 activityList.add(activity);
29 }
30 //遍歷所有Activity 并finish
31
32 public void exit()
33 {
34
35 for(Activity activity:activityList)
36 {
37 activity.finish();
38 }
39
40 System.exit(0);
41
42 }
43 }
下面的三個(gè)類IndexActivity, BActivity,CActivity 是簡單的例子, 分別是
IndexActivity–>BActivity–>CActivity 的跳轉(zhuǎn)順序。在每個(gè)Activity 類中onCreate()方法中調(diào)
用ExitApplication.getInstance().addActivity(Activity activity)方法。在任何一個(gè)Activity 界面退
出應(yīng)用程序時(shí),只要調(diào)用ExitApplication.getInstance().exit()方法,就可以在任何一個(gè)Activity
中完全退出應(yīng)用程序。
IndexActivity 類源代碼:
view plaincopy to clipboardprint?
44 import android.app.Activity;
45 import android.content.Intent;
46 import android.os.Bundle;
47 import android.view.View;
48 import android.view.View.OnClickListener;
49 import android.widget.Button;
50
51 public class IndexActivity extends Activity {
52 /** Called when the activity is first created. */
53 @Override
54 public void onCreate(Bundle savedInstanceState) {
55 super.onCreate(savedInstanceState);
56 setContentView(R.layout.main);
57
58 Button next=(Button)findViewById(R.id.next_to_b);
59 next.setOnClickListener(nextClick);
60
61 Button exit=(Button)findViewById(R.id.exit_main);
62 exit.setOnClickListener(exitClick);
63 ExitApplication.getInstance().addActivity(this);
64
65 }
66
67 OnClickListener nextClick=new OnClickListener() {
68
69 @Override
70 public void onClick(View v) {
71 // TODO Auto-generated method stub
72
73 Intent intent=new Intent(IndexActivity.this,BActivity.class);
74 startActivity(intent);
75
76 }
77 };
78
79 OnClickListener exitClick=new OnClickListener() {
80
81 @Override
82 public void onClick(View v) {
83 // TODO Auto-generated method stub
84 ExitApplication.getInstance().exit();
85 }
86 };
87 }
BActivity 類源代碼:
view plaincopy to clipboardprint?
88 import android.app.Activity;
89 import android.content.Intent;
90 import android.os.Bundle;
91 import android.view.View;
92 import android.view.View.OnClickListener;
93 import android.widget.Button;
94
95 public class BActivity extends Activity {
96
97 @Override
98 protected void onCreate(Bundle savedInstanceState) {
99 // TODO Auto-generated method stub
100 super.onCreate(savedInstanceState);
101
102 setContentView(R.layout.b);
103 Button next_to_c=(Button)findViewById(R.id.next_to_c);
104 next_to_c.setOnClickListener(next_to_cClick);
105
106 Button exit_b=(Button)findViewById(R.id.exit_b);
107 exit_b.setOnClickListener(exitClick);
108 ExitApplication.getInstance().addActivity(this);
109
110 }
111
112 OnClickListener next_to_cClick=new OnClickListener() {
113
114 @Override
115 public void onClick(View v) {
116 // TODO Auto-generated method stub
117
118 Intent intent=new Intent(BActivity.this,CActivity.class);
119 startActivity(intent);
120
121 }
122 };
123
124 OnClickListener exitClick=new OnClickListener() {
125
126 @Override
127 public void onClick(View v) {
128 // TODO Auto-generated method stub
129 ExitApplication.getInstance().exit();
130 }
131 };
132 }
CActivity 類源代碼:
view plaincopy to clipboardprint?
133 import android.app.Activity;
134 import android.os.Bundle;
135 import android.view.View;
136 import android.view.View.OnClickListener;
137 import android.widget.Button;
138
139 public class CActivity extends Activity{
140
141 @Override
142 protected void onCreate(Bundle savedInstanceState) {
143 // TODO Auto-generated method stub
144 super.onCreate(savedInstanceState);
145
146 setContentView(R.layout.c);
147
148 Button exit_c=(Button)findViewById(R.id.exit_c);
149 exit_c.setOnClickListener(exitClick);
150 ExitApplication.getInstance().addActivity(this);
151
152 }
153
154 OnClickListener exitClick=new OnClickListener() {
155
156 @Override
157 public void onClick(View v) {
158 // TODO Auto-generated method stub
159 ExitApplication.getInstance().exit();
160 //如果只是調(diào)用以下其中的一個(gè)方法,并不會(huì)完全退出應(yīng)用
161 //android.os.Process.killProcess(android.os.Process.myPid());
162 //System.exit(0);
163 }
164 };
165
166 }