工具類
MyBatis進行數據庫查詢一定會用到SqlSessionFactory和SqlSession這兩個類的對象,為了以后每次查詢方便,就先構造有一個工具類,用來管理這兩個對象:
【SqlSessionFactory的對象是重量級的,而SqlSession是輕量級的】
以下是工具類:
package com.hgd; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; import java.io.InputStream; /* * Mybatis工具類 * 創建SqlSessionFactory對象以及獲取SqlSession對象 * */ public class MyBatisUtils { private static SqlSessionFactory factory = null; static{ InputStream is = null; String config = "mybatis-config.xml"; try{ is = Resources.getResourceAsStream(config); SqlSessionFactory sessionFactory =new SqlSessionFactoryBuilder().build(is); factory = sessionFactory; }catch (IOException e){ e.printStackTrace(); }finally{ if(is!=null) try{ is.close(); }catch (IOException e){ e.printStackTrace(); } } } /* * @param autoCommit 設置是否為自動提交 * */ public static SqlSession getSession(boolean autoCommit){ return factory.openSession(autoCommit); } }
mybatis-config.xml內容
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!--定義一些屬性,以便於在后面引用--> <properties> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="root"/> <property name="password" value="123"/> </properties> <!--設置--> <settings> <!--顯示SQL語句,以便於調試--> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <!--映射文件--> <mappers> <mapper resource="com/hgd/userMapper.xml"/> <mapper resource="com/hgd/employeeMapper.xml"/> <mapper resource="com/hgd/mapper.xml"/> </mappers> </configuration>
需要查詢的數據庫中的user表結構:
實體類User【普通JavaBean】
package com.hgd; public class User { private Integer id; private String username; private String password; private String email; public User(){} public User(Integer id,String username,String password,String email){ setId(id); setUsername(username); setPassword(password); setEmail(email); System.out.println("UserCreated"); } public Integer getId() { return id; } public String getUsername() { return username; } public String getPassword() { return password; } public String getEmail() { return email; } public void setId(Integer id) { this.id = id; } public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", email='" + email + '\'' + '}'; } }
1.利用默認SqlSession中的方法,進行查詢
(1)根據id,查詢某個User的全部字段:
①新建一個映射配置文件【userMapper.xml】
<mapper namespace="${NAMESPACE}" > <!--resultMap 結果映射--> <select id="selectByID" parameterType="int" resultType="com.hgd.User"> select id,username,password,email from user where id = #{id}; </select> </mapper>
【注:實體類User里面的字段和數據庫里面的列名是一樣的,所以就不用再去配置resultMap了;
如果不一樣的話可以
Ⅰ使用別名,比如select e_id as id 這種,別名和實體類屬性一致
Ⅱ再配置一個resultMap,里面配置清楚property和column的聯系。
這里估計是MyBatis反射調用User類中的setter方法設置屬性值的】
②然后在Mybatis主配置文件中引用這個文件,像這樣:
③然后就可以在Java代碼中進行查詢操作了:
這里用到了SqlSession的一個方法,selectOne(String id,Object o);
這里的id就是你在userMapper.xml中配置的select節點的id,Object就是你傳入的參數
運行結果:
【其余的輸出均為設置的<setting name="logImpl" value="STDOUT_LOGGING"/>輸出的內容】:
(2)查詢一組User,返回List<User>這樣的返回值:
這個時候就需要用到select子節點中的resultMap屬性了【這個屬性的意思是,結果映射,與Java中的Map關系不是很大】
①在映射文件中[userMapper.xml]配置一個結果集映射,這里MyBatis是反射調用User的構造方法來創建的對象(猜測
<resultMap id="constructedUser" type="com.hgd.User"> <!--利用構造方法構造對象,參數順序為構造方法中的順序[3.4.3+可任意順序]--> <constructor> <idArg column="id" javaType="int"/> <arg column="username" javaType="String" /> <arg column="password" javaType="String"/> <arg column="email" javaType="String"/> </constructor> </resultMap>
②配置一個select,注意這里是resultMap,然后這個屬性要引用上面配置的resultMap的id
<select id="Users" resultMap="constructedUser"> select * from user </select>
③寫個測試
@Test public void testMyBatis(){ SqlSession s = MyBatisUtils.getSession(true); List<User> u = s.selectList("Users"); System.out.println(u); s.close(); }
輸出結果:
2.自定義接口,由Mybatis代理查詢(抱歉,不是很懂
(1)先新建一個接口[UserMapper],這里會有一系列查詢操作的模板方法:
第一個方法查詢所有的User,第二個方法根據傳入的ID查找指定的一個User
public interface UserMapper { ArrayList<User> getUsers(); User getUserById(Integer id); }
(2)為這個接口配置查詢語句,新建一個配置文件mapper.xml,注意這個時候的namespace應該為這個接口的全類名(好像又看到了反射的影子)
【這里的select的id應該與接口中的函數名一致】
可以理解為 為接口中的每一個函數配置一個對應的<select></select>
<?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.hgd.UserMapper"> <select id="getUsers" resultMap="userList"> select * from user; </select> <resultMap id="userList" type="com.hgd.User"> <id property="id" column="id"/> <result property="username" column="username"/> <result property="password" column="password"/> <result property="email" column="email"/> </resultMap> <select id="getUserById" parameterType="int" resultType="com.hgd.User"> select id,username,password,email from user where id=#{id} </select> </mapper>
(3)在MyBatis全局配置文件中將這個配置文件mapper.xml包含進去
(4)寫個測試:
@Test public void testMyBatis(){ SqlSession s = MyBatisUtils.getSession(true); UserMapper mapper = s.getMapper(UserMapper.class); User u = mapper.getUserById(5); List<User> list = mapper.getUsers(); System.out.println("id為5的用戶:"+u); System.out.println("所有的用戶列表:"+list); }
SqlSession.getMapper(Class clazz);這里可能用了代理
輸出結果:
【SELECT】
在select子節點中,可以有下面的一些屬性:
<select id="selectPerson" parameterType="int" parameterMap="deprecated" resultType="hashmap" resultMap="personResultMap" flushCache="false" useCache="true" timeout="10000" fetchSize="256" statementType="PREPARED" resultSetType="FORWARD_ONLY">
屬性 | 描述 |
---|---|
id | 在命名空間中唯一的標識符,可以被用來引用這條語句。 |
parameterType | 將會傳入這條語句的參數類的完全限定名或別名。這個屬性是可選的,因為 MyBatis 可以通過 TypeHandler 推斷出具體傳入語句的參數,默認值為 unset。 |
resultType | 從這條語句中返回的期望類型的類的完全限定名或別名。注意如果是集合情形,那應該是集合可以包含的類型,而不能是集合本身。使用 resultType 或 resultMap,但不能同時使用。 |
resultMap | 外部 resultMap 的命名引用。結果集的映射是 MyBatis 最強大的特性,對其有一個很好的理解的話,許多復雜映射的情形都能迎刃而解。使用 resultMap 或 resultType,但不能同時使用。 |
flushCache | 將其設置為 true,任何時候只要語句被調用,都會導致本地緩存和二級緩存都會被清空,默認值:false。 |
useCache | 將其設置為 true,將會導致本條語句的結果被二級緩存,默認值:對 select 元素為 true。 |
timeout | 這個設置是在拋出異常之前,驅動程序等待數據庫返回請求結果的秒數。默認值為 unset(依賴驅動)。 |
fetchSize | 這是嘗試影響驅動程序每次批量返回的結果行數和這個設置值相等。默認值為 unset(依賴驅動)。 |
statementType | STATEMENT,PREPARED 或 CALLABLE 的一個。這會讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,默認值:PREPARED。 |
resultSetType | FORWARD_ONLY,SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE 中的一個,默認值為 unset (依賴驅動)。 |
databaseId | 如果配置了 databaseIdProvider,MyBatis 會加載所有的不帶 databaseId 或匹配當前 databaseId 的語句;如果帶或者不帶的語句都有,則不帶的會被忽略。 |
resultOrdered | 這個設置僅針對嵌套結果 select 語句適用:如果為 true,就是假設包含了嵌套結果集或是分組了,這樣的話當返回一個主結果行的時候,就不會發生有對前面結果集的引用的情況。這就使得在獲取嵌套的結果集的時候不至於導致內存不夠用。默認值:false。 |
resultSets | 這個設置僅對多結果集的情況適用,它將列出語句執行后返回的結果集並每個結果集給一個名稱,名稱是逗號分隔的。 |
--------表格來自MyBatis官方中文網站:http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html
常用的幾個屬性一般有resultType,resultMap,parameterType等