1、mybatis入門(mybatis筆記)

由于之前我們已經(jīng)有了hibernate的基礎(chǔ),所以這里很多細(xì)節(jié)就不再提及。

一、基本架構(gòu)

這里從網(wǎng)絡(luò)上找了幾張mybatis的架構(gòu)和執(zhí)行圖:

架構(gòu)圖
執(zhí)行圖

說明:其實基本過程和hibernate有點類似,

  • SqlMapConfig.xml是mybatis的全局配置文件,配置了數(shù)據(jù)源、事務(wù)等mybatis運行環(huán)境,還要配置mapper.xml(主要是配置要執(zhí)行的sql語句)。
  • SqlSessionFactory(會話工廠)。作用:創(chuàng)建SqlSession
  • SqlSession(會話)。作用:操作數(shù)據(jù)層增刪改查。不直接操作數(shù)據(jù)庫,而是使用Executor執(zhí)行器來操作數(shù)據(jù)庫。通過mapped statement底層封裝對象,其作用是對操作數(shù)據(jù)庫存儲的封裝,包括sql,輸入?yún)?shù)、輸出結(jié)果類型。

二、入門程序

下面我們通過一個入門程序說明一下。(工程mybatis01

2.1 需求

  • 根據(jù)用戶id(主鍵)查詢用戶信息
  • 根據(jù)用戶名模糊查詢
  • 添加、刪除、更新

2.2 依賴包

  • mybatis-3.2.8.jar和lib目錄下的所有包。
  • mysql驅(qū)動包。

2.3 全局配置文件

  • 其中SqlMapperConfig.xmllog4j.properties這里的配置我們可以參考包中的pdf文檔。

  • SqlMapperConfig.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>
    <!-- 和spring整合后environments配置將被廢除 -->
    <environments default="development">
        <environment id="development">
            <!-- 使用jdbc事務(wù)管理 -->
            <transactionManager type="JDBC" />
            <!-- 配置數(shù)據(jù)庫連接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3305/mybatis" />
                <property name="username" value="root" />
                <property name="password" value="walp1314" />
            </dataSource>
        </environment>
    </environments>
    
    <mappers>
        <mapper resource="sqlmap/User.xml" />
    </mappers>
</configuration>
  • log4j.properties
# Global logging configuration
#在開發(fā)的環(huán)境下,日志級別要設(shè)置為DEBUG,生成環(huán)境設(shè)置為ERROR或INFO
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

2.4 入門程序

(1)首先我們需要寫一個映射文件config/sqlmap/User.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 = "test">

    <!--(1)-->
    <!-- 查詢,通過用戶id進(jìn)行查詢-->
    <select id="findUserById" parameterType="java.lang.Integer" resultType="cn.itcast.pojo.User">
        <!-- 最后不能有分號 -->
        SELECT * FROM USER WHERE id = #{value}
    </select>

    <!--(2)-->
    <!-- 根據(jù)用戶名模糊查詢用戶信息,可能返回多條結(jié)果 ,但是結(jié)果類型還是User-->
    <select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.pojo.User">
        <!-- SELECT * FROM USER WHERE username LIKE #{username} -->
        SELECT * FROM USER WHERE username LIKE '%${value}%'
    </select>

    <!--(3)-->
    <!-- 添加用戶-->
    <insert id="insertUser" parameterType="cn.itcast.pojo.User">
        <!-- 返回主鍵,使用SELECT LAST_INSERT_ID() 得到剛插入的主鍵,只適應(yīng)于自增主鍵
        keyProperty指的是將查詢到的主鍵值設(shè)置到parameterType指定的對象的哪個屬性,order指的是相對于insert語句
        來說的執(zhí)行順序,必須在insert語句執(zhí)行之后執(zhí)行-->
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            SELECT LAST_INSERT_ID()
        </selectKey>
        INSERT INTO USER(username, birthday, sex, address) VALUE(#{username}, #{birthday}, #{sex} ,#{address}); 
        
        <!-- 使用mysql的uuid函數(shù)來生成主鍵,是在insert執(zhí)行之前執(zhí)行,首先通過uuid()得到主鍵,將主鍵設(shè)置到對象的屬性中
        然后在insert執(zhí)行時,從user對象中取出id屬性值
        <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
            SELECT UUID()
        </selectKey>
        INSERT INTO USER(id, username, birthday, sex, address) VALUE(#{id}, #{username}, #{birthday}, #{sex} ,#{address}); 
         -->
    </insert>

    <!--(4)-->
    <!-- 刪除用戶,根據(jù)id刪除用戶,需要輸入id值 -->
    <delete id="deleteUserById" parameterType="java.lang.Integer">
        DELETE FROM USER WHERE id = #{value}
    </delete>

    <!--(5)-->
    <!-- 根據(jù)id更新用戶,指定輸入類型為User,就包含了id和需要更新的信息了,注意:id是必須存在的 
    #{id}:通過輸入的User中獲得id值,和之前的不一樣了。-->
    <update id="updateUserById" parameterType="cn.itcast.pojo.User">
        UPDATE USER SET username = #{username}, birthday = #{birthday}, sex = #{sex}, address = #{address} WHERE id = #{id}
    </update>
</mapper>

說明:

  • 1、一般我們需要使用namespace來指定命名空間,這樣便于管理使用,在后面的例子中我們可以看到如何進(jìn)行使用。而每個標(biāo)簽的id就是我們在后面需要定義的方法名,使用parameterType來指定輸入?yún)?shù)的類型,使用resultType指定輸出參數(shù)的類型。

  • 2、對于配置(1),id一般稱為statement的id,因為將來sql會封裝到mappedStatement對象中,#{}表示一個占位符,parameterType指定輸入?yún)?shù)的類型,這里為int(Integer)#{id}中的id表示接收的參數(shù),參數(shù)的名稱就是id,如果輸入?yún)?shù)類型是簡單類型,名稱可以任意,一般我們使用valueresultType指定sql輸出結(jié)果所映射的java對象類型,這里select指定resultType表示單條記錄映射成java對象。

  • 3、對于配置(2),使用#{value}和使用'%${value}%'是有區(qū)別的,前面這種語句我們在傳參的時候還需要自己加上百分號。后面的${}表示拼接sql,將接收到的參數(shù)的內(nèi)容不加任何修飾內(nèi)容拼接在sql中,但是可能有sql注入的隱患。同時如果傳入的是簡單類型,則其中只能使用value,而不能使用任意的,如username不建議使用后一種。

  • 4、對于配置(3),parameterType指定參數(shù)是pojo(包括用戶信息) ,#{}中指定pojo的屬性名,接收到pojo對象的屬性值,通過OGNL獲取對象的屬性值,id如果是自增的話可以不寫。使用SELECT LAST_INSERT_ID()得到剛插入的主鍵,只適應(yīng)于自增主鍵keyProperty指的是將查詢到的主鍵值設(shè)置到parameterType指定的對象的哪個屬性,order指的是相對于insert語句來說的執(zhí)行順序,必須在insert語句執(zhí)行之后執(zhí)行,于是我們使用order進(jìn)行說明。在后面我們還提供了如果主鍵是使用數(shù)據(jù)庫的UUID生成方式該如何取得其值,此種方式有所不同,必須在insert語句執(zhí)行之前執(zhí)行。當(dāng)如對于這里給出的兩個數(shù)據(jù)庫函數(shù)LAST_INSERT_ID()UUID()需要掌握。

  • 5、對于配置(4)和(5),這里就不做過多的說明了。最后需要將此配置文件在全局配置文件中配置進(jìn)去。

(2)實體類pojo(User.java

    private Integer id ;
    private String username ;
    private String sex ;
    private Date birthday ;
    private String address ;

說明:其實pojojavabean差不多。

(3)數(shù)據(jù)庫表

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) NOT NULL COMMENT '用戶名稱',
  `birthday` date DEFAULT NULL COMMENT '生日',
  `sex` char(1) DEFAULT NULL COMMENT '性別',
  `address` varchar(256) DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8

(4)一個示范程序(cn.itcast.first/findUserById.java

package cn.itcast.first;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
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 org.junit.Test;
import cn.itcast.pojo.User;

//入門程序
public class MybatisFirst {
    //根據(jù)id查詢用戶信息
    @Test
    public void findUserById() throws IOException{
        
        //mybatis配置文件
        String resource = "SqlMapConfig.xml";
        //得到配置文件流
        InputStream is = Resources.getResourceAsStream(resource);
        //創(chuàng)建會話工廠,要想build方法中傳入配置信息
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        
        //通過工廠得到SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        //通過SqlSession操作數(shù)據(jù)庫
        //第一個參數(shù)是:映射文件中Statement的id,等于namespace+statement的id
        //第二個參數(shù):指定和映射文件中所匹配的parameterType類型的參數(shù)
        //結(jié)果就是實體類,selectOne表示查詢出一條記錄
        User user = sqlSession.selectOne("test.findUserById", 1);
        
        System.out.println(user.getUsername());
        
        //釋放資源
        sqlSession.close();
    }
    
    //根據(jù)用戶名模糊查詢用戶信息
    @Test
    public void findUserByName() throws IOException{
        
        //mybatis配置文件
        String resource = "SqlMapConfig.xml";
        //得到配置文件流
        InputStream is = Resources.getResourceAsStream(resource);
        //創(chuàng)建會話工廠,要想build方法中傳入配置信息
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        
        
        //通過工廠得到SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        //List<User> users = sqlSession.selectList("test.findUserByName", "%小明%");
        List<User> users = sqlSession.selectList("test.findUserByName", "小明");
        
        for(User user : users){
            System.out.println(user.getUsername());
        }
        
        //釋放資源
        sqlSession.close();
    }
    //添加用戶
    @Test
    public void insertUser() throws IOException{
        
        //mybatis配置文件
        String resource = "SqlMapConfig.xml";
        //得到配置文件流
        InputStream is = Resources.getResourceAsStream(resource);
        //創(chuàng)建會話工廠,要想build方法中傳入配置信息
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        
        
        //通過工廠得到SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        User user = new User();
        user.setUsername("狗蛋");
        user.setBirthday(new Date());
        user.setSex("1");
        user.setAddress("西安");
        
        sqlSession.insert("test.insertUser", user);
        
        //提交事務(wù)
        sqlSession.commit();
        
        //獲取用戶信息主鍵
        System.out.println(user.getId());
        
        //釋放資源
        sqlSession.close();
    }
    //根據(jù)id刪除用戶
    @Test
    public void deleteUserById() throws IOException{
        
        //mybatis配置文件
        String resource = "SqlMapConfig.xml";
        //得到配置文件流
        InputStream is = Resources.getResourceAsStream(resource);
        //創(chuàng)建會話工廠,要想build方法中傳入配置信息
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        
        //通過工廠得到SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        sqlSession.delete("test.deleteUserById", 32);
        
        //提交事務(wù)
        sqlSession.commit();
        
        //釋放資源
        sqlSession.close();
    }
    //根據(jù)id更新用戶
    @Test
    public void updateUserById() throws IOException{
        
        //mybatis配置文件
        String resource = "SqlMapConfig.xml";
        //得到配置文件流
        InputStream is = Resources.getResourceAsStream(resource);
        //創(chuàng)建會話工廠,要想build方法中傳入配置信息
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        
        //通過工廠得到SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        User user = new User();
        user.setId(1);//必須設(shè)置id
        user.setUsername("趙四");
        user.setBirthday(new Date());
        user.setSex("1");
        user.setAddress("西安");
        
        sqlSession.update("test.updateUserById", user);
        
        //提交事務(wù)
        sqlSession.commit();
        
        //釋放資源
        sqlSession.close();
    }
}

說明:

  • 1.首先我們需要定義一個會話工廠SqlSessionFactory 來產(chǎn)生會話SqlSession,這里通過一個構(gòu)造函數(shù)進(jìn)行注入。

  • 2.我們使用會話SqlSession的相關(guān)方法來進(jìn)行數(shù)據(jù)庫操作,對于單條記錄我們使用方法selectOne來進(jìn)行查詢,如果是多條記錄則使用selectList來進(jìn)行查詢,而它們的第一個參數(shù)都是命名空間加上id名,第二個參數(shù)是傳入的值。當(dāng)然對于單條記錄也可以使用selectList方法。

  • 3.在方法findUserByName中我們還可以看到使用#{value}'${value}'的區(qū)別。在方法insertUser中我們在最后演示了獲取數(shù)據(jù)庫生成的主鍵的方式。當(dāng)然這里主鍵的生成方式是自增。

  • 4.對于插入和更新不做過多解釋,最后我們需要手動關(guān)閉會話,因為這里沒有使用spring進(jìn)行管理。很顯然,各個方法中有很多重復(fù)的代碼,所以這種dao層的開發(fā)方式mybatis不推薦。

  • 5.自增主鍵返回:Mysql自增主鍵,執(zhí)行insert提交之前自動生成一個自增主鍵。通過mysql函數(shù)獲取到剛剛提交記錄的自增主鍵:LAST_INSERT_ID(),是在insert之后調(diào)用。非自增主鍵的返回:使用mysqlUUID來生成主鍵,需要修改表中id字段類型為String,長度為35,一般設(shè)置為36。執(zhí)行順序相對于insert是在其之前執(zhí)行。

  • 6.通過Oracle的序列生成主鍵

<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
            SELECT 序列名.nextval()
</selectKey>
INSERT INTO USER(id, username, birthday, sex, address) VALUE(#{id}, #{username}, #{birthday}, #{sex} ,#{address});

三、dao層開發(fā)

3.1使用原始方式進(jìn)行dao層開發(fā)

從上面的例子中我們基本知道m(xù)ybatis的使用方法了。下面我們將上面的程序抽象為dao層。
dao接口(UserDaoI.java

package cn.itcast.dao;
import java.util.List;
import cn.itcast.pojo.User;

//用戶管理接口
public interface UserDaoI {
    //根據(jù)id查詢用戶信息
    public User findUserById(int id );
    public List<User> findUserByName(String username);
    
    //添加用戶
    public void insertUser(User user);
    
    //根據(jù)id查詢用戶
    public void deleteUserById(int id);
}

實現(xiàn)類(UserDaoImpl.java

package cn.itcast.dao;
import java.util.Date;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import cn.itcast.pojo.User;

public class UserDaoImpl implements UserDaoI {

    private SqlSessionFactory sqlSessionFactory;

    // 注入一個SqlSessionFactory,這里通過構(gòu)造函數(shù)注入
    public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    @Override
    public User findUserById(int id) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        User user = sqlSession.selectOne("test.findUserById", id);
        // 釋放資源
        sqlSession.close();
        return user;
    }
    
    @Override
    public List<User> findUserByName(String username) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<User> users = sqlSession.selectList("test.findUserByName", username);
        // 釋放資源
        sqlSession.close();
        return users;
    }

    @Override
    public void insertUser(User user) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.insert("test.insertUser", user);
        // 提交事務(wù)
        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public void deleteUserById(int id) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.delete("test.deleteUserById", id);
        // 提交事務(wù)
        sqlSession.commit();
        sqlSession.close();

    }
}

(5)測試

test/cn.itcast.dao/UserDaoImplTest.java
package cn.itcast.dao;
import static org.junit.Assert.*;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import cn.itcast.pojo.User;

public class UserDaoImplTest {

    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void setUp() throws Exception {
        // 創(chuàng)建sqlSessionFactory
        
        // mybatis配置文件
        String resource = "SqlMapConfig.xml";
        // 得到配置文件流
        InputStream is = Resources.getResourceAsStream(resource);
        // 創(chuàng)建會話工廠,要想build方法中傳入配置信息
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    }

    @Test
    public void testFindUserById() {
        // 創(chuàng)建一個UserDao對象
        UserDaoI userDao = new UserDaoImpl(sqlSessionFactory);

        //調(diào)用UserDao的方法
        User user = userDao.findUserById(1);
        
        System.out.println(user.getUsername());
    }
}

說明:

  • 1、對于一些公共的代碼我們放在setUp方法中執(zhí)行,首先需要讀取配置文件,然后創(chuàng)建出工廠。我們在測試相關(guān)方法的時候需要傳入工廠。
  • 2.相關(guān)的測試方法我們在之前的例子中已經(jīng)有了,這里不再說明。
  • 3.在查詢的時候會自動提交,但是在刪除和更新的時候我們必須手動提交事務(wù)。當(dāng)然以后交給spring管理之后是不需要手動提交的。

3.2 hibernate和mybatis的區(qū)別和應(yīng)用的場景

  • Hibernate:是一個標(biāo)準(zhǔn)的orm框架。不需要程序員寫sql。對sql語句進(jìn)行優(yōu)化、修改比較困難。
    應(yīng)用場景:使用于需求變化不多的中小型的項目,比如:后臺管理系統(tǒng)等。

  • Mybatis:專注的是sql本身,需要自己寫sql。是一個不完全的orm框架。
    應(yīng)用場景:使用于需求變化較多的中小型的項目,比如:互聯(lián)網(wǎng)項目。

3.3 使用mybatis的方式開發(fā)dao層(工程mybatis02

3.3.1相關(guān)概念

  • mybatis通過工廠創(chuàng)建SqlSession,工廠是由SqlSessionFactoryBuilder創(chuàng)建的。通過單例模式來管理SqlSessionFactory,和spring整合之后使用單例管理SqlSessionFactory。但是將SqlSessionFactoryBuilder可以只當(dāng)成一個工具類即可,不需要使用單例管理SqlSessionFactory

  • SqlSession是一個面向用戶的接口,提供了很多操作數(shù)據(jù)庫的方法。SqlSession是線程不安全的,在SqlSession的實現(xiàn)類中除了有操作數(shù)據(jù)庫的方法,還有數(shù)據(jù)域的屬性。SqlSession最佳的應(yīng)用場合在方法體內(nèi),定義為局部變量。

3.3.2 mybatis推薦方式開發(fā)dao層

原始dao開發(fā)方法需要寫dao的接口和實現(xiàn)類
需要向dao實現(xiàn)類中注入SqlSessionFactory,在方法體內(nèi)通過SqlSessionFactory創(chuàng)建SqlSession。于是我們總結(jié)出了這種開發(fā)方式的幾個問題:

  • 1、 方法體中有很多大量的重復(fù)代碼。
  • 2、 在調(diào)用sqlSession方法時將statement的id寫死了。而且使用的是泛型,我們要是寫錯了,在編譯的時候是不會報錯的,不利于開發(fā)。

mabytis使用mapper代理的方法,只需要寫mapper接口,這個接口其實和dao接口一樣。不需要寫實現(xiàn)類,但是這樣的話其映射文件config/mapper/UserMapper.xml就必須尊需一定的規(guī)則:

  • (1)在UserMapper.xmlnamespace等于mapper接口的地址
<mapper namespace = "cn.itcast.mapper.UserMapper">
  • (2)UserMapper.java接口中的方法名和UserMapper.xmlstatement的id一致。方法的輸入類型和parameteType指定的類型一致。返回值和resultType指定的類型一致。

UserMapper.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代理開發(fā),namespace有重要作用  -->
<mapper namespace = "cn.itcast.mapper.UserMapper"><!-- namespace為mapper接口地址 -->

    <!-- 查詢,通過用戶id進(jìn)行查詢
    <select id="findUserById" parameterType="java.lang.Integer" resultType="cn.itcast.pojo.User">
        <!-- 最后不能有分號 -->
        SELECT * FROM USER WHERE id = #{value}
    </select>
    
    
    <!-- 根據(jù)用戶名模糊查詢用戶信息,可能返回多條結(jié)果 ,但是結(jié)果類型還是User-->
    <select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.pojo.User">
        <!-- SELECT * FROM USER WHERE username LIKE #{value} -->
        SELECT * FROM USER WHERE username LIKE '%${value}%'
    </select>
    
    <!-- 添加用戶-->
    <insert id="insertUser" parameterType="cn.itcast.pojo.User">
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            SELECT LAST_INSERT_ID()
        </selectKey>
        INSERT INTO USER(username, birthday, sex, address) VALUE(#{username}, #{birthday}, #{sex} ,#{address})
    </insert>
    
    <!-- 刪除用戶,根據(jù)id刪除用戶,需要輸入id值 -->
    <delete id="deleteUserById" parameterType="java.lang.Integer">
        DELETE FROM USER WHERE id = #{value}
    </delete>
    
    <!-- 根據(jù)id更新用戶。-->
    <update id="updateUserById" parameterType="cn.itcast.pojo.User">
        UPDATE USER SET username = #{username}, birthday = #{birthday}, sex = #{sex}, address = #{address} WHERE id = #{id}
    </update>
</mapper>

說明:和之前一樣,我們需要將此文件配置到全局配置文件中。

UserMapper.java

package cn.itcast.mapper;
import java.util.List;
import cn.itcast.pojo.User;
import cn.itcast.pojo.UserCustom;
import cn.itcast.pojo.UserQueryVo;

//用戶管理接口
public interface UserMapper {
    //根據(jù)id查詢用戶信息
    public User findUserById(int id );
    //模糊查詢
    public List<User> findUserByName(String username);
    
    //添加用戶
    public void insertUser(User user);
    
    //根據(jù)id查詢用戶
    public void deleteUserById(int id);
    
    //用戶信息綜合查詢
    public List<UserCustom> findUserList(UserQueryVo userQueryVo);
}

說明:可以看到其實和dao接口是一樣的。

  • 測試UserMapperTest.java
package cn.itcast.mapper;
import static org.junit.Assert.*;
import java.io.InputStream;
import java.util.List;
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 org.junit.Before;
import org.junit.Test;
import cn.itcast.pojo.User;
import cn.itcast.pojo.UserCustom;
import cn.itcast.pojo.UserQueryVo;

public class UserMapperTest {
    
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void setUp() throws Exception {
        // 創(chuàng)建sqlSessionFactory
        
        // mybatis配置文件
        String resource = "SqlMapConfig.xml";
        // 得到配置文件流
        InputStream is = Resources.getResourceAsStream(resource);
        // 創(chuàng)建會話工廠,要想build方法中傳入配置信息
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    }
    
    @Test
    public void testFindUserById() {
        //創(chuàng)建一個UserMapper的對象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //mybatis自動生成代理對象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        
        User user = userMapper.findUserById(1);
        System.out.println(user.getUsername());
        
        sqlSession.close();
    }
    @Test
    public void testfindUserByName() {
        //創(chuàng)建一個UserMapper的對象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //mybatis自動生成代理對象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        
        List<User> users = userMapper.findUserByName("小明");
        for(User user : users){
            System.out.println(user.getUsername());
        }
        sqlSession.close();
    }
}
  • 問題:mapper接口方法參數(shù)只能有一個,是否影響系統(tǒng)開發(fā)?
    系統(tǒng)框架中,dao層的代碼是被業(yè)務(wù)層公用的。即使mapper接口只有一個參數(shù),可以使用包裝類型的pojo滿足不同的業(yè)務(wù)方法的需求。

  • 注意:持久層中方法的參數(shù)可以用包裝類型(map。。。),而service方法中不建議使用包裝類型(不利于業(yè)務(wù)層的維護(hù)和可擴(kuò)展性)。

最后:這就是mybatis的基本使用方式。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,882評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,208評論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,746評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,666評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,477評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,960評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,047評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,200評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,726評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,617評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,807評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,327評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,049評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,425評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,674評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,432評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,769評論 2 372

推薦閱讀更多精彩內(nèi)容