数据库开发技术java方向_Java开发工程师(Web方向) - 03.数据库开发 - 第5章.MyBatis...
第5章--MyBatis
MyBatis入門
Abstract: 數(shù)據(jù)庫框架的工作原理和使用方法(以MyBatis為例)
面向?qū)ο蟮氖澜缗c關(guān)系型數(shù)據(jù)庫的鴻溝:
面向?qū)ο笫澜缰械臄?shù)據(jù)是對象;
關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù)是以行、列表示的二元表。
什么映射技術(shù)能實現(xiàn)對象和二元表之間的自動轉(zhuǎn)換呢?
--ORM (Object Relation Mapping)
持久化類與數(shù)據(jù)庫表之間的映射關(guān)系;對持久化對象的操作自動轉(zhuǎn)換成對關(guān)系數(shù)據(jù)庫操作。
關(guān)系數(shù)據(jù)庫的每一行映射為每一個對象;關(guān)系數(shù)據(jù)庫的每一列映射為對象的一個屬性。
MyBatis:
項目前身為Apache基金會下的開源項目iBatis
支持自定義SQL、存儲過程和高級映射的持久化框架
使用XML或注解配置
能映射基本數(shù)據(jù)元素、接口、Java對象到數(shù)據(jù)庫
本質(zhì)上是ORM框架,但不同的是:
不是直接建立Java對象到關(guān)系數(shù)據(jù)庫表中數(shù)據(jù)之間的映射,而是建立對對象的操作方法到SQL語句之間的映射。
MyBatis功能架構(gòu):
API接口層:主要提供了供外部使用的API,開發(fā)人員通過這些本地API來操作數(shù)據(jù)庫;接口層接到調(diào)用請求以后,將請求轉(zhuǎn)給數(shù)據(jù)處理層去完成具體的數(shù)據(jù)處理。
數(shù)據(jù)處理層:完成數(shù)據(jù)庫的操作
基礎(chǔ)支撐層:最基礎(chǔ)的組件,為數(shù)據(jù)處理成提供支撐
MyBatis工作流機制:
在應(yīng)用程序啟動時,加載一個XML文件,該文件定義了后端數(shù)據(jù)庫地址、SQL與Java之間的映射關(guān)系,根據(jù)XML或注解加載SQL語句、參數(shù)映射、結(jié)果映射到內(nèi)存中;
應(yīng)用程序調(diào)用API傳入?yún)?shù)和SQL ID
MyBatis自動生成SQL語句完成數(shù)據(jù)庫訪問,轉(zhuǎn)換執(zhí)行結(jié)果返回應(yīng)用程序,應(yīng)用程序得到Java對象。
MyBatis環(huán)境搭建:
JAR: mybatis-3.4.5.jar:?https://github.com/mybatis/mybatis-3/releases
(由于MyBatis的底層是基于JDBC實現(xiàn)數(shù)據(jù)庫訪問的,所以也需要JDBC的jar包)
MyBatis配置:
SqlSessionFactory: 通過該實例可以獲取能夠?qū)ο筠D(zhuǎn)換成數(shù)據(jù)庫的這么一個session
通過xml配置文件完成SqlSessionFactory的配置
MyBatis系統(tǒng)的核心配置:后端數(shù)據(jù)庫連接實例的數(shù)據(jù)源、決定事務(wù)范圍和控制方式的事務(wù)管理器 (transactionManager)
將該配置文件放置于工程的根目錄下MyBatisTest/src/main/java/...xml
transactionManager的type屬性可以設(shè)置為jdbc或managed
jdbc: 表示MyBatis的事務(wù)控制其實是直接使用jdbc的提交和回滾
managed: 表示對于MyBatis的事務(wù)提交和回滾,MyBatis不會做任何事情,也不會調(diào)用jdbc的提交和回滾;事務(wù)的控制交給外部的容器,比如Spring的方式來完成
后端數(shù)據(jù)庫源:和jdbc一樣,包括driver, url, username, password.
完成了SqlSessionFactory的配置以后,就可以開始Java程序的編寫了。
MyBatis本身是ORM框架,因此需要定義一些Java對象,建立對象對對象操作和sql語句之間的映射。
在類包MyBatisTest/src/package_name/中:創(chuàng)建User.java和GetUserInfo.java
i.e.
構(gòu)造對象:
public classUser {private intid;privateString userName;privateString corp;publicUser(Integer id, String userName, String corp) {this.id =id;this.userName =userName;this.corp =corp;
}public intgetId() {returnid;
}public void setId(intid) {this.id =id;
}publicString getUserName() {returnuserName;
}public voidsetUserName(String userName) {this.userName =userName;
}publicString getCorp() {returncorp;
}public voidsetCorp(String corp) {this.corp =corp;
}
}
對對象的操作接口:
public interfaceGetUserInfo {public User getUser(intid);public voidaddUser(User user);public voidupdateUser(User user);public voiddeleteUser(User user);
}
完成了Java對象和對Java對象操作的接口的定義之后,
需要創(chuàng)建Java對象和SQL語句映射關(guān)系的配置文件
在類包MyBatisTest/src/package_name/中:創(chuàng)建userMaper.xml(自命名,之后注冊到SqlSessionFactory.xml中)
select id, userName, corp from MyBatisUser where id = #{id}
mapper標(biāo)簽中namespace屬性:定義接口的操作類(interface name)
select標(biāo)簽的id:對對象的操作(getUser())
select標(biāo)簽的parameterType:傳入值的類型(parameter of getUser())
select標(biāo)簽的resultType:要封裝成的類(return from getUser())
上述完成了映射關(guān)系的配置文件,
接下來需要將這些配置文件注冊到最開始的SqlSessionFactory配置文件中:
...
完成數(shù)據(jù)庫查詢的步驟:
1. 加載配置文件(應(yīng)用配置文件SqlSessionFactory.xml、關(guān)聯(lián)映射文件userMapper.xml)
2. 生成SqlSessionFactory實例,獲取SqlSession
3. 利用Session執(zhí)行SQL
測試類:Test.java
public classTest {public static voidmain(String[] args) {//1. 聲明配置文件的目錄地址
String resource = "SqlSessionFactory.xml";//2. 加載應(yīng)用配置文件
InputStream is = Test.class.getClassLoader().getResourceAsStream(resource);//3. 創(chuàng)建SqlSessionFactory
SqlSessionFactory sessionFactory = newSqlSessionFactoryBuilder().build(is);//4. 獲取Session
SqlSession session =sessionFactory.openSession();try{//5. 獲取操作類
GetUserInfo getUserInfo = session.getMapper(GetUserInfo.class);//6. 查詢操作
User user = getUserInfo.getUser(2);
System.out.println(user.getId()+ ". " + user.getUserName() + ":" +user.getCorp());
}finally{//7. 關(guān)閉Session
session.close();
}
}
}
1. 因為配置文件在項目的根目錄,于是路徑直接寫文件名即可。
2. 將配置文件用InputStream加載到程序中
3. 通過上述流對象,創(chuàng)建SqlSessionFactory的實例
4. 從SqlSessionFactory實例中獲取session
5. 通過mapper,獲得接口
6. 通過調(diào)用接口的方法,完成具體操作
7. finally,關(guān)閉session
以上程序即可運行,但是通過兩個配置文件進(jìn)行配置,會不會太繁瑣了呢?
通過注解的方式進(jìn)行配置:通過注解的方式進(jìn)行聲明接口與sql語句之間的映射,以替代映射文件
接口類文件GetUserInfoAnnotation.java (同上例的GetUserInfo.java)
public interfaceGetUserInfoAnnotation {
@Select("select * from user where id = #{id}")public User getUser(intid);
}
Test方法中需要配置映射關(guān)系:
Configuration conf = sessionFactory.getConfiguration();
conf.addMapper(GetUserInfoAnnotation.class);
public static voidmain(String[] args) {//1. 聲明配置文件的目錄地址
String resource = "SqlSessionFactoryAnnotation.xml";//2. 加載應(yīng)用配置文件
InputStream is = TestAnnotation.class.getClassLoader().getResourceAsStream(resource);//3. 創(chuàng)建SqlSessionFactory
SqlSessionFactory sessionFactory = newSqlSessionFactoryBuilder().build(is);//完成配置映射關(guān)系 ******
Configuration conf =sessionFactory.getConfiguration();
conf.addMapper(GetUserInfoAnnotation.class);//4. 獲取Session
SqlSession session =sessionFactory.openSession();try{//5. 獲取操作類
GetUserInfoAnnotation getUserInfoAnnotation = session.getMapper(GetUserInfoAnnotation.class);//6. 查詢操作
User user = getUserInfoAnnotation.getUser(2);
System.out.println(user.getId()+ ". " + user.getUserName() + ":" +user.getCorp());
}finally{//7. 關(guān)閉Session
session.close();
}
}
以上代碼實現(xiàn)了之前mapper的作用(無需userMapper.xml文件,且在SqlSessionFactory.xml中無需添加mapper的注冊)
添加增刪改的功能:
實現(xiàn)接口中的addUser(User user); updateUser(User user); deleteUser(int id);功能
insert into MyBatisUser (userName, Corp) values (#{userName}, #{Corp})
update MyBatisUser SET userName=#{userName}, Corp=#{Corp} WHERE id=#{id};
delete from MyBatisUser where id=#{id};
useGeneratedKeys="true" 使用自增
keyProperty="id" 自增對應(yīng)到id上
對應(yīng)Test.java中:
改為SqlSessionFactory.openSession(true);
JDBC獲取數(shù)據(jù)庫連接時,默認(rèn)自動進(jìn)行提交,不是以事務(wù)為單位提交的;
而在MyBatis中,獲取的事務(wù)默認(rèn)是開啟事務(wù)的,則默認(rèn)對之后的每一個操作都是以事務(wù)的方式來提交的,需顯式調(diào)用commit()
進(jìn)行數(shù)據(jù)庫操作:
public classTest {public static voidmain(String[] args) {//1. 聲明配置文件的目錄地址
String resource = "SqlSessionFactory.xml";//2. 加載應(yīng)用配置文件
InputStream is = Test.class.getClassLoader().getResourceAsStream(resource);//3. 創(chuàng)建SqlSessionFactory
SqlSessionFactory sessionFactory = newSqlSessionFactoryBuilder().build(is);//4. 獲取Session
SqlSession session =sessionFactory.openSession();try{//5. 獲取操作類
GetUserInfo getUserInfo = session.getMapper(GetUserInfo.class);//6. 數(shù)據(jù)庫操作//add user
User user = new User("XiaoMing", "Netease");
getUserInfo.addUser(user);
System.out.println("new ID: " + user.getId()); //id : useGeneratedKey//select user
user =getUserInfo.getUser(user.getId());
System.out.println(user.getId()+ "." + user.getUserName() + ": " +user.getCorp());//update user
user.setUserName("LiMing");
getUserInfo.updateUser(user);
user=getUserInfo.getUser(user.getId());
System.out.println(user.getId()+ "." + user.getUserName() + ": " +user.getCorp());//delete user
getUserInfo.deleteUser(user.getId());
user=getUserInfo.getUser(user.getId());
System.out.println(user);
}finally{//7. 關(guān)閉Session
session.close();
}
}
}
MyBatis的優(yōu)勢和劣勢
優(yōu)勢:入門門檻低;可以自己編寫SQL使得更加靈活也可以進(jìn)行SQL優(yōu)化
劣勢:需要自己編寫SQL導(dǎo)致工作量大;數(shù)據(jù)庫移植性差(需要修改sql語句)
MyBatis進(jìn)階
實際開發(fā)中會遇到復(fù)雜的數(shù)據(jù)庫和復(fù)雜的SQL語句
i.e.
上述ER圖中User與Course之間的關(guān)系為many-to-many, 需要一個Associative Entity
創(chuàng)建數(shù)據(jù)庫:studentEnrollment
./mysql -u root -p;
mysql> create databasestudentEnrollment;
mysql> grant all privileges on studentEnrollment.* to matt@localhost;
mysql> flush privileges;
mysql> exit;
./mysql -u matt -p;
mysql> usestudentEnrollment;
mysql> CREATE TABLE User(-> id int(11) NOT NULLAUTO_INCREMENT,-> userName varchar(100) NOT NULL,-> corp varchar(100) DEFAULT NULL,-> PRIMARY KEY(id)-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
mysql> CREATE TABLEteacher (-> id int(11) NOT NULLAUTO_INCREMENT,-> teacherName varchar(100) NOT NULL,-> PRIMARY KEY(id)-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
mysql> CREATE TABLEcourse (-> id int(11) NOT NULLAUTO_INCREMENT,-> CourseName varchar(100) DEFAULT NULL,-> teacher_id int(11) DEFAULT NULL,-> PRIMARY KEY(id),-> FOREIGN KEY (teacher_id) REFERENCESteacher(id)-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
mysql> CREATE TABLEUserCourse (-> id int(11) NOT NULLAUTO_INCREMENT,-> user_id int(11) DEFAULT NULL,-> course_id int(11) DEFAULT NULL,-> PRIMARY KEY(id),-> FOREIGN KEY (user_id) REFERENCES user(id),-> FOREIGN KEY (course_id) REFERENCEScourse(id)-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
mysql> INSERT INTO User VALUES (null, "XiaoMing", "Netease");
mysql> INSERT INTO Teacher VALUES (null, "Smith");
mysql> INSERT INTO Course VALUES (null, "math", 1);
mysql> INSERT INTO UserCourse VALUES (null, 1, 1);
創(chuàng)建對應(yīng)的Java對象:User, Course, Teacher
public classUser {private intid;privateString userName;privateString corp;private Listcourses;public User(intid, String userName, String corp) {this.id =id;this.userName =userName;this.corp =corp;
}
}
// 還有其他getters和setters,省略(三個類都有)
public classCourse {private intid;privateString courseName;privateTeacher teacher;//getters and setters
}public classTeacher {private intid;privateString teacherName;//getters and setters
}
創(chuàng)建對象的操作的接口:UserOperation.java
三張數(shù)據(jù)庫表之間的連接查詢
public interfaceUserOperation {public User getUser(intid);
}
MyBatis中有很強大的元素ResultMap:可以實現(xiàn)復(fù)雜查詢結(jié)果到復(fù)雜對象關(guān)聯(lián)關(guān)系的轉(zhuǎn)化。
通過構(gòu)造函數(shù)Constructor,在類實例化時注入結(jié)果:一般在關(guān)聯(lián)的時候使用
idArg:ID參數(shù),標(biāo)記結(jié)果作為ID可以幫助提高整體效能
arg:注入到構(gòu)造方法的一個普通結(jié)果
在mapper配置文件userMapperConstructor.xml中
要求在User類中的構(gòu)造函數(shù)的參數(shù)必須和這里的column相同。(courses沒有進(jìn)行初始化)
此時若要映射getUser(),可以這么寫:
select * from user where id = #{id}
其中,resultMap="UserMap"中的"UserMap"就是上面定義的resultMap的id
不要忘記寫上SqlSessionFactory.xml哦~
到這里,已經(jīng)完成了從Java類到具體字段之間的映射關(guān)系。
測試:Test.java
public classTest {public static voidmain(String[] args) {
String resource= "SqlSessionFactory.xml";
InputStream is= Test.class.getClassLoader().getResourceAsStream(resource);
SqlSessionFactory sessionFactory= newSqlSessionFactoryBuilder().build(is);
SqlSession session= sessionFactory.openSession(true);try{
UserOperation userOperation= session.getMapper(UserOperation.class);
User user= userOperation.getUser(1);
System.out.println(user.getId()+"." + user.getUserName() + ":" +user.getCorp());
}finally{
session.close();
}
}
}
但是報錯:
解決方案:將User的構(gòu)造函數(shù)改為public User (Integer id, String userName, String corp) {} 即可
(原來是 public User (int id, String userName, String corp) {} )
但如何讀取User中的courses呢?-- 解決容器問題
使用resultMap中的Collection標(biāo)簽:實現(xiàn)一對多的關(guān)聯(lián)(顧名思義:collection (a collection of complex types))
id:一個ID結(jié)果,標(biāo)記結(jié)果作為ID可以幫助提高整體效能
result: 注入到字段或JavaBean屬性的普通結(jié)果
(Source: The only difference between the two is that?id?will flag the result as an identifier property to be used when comparing object instances. This helps to improve general performance, but especially performance of caching and nested result mapping (i.e. join mapping).)
在mapper.xml中的中加入標(biāo)簽:(與同級)
property的值"courses"必須跟要關(guān)聯(lián)的User類中的List courses變量名一致
ofType的值為該collection的類型名
id/result中的property為course對象中的變量名id;column為database返回結(jié)果中的column
修改select語句:
select u.id as userId, userName, courseName, corp, c.id as courseId from user u left joinuserCourse ucon u.id=uc.user_id left joincourse con c.id=uc.course_idwhere u.id = #{id}
三張表User, Course, UserCourse之間的關(guān)聯(lián),用left join合并
N.B. 由于select語句中使用了u.id as userId這個alias,所以需要將resultMap.constructor中的id column也改為"userID")
(which takes me nearly twenty minutes to fix the bug);
http://www.mybatis.org/mybatis-3/sqlmap-xml.html
Test.java中
System.out.println(user.getCourses().get(0).getCourseName()); // 得到結(jié)果"math"
Course和Teacher也有關(guān)聯(lián),那如何實現(xiàn)這個呢?
Association:實現(xiàn)復(fù)雜類型之間的關(guān)聯(lián)
id, result:與collection中的功能相同
select語句:
select u.id as userId, userName, courseName, corp, c.id ascourseId,teacherName, t.id asteacherIdfrom user u left joinuserCourse ucon u.id=uc.user_id left joincourse con c.id=uc.course_id left jointeacher ton t.id=c.teacher_idwhere u.id = #{id}
在collection中的末尾加上association tag:(因為teacher是與course關(guān)聯(lián)的,而course在此為collection中的元素)
...
property="teacher"對應(yīng)Course類中的Teacher teacher屬性名
column="teacher_id"對應(yīng)數(shù)據(jù)庫中返回結(jié)果的表字段teacher_id
id/result:與collection中功能相同
Test.java中:
System.out.println(user.getCourses().get(0).getTeacher().getTeacherName());
DataSource:數(shù)據(jù)庫連接池
在MyBatis 3.0中內(nèi)置了連接池,與DBCP類似
在SqlSessionFactory.xml的environment中設(shè)置DataSource type="POLLED"即為開啟連接池
有空閑連接鏈和活躍連接鏈兩個隊列,當(dāng)程序需要數(shù)據(jù)庫連接時,首先會判斷如果idleConnections中有空閑連接則直接分配并執(zhí)行sql;如果沒有,則會判斷activeConnections隊列中是否超過了最大活躍連接數(shù)的限制,如果沒有,就會創(chuàng)建新的連接加入activeConnections中;如果超過了,就會遍歷activeConnections隊列找到最早的連接判斷是否超過poolMaximunCheckoutTime,如果過期則強制使其失效并返回該連接。
連接池常用配置選項:
poolMaximunActiveConnections: 最大活躍連接數(shù)(隨著連接數(shù)增加,性能可能達(dá)到拐點,不建議設(shè)置過大))
poolMaximunIdleConnections: 最大空閑連接數(shù)(建議設(shè)置與poolMaximun相同即可)
poolMaximunCheckoutTime:在idleConnections為空且activeConnections達(dá)到最大值時檢查(詳細(xì)步驟見上)
建議設(shè)置為預(yù)期最大SQL執(zhí)行時間(2~3分鐘即可)
poolTimeToWait:獲取服務(wù)器端數(shù)據(jù)庫連接的超時時間,若超過則打印日志,并重新獲取。建議使用默認(rèn)值20s
連接失效:若有連接長期空閑,服務(wù)器端會把該連接關(guān)閉,而連接池不知道該連接被關(guān)閉,依然會使用該連接,則會拋出異常)
poolPingEnabled:啟用連接偵測,檢查連接池中的連接是否為有效連接(默認(rèn)關(guān)閉,建議啟用)
poolPingQuery:偵測sql來探測數(shù)據(jù)庫是否存活,建議使用select 1,因為開銷小
poolPingConnectionsNotUsedFor:偵測時間,建議小于服務(wù)器端超時時間,MySQL默認(rèn)8小時(則一定要小于8)
MyBatis 單元測試
本次得分為:100.00/100.00, 本次測試的提交時間為:2017-08-31
1判斷(10分)
ORM框架實現(xiàn)了關(guān)系數(shù)據(jù)庫中二元表與面向?qū)ο蟮氖澜缰袑ο蟮挠成滢D(zhuǎn)換,通過ORM框架,我們可以在面向?qū)ο蟮木幊讨?#xff0c;通過調(diào)用對象的方法實現(xiàn)對關(guān)系數(shù)據(jù)庫中數(shù)據(jù)的修改。
A.√10.00/10.00
B.×
2判斷(10分)
關(guān)系數(shù)據(jù)庫中的每一列映射為每一個Java對象,每一行映射為Java對象的一個屬性。
A.√
B.×10.00/10.00
3判斷(10分)
MyBatis的前身apache 基金會下的開源項目iBatis。
A.√10.00/10.00
B.×
4判斷(10分)
MyBatis可以實現(xiàn)自動生成SQL語句,開發(fā)者無需自己編寫SQL語句。
A.√
B.×10.00/10.00
5判斷(10分)
SqlSessionFactory是基于MyBatis的應(yīng)用中心,通過SqlSessionFactory實例可以配置后端數(shù)據(jù)庫的數(shù)據(jù)源和決定事務(wù)范圍和控制方式的的事務(wù)管理器。
A.×
B.√10.00/10.00
6判斷(10分)
通過注解的方式可以配置SQL語句和對象方法之間的映射。
A.√10.00/10.00
B.×
7判斷(10分)
association標(biāo)簽可以幫助我們實現(xiàn)通過構(gòu)造函數(shù)的方式對復(fù)雜對象注入值。
A.√
B.×10.00/10.00
8判斷(10分)
ResultMap是MyBatis最強大的元素,可以實現(xiàn)復(fù)雜查詢結(jié)果到復(fù)雜對象的映射。
A.√10.00/10.00
B.×
9判斷(10分)
MyBatis 3.0內(nèi)置了數(shù)據(jù)庫連接池,將datasource type置為pooled,啟用數(shù)據(jù)庫連接池。
A.√10.00/10.00
B.×
10判斷(10分)
MyBatis 內(nèi)置連接池維護(hù)了空閑連接和活躍連接兩個隊列,當(dāng)應(yīng)用需要執(zhí)行SQL時,首先從活躍連接隊列中獲取連接,如果獲取不到,則創(chuàng)建新的連接,然后加入到活躍連接隊列中。
A.√
B.×10.00/10.00
MyBatis?作業(yè)
MyBatis課程單元作業(yè),同學(xué)們需要認(rèn)真完成MyBatis入門和進(jìn)階兩門課程后,完成該作業(yè)題目。作業(yè)內(nèi)容為一道編程題目。
依照學(xué)術(shù)誠信條款,我保證此回答為本人原創(chuàng),所有回答中引用的外部材料已經(jīng)做了出處標(biāo)記。
1(100分)
有一個在線交易的電商平臺,主要包括三張數(shù)據(jù)庫業(yè)務(wù)表:
現(xiàn)在需要基于MyBatis數(shù)據(jù)庫ORM框架,實現(xiàn)讀取商品信息和用戶信息兩個功能。
商品對象和用戶對象定義如下:
每個用戶都關(guān)聯(lián)了一個Product的List,用于表示該用戶所購買的所有商品,可以通過查詢transaction表的交易記錄獲得。
操作接口定義如下:
請分別實現(xiàn)getProduct和getUser兩個函數(shù)方法與SQL語句的映射配置文件。
模板如下:
答:
1. 創(chuàng)建數(shù)據(jù)庫
CREATE TABLEProduct (
Idint AUTO_INCREMENT PRIMARY KEY,
ProductNamevarchar(100) NOT NULL,
Catalogvarchar(100) DEFAULT NULL) ENGINE=Innodb;CREATE TABLE User(
Idint AUTO_INCREMENT PRIMARY KEY,
UserNamevarchar(100) NOT NULL,
Telvarchar(11) DEFAULT NULL) ENGINE=InnoDB;CREATE TABLE Transaction(
Idint AUTO_INCREMENT PRIMARY KEY,
UserIdint NOT NULL,
ProductIdint NOT NULL,FOREIGN KEY (UserId) REFERENCES User(Id),FOREIGN KEY (ProductId) REFERENCESProduct(Id)
) ENGINE=InnoDB;INSERT INTO Product VALUES (null, "Product1", "Catalog1");INSERT INTO User VALUES (null, "User1", null);INSERT INTO Transaction VALUES (null, 1, 1);
2. 導(dǎo)入jdbc.jar和mybatis.jar
3. 創(chuàng)建src下包com.sheng.mybatis.assignment; src下的SqlSessionFactory.xml;
包中 Product.java & User.java & Op.java(如題), Test.java, 還有映射配置文件mapper.xml
4. SqlSessionFactory.xml
5. mapper.xml
select u.id as userId, userName, tel, p.id as productId
from user u left join Transaction t on t.UserId = u.id
left join Product p on p.id = t.productId
where u.id=#{id}
select * from Product where id = #{id}
6. Test.java
public classTest {public static voidmain(String[] args) {
String resource= "SqlSessionFactory.xml";
InputStream is= Test.class.getClassLoader().getResourceAsStream(resource);
SqlSessionFactory sessionFactory= newSqlSessionFactoryBuilder().build(is);
SqlSession session=sessionFactory.openSession();try{
Op op= session.getMapper(Op.class);//test getUser()
User user = op.getUser(1);
System.out.println(user.getUserName()+ " purchased: " +user.getProducts());//test getProduct()
for (intproductId: user.getProducts()) {
Product product=op.getProduct(productId);
System.out.println("productId:" + productId + " " +product.getProductName());
}
}finally{
session.close();
}
}
}
7. User.java的改動:增加一個構(gòu)造函數(shù)
publicUser(Integer id, String userName, String tel) {super();this.id =id;this.userName =userName;this.tel =tel;
}
8. Output
總結(jié)
以上是生活随笔為你收集整理的数据库开发技术java方向_Java开发工程师(Web方向) - 03.数据库开发 - 第5章.MyBatis...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 三星s10长宽高是多少(三星智能手机)
- 下一篇: java强引用软引用深刻理解_Java-