此處使用的是JDK的動態代理方式,延遲加載使用的cglib動態代理方式java
代理分爲靜態代理和動態代理。此處先不說靜態代理,由於Mybatis中使用的代理方式是動態代理。mysql
動態代理分爲兩種方式:sql
只須要開發Mapper接口(dao接口)和Mapper映射文件,不須要編寫實現類。數據庫
Mapper接口開發方式須要遵循如下規範:數組
一、 Mapper接口的類路徑與Mapper.xml文件中的namespace相同。session
二、 Mapper接口方法名稱和Mapper.xml中定義的每一個statement的id相同。mybatis
三、 Mapper接口方法的輸入參數類型和mapper.xml中定義的每一個sql 的parameterType的類型相同。app
四、 Mapper接口方法的返回值類型和mapper.xml中定義的每一個sql的resultType的類型相同。測試
<?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.kkb.mybatis.mapper.UserMapper"> <!-- 根據id獲取用戶信息 --> <select id="findUserById" parameterType="int" resultType="com.kkb.mybatis.po.User"> select * from user where id = #{id} </select> </mapper>
/** * 用戶管理mapper */ public interface UserMapper { //根據用戶id查詢用戶信息 public User findUserById(int id) throws Exception; }
<!-- 加載映射文件 --> <mappers> <mapper resource="mapper/UserMapper.xml"/> </mappers>
public class UserMapperTest{ private SqlSessionFactory sqlSessionFactory; @Before public void setUp() throws Exception { //mybatis配置文件 String resource = "SqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); //使用SqlSessionFactoryBuilder建立sessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } @Test public void testFindUserById() throws Exception { //獲取session SqlSession session = sqlSessionFactory.openSession(); //獲取mapper接口的代理對象 UserMapper userMapper = session.getMapper(UserMapper.class); //調用代理對象方法 User user = userMapper.findUserById(1); System.out.println(user); //關閉session session.close(); } }
只須要編寫mapper接口文件接口。ui
public interface AnnotationUserMapper { // 查詢 @Select("SELECT * FROM user WHERE id = #{id}") public User findUserById(int id); // 模糊查詢用戶列表 @Select("SELECT * FROM user WHERE username LIKE '%${value}%'") public List<User> findUserList(String username); // 添加並實現主鍵返回 @Insert("INSERT INTO user (username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address})") @SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty = "id", resultType = int.class, before = false) public void insertUser(User user); }
public class AnnotationUserMapperTest { private SqlSessionFactory sqlSessionFactory; /** * @Before註解的方法會在@Test註解的方法以前執行 * * @throws Exception */ @Before public void init() throws Exception { // 指定全局配置文件路徑 String resource = "SqlMapConfig.xml"; // 加載資源文件(全局配置文件和映射文件) InputStream inputStream = Resources.getResourceAsStream(resource); // 還有構建者模式,去建立SqlSessionFactory對象 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } @Test public void testFindUserById() { SqlSession sqlSession = sqlSessionFactory.openSession(); AnnotationUserMapper userMapper = sqlSession.getMapper(AnnotationUserMapper.class); User user = userMapper.findUserById(1); System.out.println(user); } @Test public void testFindUserList() { SqlSession sqlSession = sqlSessionFactory.openSession(); AnnotationUserMapper userMapper = sqlSession.getMapper(AnnotationUserMapper.class); List<User> list = userMapper.findUserList("老郭"); System.out.println(list); } @Test public void testInsertUser() { SqlSession sqlSession = sqlSessionFactory.openSession(); AnnotationUserMapper userMapper = sqlSession.getMapper(AnnotationUserMapper.class); User user = new User(); user.setUsername("開課吧-2"); user.setSex("1"); user.setAddress("致真大廈"); userMapper.insertUser(user); System.out.println(user.getId()); } }
SqlMapConfig.xml中配置的內容和順序以下:
properties(屬性) settings(全局配置參數) typeAliases(類型別名) typeHandlers(類型處理器)--Java類型--JDBC類型--->數據庫類型轉換 objectFactory(對象工廠) plugins(插件)--能夠在Mybatis執行SQL語句的流程中,橫叉一腳去實現一些功能加強,好比PageHelper分頁插件,就是第三方實現的一個插件 environments(環境集合屬性對象) environment(環境子屬性對象) transactionManager(事務管理) dataSource(數據源) mappers(映射器)
SqlMapConfig.xml能夠引用java屬性文件中的配置信息。
一、在classpath下定義db.properties文件,
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/ssm?characterEncoding=utf-8 jdbc.username=root jdbc.password=root
二、在SqlMapConfig.xml文件中,引用db.properties中的屬性,具體以下:
<properties resource="db.properties"/> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments>
properties標籤除了可使用resource屬性,引用properties文件中的屬性。還能夠在properties標籤內定義property子標籤來定義屬性和屬性值,具體以下:
<properties> <property name="driver" value="com.mysql.jdbc.Driver"/> </properties>
注意: MyBatis 將按照下面的順序來加載屬性:
別名的做用:就是爲了簡化映射文件中parameterType和ResultType中的POJO類型名稱編寫。
別名 | 映射的類型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
map | Map |
在SqlMapConfig.xml中進行以下配置:
<typeAliases> <!-- 單個別名定義 --> <typeAlias alias="user" type="com.kkb.mybatis.po.User"/> <!-- 批量別名定義,掃描整個包下的類,別名爲類名(首字母大寫或小寫均可以) --> <package name="com.kkb.mybatis.po"/> </typeAliases>
使用相對於類路徑的資源
如:
<mapper resource="sqlmap/User.xml" />
使用絕對路徑加載資源
如:
<mapper url="file://d:/sqlmap/User.xml" />
使用mapper接口類路徑,加載映射文件。
如:
<mapper class="com.kkb.mybatis.mapper.UserMapper"/>
注意:此種方法要求mapper接口名稱和mapper映射文件名稱相同,且放在同一個目錄中。
註冊指定包下的全部mapper接口,來加載映射文件。
如:
<package name="com.kkb.mybatis.mapper"/>
注意:此種方法要求mapper接口名稱和mapper映射文件名稱相同,且放在同一個目錄中。
parameterType屬性能夠映射的輸入參數Java類型有:簡單類型、POJO類型、Map類型、List類型(數組)。
參考《Mybatis基礎》(在個人主頁內查找)中用戶查詢的案例。
參考《Mybatis基礎》(在個人主頁內查找)中的添加用戶的案例。
包裝對象:pojo類中嵌套pojo。
經過包裝POJO傳遞參數,完成用戶查詢。
定義包裝對象QueryVO
public class QueryVO { private User user; }
SELECT * FROM user where username like '%小明%'
<!-- 使用包裝類型查詢用戶 使用ognl從對象中取屬性值,若是是包裝對象可使用.操做符來取內容部的屬性 --> <select id="findUserList" parameterType="queryVo" resultType="user"> SELECT * FROM user where username like '%${user.username}%' </select>
/** * 用戶管理mapper */ public interface UserMapper { //綜合查詢用戶列表 public List<User> findUserList(QueryVo queryVo)throws Exception; }
在UserMapperTest測試類中,添加如下測試代碼:
@Test public void testFindUserList() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); //得到mapper的代理對象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //建立QueryVo對象 QueryVo queryVo = new QueryVo(); //建立user對象 User user = new User(); user.setUsername("小明"); queryVo.setUser(user); //根據queryvo查詢用戶 List<User> list = userMapper.findUserList(queryVo); System.out.println(list); sqlSession.close(); }
resultType屬性能夠映射的java類型有:簡單類型、POJO類型、Map類型。
不過Map類型和POJO類型的使用狀況相似,因此只需講解POJO類型便可。
使用resultType進行輸出映射時,要求sql語句中查詢的列名和要映射的pojo的屬性名一致。
查詢用戶記錄總數。
<!-- 獲取用戶列表總數 --> <select id="findUserCount" resultType="int"> select count(1) from user </select>
//查詢用戶總數 public int findUserCount() throws Exception;
在UserMapperTest測試類中,添加如下測試代碼:
@Test public void testFindUserCount() throws Exception { SqlSession sqlSession = sessionFactory.openSession(); //得到mapper的代理對象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); int count = userMapper.findUserCount(queryVo); System.out.println(count); sqlSession.close(); }
注意:輸出簡單類型必須查詢出來的結果集只有一列。
注意:無論是單個POJO仍是POJO集合,在使用resultType完成映射時,用法同樣。
參考《Mybatis基礎》(在個人主頁內查找)中根據用戶ID查詢用戶信息和根據名稱模糊查詢用戶列表的案例
若是sql查詢列名和pojo的屬性名能夠不一致,經過resultMap將列名和屬性名做一個對應關係,最終將查詢結果映射到指定的pojo對象中。
注意:resultType底層也是經過resultMap完成映射的。
將如下sql的查詢結果進行映射:
SELECT id id_,username username_,birthday birthday_ FROM user
// resultMap入門 public List<User> findUserListResultMap() throws Exception;
因爲sql查詢列名和User類屬性名不一致,因此不能使用resultType進行結構映射。
須要定義一個resultMap將sql查詢列名和User類的屬性名對應起來,完成結果映射。
<!-- 定義resultMap:將查詢的列名和映射的pojo的屬性名作一個對應關係 --> <!-- type:指定查詢結果要映射的pojo的類型 id:指定resultMap的惟一標示 --> <resultMap type="user" id="userListResultMap"> <!-- id標籤:映射查詢結果的惟一列(主鍵列) column:查詢sql的列名 property:映射結果的屬性名 --> <id column="id_" property="id"/> <!-- result標籤:映射查詢結果的普通列 --> <result column="username_" property="username"/> <result column="birthday_" property="birthday"/> </resultMap> <!-- resultMap入門 --> <select id="findUserListResultMap" resultMap="userListResultMap"> SELECT id id_,username username_,birthday birthday_ FROM user </select>
<id/>:表示查詢結果集的惟一標識,很是重要。若是是多個字段爲複合惟一約束則定義多個<id />