咱們知道在mybatis框架中,config.xml中會關聯到許多的XxxxMapper的xml文件,這些文件又對應着一個個的接口,來觀察下這些xml文件
從如下這個文件爲例子:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.briup.mappers.StudentMapper">
首先是如何執行sql語句
<insert id="insertStudent" parameterType="Student">
INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL,PHONE) VALUES(#{studId},#{name},#{email},#{phone})
</insert>
ID屬性爲insertStudent,能夠在當前xml文件中的名空間 com.briup.mappers.StudentMapper.insertStudent中惟一標識該sql語句。parameterType 屬性是一個徹底限定類名或者是一個類型別名alias。
能夠以下調用這個sql語句:
int count = sqlSession.insert("com.briup.mappers.StudentMapper.insertStudent", student);
sqlSession.insert() 方法返回執行 INSERT 語句後所影響的行數。
或者使用映射接口Mapper來調用:
public interface Student Mapper{
int insertStudent(Student student);
}
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
int count = mapper.insertStudent(student);
INSERT插入,(自動生成主鍵)
在INSERT語句中,能夠自動生成主鍵列 STUD_ID 的值。
使用useGeneratedKeys和keyProperty屬性讓數據庫生成auto_increment列的值,並將生成的值設置到其中一個輸入對象屬性內,以下所示:
<insert id="insertStudent2" parameterType="Student" useGeneratedKeys="true" keyProperty="studId">
INSERT INTO STUDENTS(NAME, EMAIL, PHONE) VALUES(#{name},#{email},#{phone})
</insert>
這裏STUD_ID列值將會被數據庫自動生成(如
mysql),而且生成的值會被設置到student對象的studId屬性上
注意:
有些數據庫,如
oracle,並不支持AUTO_INCREMENT列,可是oracle中可使用序列來生成主鍵值。
例如:使用序列my_seq來生成SUTD_ID主鍵值。使用以下代碼來生成主鍵:
drop sequence my_seq;
create sequence my_seq;
<insert id="insertStudent" parameterType="Student">
<selectKey keyProperty="studId" resultType="int" order="BEFORE">
SELECT my_seq.nextval FROM DUAL
</selectKey>
INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL, PHONE)
VALUES(#{studId},#{name},#{email},#{phone})
</insert>
這裏使用了<selectKey>標籤來獲取主鍵值,並將值保存到Student對象的studId 屬性上。屬性order="before" 表示,MyBatis將取得序列的下一個值做爲主鍵值,而且在執行INSERT語句以前將值設置到studId屬性上。
update and delete
<update id="updateStudent" parameterType="Student">
UPDATE STUDENTS SET NAME=#{name}, EMAIL=#{email}, PHONE=#{phone}
WHERE STUD_ID=#{studId}
</update>
<delete id="deleteStudent" parameterType="int">
DELETE FROM STUDENTS WHERE STUD_ID=#{id}
</delete>
注意:在insert updata delete 標籤中都沒有resultType這種屬性,可是並不能說使用這三種SQL語句對應的方法就沒有返回值 ,咱們能夠在接口中爲這三種方法添加int類型的參數,返回的是一個int類型的值,這個值表示SQL語句執行後影響的行數。
SELECT 查詢語句
MyBatis真正強大的功能,在於映射SELECT查詢結果到java的各類類型上。說到查詢,就不能不提映射結果集,有一對一映射,一對多映射,多對多映射。
一個簡單的select查詢配置,以下所示:
<select id="findStudentById" parameterType="int"
resultType="Student">
SELECT STUD_ID, NAME, EMAIL, PHONE
FROM STUDENTS
<!--這裏的#{}中的值,若是傳的是myBatis中封裝的類型,好比int,Integer,那麼這裏的#{}中的值是作形參,命名不限-->
<!--若是是pojo類型的參數傳入另當別論-->
WHERE STUD_ID=#{studId}
</select>
像這樣寫存在一個問題,在Student類型中若是沒有STUD_ID屬性與查詢出來的值對應,咱們能夠給這個列起個別名,若是本身封裝了resultMap那就另說
SELECT STUD_ID AS STUDID, NAME, EMAIL, PHONE FROM STUDENTS WHERE STUD_ID=#{studId}
MyBatis執行返回多條結果的SELECT語句查詢
以下所示:
<select id="findAllStudents" resultType="Student">
SELECT STUD_ID AS studId, NAME,EMAIL, PHONE
FROM STUDENTS
</select>
注意:在這裏雖然返回值仍然寫的是Student 可是結果集是個List<Student>類型的集合,mybatis會將查詢到的結果集中的數據,一條條封裝成Student對象,再將這一個個Student對象存入集合中返回
注意,除了List集合類型,也可使用其餘類型的集合類,如Set,Map等。
MyBatis會根據集合的類型,採用適當的集合實現,以下所示:
對於List,Collection,Iterable類型,
MyBatis將返回java.util.ArrayList
若是查詢出多個條數據,resultType指定封裝的類型,那麼能夠直接將方法的返回值聲明爲list集合接收
對於Map類型,
MyBatis 將返回java.util.HashMap
這裏注意是返回一個鍵值對,仍是多個鍵值對
一個鍵值對---查詢出一條數據:列名作K,值作V,若是查出了多個屬性,就在map中存放了多個K-V對
返回值聲明爲HashMap集合接收
多個鍵值對---查詢出多條數據:可使用List<HashMap<K,V>>存放,一條數據對應一個HashMap
返回值聲明爲List<HashMap<K,V>>集合接收
對於Set類型,
MyBatis 將返回java.util.HashSet
對於SortedSet類型
MyBatis將返回java.util.TreeSet -->
結果集映射 resultMap
resultMap被用來將SELECT語句的結果集映射到java對象的屬性中。
在映射文件中,能夠先定義出結果集映射resultMap,而後在一些SELECT語句上引用這個resultMap。
MyBatis的結果集映射resultMap很是強大,可使用它指定sql查詢出的結果集,會被怎麼處理並封裝成對象,也可使用它完成複雜查詢的映射,例如一對1、一對多關係的SELECT語句。
resultMap標籤中的屬性:
id 屬性值在當前名空間內是惟一的。
type屬性值是指定封裝成的類型的全限定名或者是別名。這個屬性要和方法的返回值相同
<resultMap id="StudentResult" type="com.briup.pojo.Student">
<!--<id>子標籤和<result>標籤功能相同,可是<id>用來映射的是表中的主鍵。-->
<id property="studId" column="stud_id" />
<!-- <result>子標籤用來將一個resultset列映射到對象的一個屬性中。-->
<result property="name" column="name" />
<result property="email" column="email" />
<result property="phone" column="phone" />
</resultMap>
注意1,在<select>標籤中,使用的是resultMap屬性,而不是resultType屬性。
當<select>標籤中配置了resutlMap屬性,MyBatis會根據resutlMap標籤中定義的列名與對象屬性名的 【對應關係】 來自動填充對象中的屬性值。
注意2,resultType和resultMap兩者只能用其一,不能同時使用。
resultType屬性指的是結果集將自動封裝成什麼類型。這時候默認表中列的名字和類中屬性名字一致。
resultMap 屬性指的是結果集將按照<resultMap>標籤中定義的 【對應關係】 來封裝數據。
最後再次說下sql語句的執行方式
1.經過字符串,調用映射文件中的SQL語句
字符串形式爲:
映射文件的namespace + sql語句的id
例如:
SqlSession sqlSession = MyBatisSqlSessionFactory.openSession();
try{
Student student = sqlSession.selectOne("com.briup.mappers.StudentMapper.findStudentById", 1);
System.out.println(student);
}
finally {
sqlSession.close();
}
這種方式容易出錯,由於須要本身編寫字符串,咱們須要檢查映射文件中namespace,以及sql語句定義中對參數和返回值的要求,以保證輸入的參數類型和結果返回類型是有效的。-->java
2.MyBatis中還能夠經過使用映射接口Mapper,調用映射文件中的sql。
sql映射文件中的namespace和映射接口的全限定名要保持一致。
<mapper namespace="com.briup.mappers.StudentMapper">
sql映射文件中的sql語句id值和映射接口中的方法名要保持一致。
sql語句配置的parameterType屬性和映射接口中對應的方法的參數類型保持一致。
sql語句配置的returnType屬性和映射接口中對應的方法的返回值類型保持一致。
<select id="findStudentById" parameterType="int" resultType="Student">
例如:映射接口StudentMapper.java
package com.briup.mappers;
public interface StudentMapper{
Student findStudentById(Integer id);
}
經過映射接口,調用映射文件中的SQL語句。
代碼以下:
SqlSession sqlSession = MyBatisSqlSessionFactory.openSession();
try {
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
Student stu = studentMapper.findStudentById(1);
}
finally {
sqlSession.close();
}