1. 程式人生 > >Mybatis使用詳解和入門案例

Mybatis使用詳解和入門案例

前言 MyBatis和Hibernate一樣,是一個優秀的持久層框架。已經說過很多次了,原生的jdbc操作存在大量的重複性程式碼(如註冊驅動,建立連線,建立statement,結果集檢測等)。框架的作用就是把這些繁瑣的程式碼封裝,這樣可以讓程式設計師專注於sql語句本身。

MyBatis通過XML或者註解的方式將要執行的sql語句配置起來,並通過java物件和sql語句對映成最終執行的sql語句。最終由MyBatis框架執行sql,並將結果對映成java物件並返回。

正文 一,MyBatis的執行流程

mybatis配置檔案,包括Mybatis全域性配置檔案和Mybatis對映檔案,其中全域性配置檔案配置了資料來源、事務等資訊;對映檔案配置了SQL執行相關的  資訊。 mybatis通過讀取配置檔案資訊(全域性配置檔案和對映檔案),構造出SqlSessionFactory,即會話工廠。 通過SqlSessionFactory,可以建立SqlSession即會話。Mybatis是通過SqlSession來操作資料庫的。 SqlSession本身不能直接操作資料庫,它是通過底層的Executor執行器介面來操作資料庫的。Executor介面有兩個實現類,一個是普通執行器,一個是快取執行器(預設)。 Executor執行器要處理的SQL資訊是封裝到一個底層物件MappedStatement中。該物件包括:SQL語句、輸入引數對映資訊、輸出結果集對映資訊。其中輸入引數和輸出結果的對映型別包括java的簡單型別、HashMap集合物件、POJO物件型別。 二,MyBatis經典入門案例(原始DAO實現使用者表的增刪改查)

1,環境準備

Jdk環境:jdk1.7.0_72 Ide環境:eclipse indigo 資料庫環境:MySQL 5.1 Mybatis:3.2.7 mysql建庫:

CREATE TABLE `user4` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `username` varchar(20) ,   `password` varchar(20) ,   `age` int(11) ,   PRIMARY KEY (`id`) ) 1 2 3 4 5 6 7 專案目錄如下: 

下面一一講解這些檔案。

2,全域性配置檔案:SqlMapConfig.xml

主要是2個標籤:

environments-用於獲取連線池連線,將來與spring整合時,這個就不要啦,由spring來配置資料庫連線。

mappers-用於引用對映檔案。

<?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>     <environments default="development">         <environment id="development">             <transactionManager type="JDBC"/>             <dataSource type="POOLED">                 <property name="driver" value="com.mysql.jdbc.Driver"/>                 <property name="url" value="jdbc:mysql://localhost:3306/user"/>                 <property name="username" value="root"/>                 <property name="password" value="123456"/>             </dataSource>         </environment>     </environments>     <mappers>         <mapper resource="User.xml"/>     </mappers> </configuration> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 3,建立主體類:User.class

package com.jimmy.domain;

public class User {     private Integer id;     private String username;     private String password;     private Integer age;     //get,set方法省略 } 1 2 3 4 5 6 7 8 9 4,建立對映檔案:User.xml

對映檔案就是框架的核心啦,下面這個檔案就配置了java物件與資料庫表之間的對映。

我們看到,其中4個標籤:select,insert ,delete ,update 分別對應著“查,增,刪,改”操作。每個標籤中還有一些屬性,下面來解釋下:

id:給標籤體內的sql操作起個名字,方便呼叫。 parameterType:傳入引數的型別。傳入java型別,轉化為sql型別,新增到sql語句上。 resultType:返回結果型別。sql結果集轉化為java型別並返回。 <?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屬性,不然會報錯,可看做包名--> <mapper namespace="user">     <select id="findUserById" parameterType="int" resultType="com.jimmy.domain.User">         select * from user4 where id = #{id}     </select>     <select id="findUserAll" resultType="com.jimmy.domain.User">         select * from user4      </select>     <insert id="insertUser" parameterType="com.jimmy.domain.User">         insert into user4(username,password,age) values(#{username},#{password},#{age})     </insert>     <delete id="deleteUserById" parameterType="int">         delete from user4 where id=#{id}     </delete>     <update id="updateUserPassword" parameterType="com.jimmy.domain.User">         update user4 set password=#{password} where id=#{id}     </update> </mapper> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 5,建立dao介面和實現類

package com.jimmy.dao;

import java.util.List;

import com.jimmy.domain.User;

// 介面 public interface UserDao {       public User findUserById(int id) throws Exception ;     public List<User> findAllUsers() throws Exception;     public void insertUser(User user) throws Exception;     public void deleteUserById(int id) throws Exception;     public void updateUserPassword(User user) throws Exception; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 package com.jimmy.dao.impl;

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 com.jimmy.dao.UserDao; import com.jimmy.domain.User;

// 實現類 public class UserDaoImpl implements UserDao {

    public User findUserById(int id) throws Exception {         String resource = "SqlMapConfig.xml";         InputStream inputStream = Resources.getResourceAsStream(resource);         SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);         SqlSession session = factory.openSession();         //---------------         User user = session.selectOne("user.findUserById",id); //引數一:namespace.id                    //--------------         session.close();         return user;     }

    public List<User> findAllUsers() throws Exception {         String resource = "SqlMapConfig.xml";         InputStream inputStream = Resources.getResourceAsStream(resource);         SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);         SqlSession session = factory.openSession();         //---------------------         List<User> users = session.selectList("user.findUserAll");         //----------------------         session.close();         return users;     }

    public void insertUser(User user) throws Exception {         String resource = "SqlMapConfig.xml";         InputStream inputStream = Resources.getResourceAsStream(resource);         SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);         SqlSession session = factory.openSession();         //---------------------         session.insert("user.insertUser", user);         session.commit();   //增刪改,一定一定要加上commit操作         //----------------------         session.close();     }

    public void deleteUserById(int id) throws Exception {         String resource = "SqlMapConfig.xml";         InputStream inputStream = Resources.getResourceAsStream(resource);         SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);         SqlSession session = factory.openSession();         //---------------------         session.delete("user.deleteUserById", id);         session.commit();   //增刪改,一定一定要加上commit操作         //----------------------         session.close();     }

    public void updateUserPassword(User user) throws Exception {         String resource = "SqlMapConfig.xml";         InputStream inputStream = Resources.getResourceAsStream(resource);         SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);         SqlSession session = factory.openSession();         //---------------------         session.update("user.updateUserPassword", user);         session.commit();   //增刪改,一定一定要加上commit操作         //----------------------         session.close();     } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 6,編寫測試類

package com.jimmy.test;

import java.util.List; import org.junit.Test; import com.jimmy.dao.UserDao; import com.jimmy.dao.impl.UserDaoImpl; import com.jimmy.domain.User;

public class Test3 {     @Test     public void testFindUserById() throws Exception{         UserDao userDao = new UserDaoImpl();         User user = userDao.findUserById(7);         System.out.println(user);     }     @Test     public void testFindAllUser() throws Exception{         UserDao userDao = new UserDaoImpl();         List<User> findAllUsers = userDao.findAllUsers();         for (User user2 : findAllUsers) {                        System.out.println(user2);         }     }     @Test     public void testInsertUser() throws Exception{         UserDao userDao = new UserDaoImpl();         User user = new User();         user.setUsername("張三");         user.setPassword("lalal");         user.setAge(12);         userDao.insertUser(user);     }     @Test     public void testDeleteUserById() throws Exception{         UserDao userDao = new UserDaoImpl();         userDao.deleteUserById(3);     }     @Test     public void testUpdateUserPassword() throws Exception{         UserDao userDao = new UserDaoImpl();         User user = new User();         user.setId(9);         user.setPassword("newpassword");         userDao.updateUserPassword(user);     } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 至此,一個完整的Mybatis入門案例已經初步完成。

回過頭來看DAO的實現類,原始dao開發存在一些問題:

存在一定量的模板程式碼。比如:通過SqlSessionFactory建立SqlSession;呼叫SqlSession的方法操作資料庫;關閉Sqlsession。 存在一些硬編碼。呼叫SqlSession的方法操作資料庫時,需要指定statement的id,這裡存在了硬編碼。 三,Mapper代理開發模式

Mapper代理的開發方式,程式設計師只需要編寫mapper介面(相當於dao介面)即可,而不同再寫dao實現類啦。Mybatis會自動的為mapper介面生成動態代理實現類。不過要實現mapper代理的開發方式,需要遵循一些開發規範。

mapper介面的全限定名要和mapper對映檔案的namespace的值相同。 mapper介面的方法名稱要和mapper對映檔案中的statement的id相同。 mapper介面的方法引數只能有一個,且型別要和mapper對映檔案中statement的parameterType的值保持一致。 mapper介面的返回值型別要和mapper對映檔案中statement的resultType值或resultMap中的type值保持一致。 上面4句話的意思是:介面的包名,類名,引數,返回值分別對應著對映檔案的namespace,id,parameterType,resultType。

下面來改造上面的例子。

1,環境準備,同上。  2,全域性配置檔案,同上。記得引用新的對映檔案。  3,建立主題類,同上。  4,建立對映檔案:UserMapper.xml。檔名一般加上“Mapper”。

下面這個檔案跟原始dao程式設計只有一點不同,就是namespace值。

<?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屬性,不然會報錯,且mapper開發時設定為Mapper介面的全限定名--> <mapper namespace="com.jimmy.dao.UserMapper">     <select id="findUserById" parameterType="int" resultType="com.jimmy.domain.User">         select * from user4 where id = #{id}     </select>     <select id="findUserAll" resultType="com.jimmy.domain.User">         select * from user4      </select>     <insert id="insertUser" parameterType="com.jimmy.domain.User">         insert into user4(username,password,age) values(#{username},#{password},#{age})     </insert>     <delete id="deleteUserById" parameterType="int">         delete from user4 where id=#{id}     </delete>     <update id="updateUserPassword" parameterType="com.jimmy.domain.User">         update user4 set password=#{password} where id=#{id}     </update> </mapper> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 5,建立Mapper介面,這裡就沒有實現類啦。

注意,函式一定要注意4點規範。

package com.jimmy.dao;

import java.util.List;

import com.jimmy.domain.User;

public interface UserMapper {     public User findUserById(int id);     public List<User> findUserAll();     public void insertUser(User user);     public void deleteUserById(int id);     public void updateUserPassword(User user); } 1 2 3 4 5 6 7 8 9 10 11 12 13 6,編寫測試類

package com.jimmy.test;

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.Test;

import com.jimmy.dao.UserMapper; import com.jimmy.domain.User;

public class Test1 {     @Test     public void findUserByID() throws Exception{         String resource = "SqlMapConfig.xml";         InputStream inputStream = Resources.getResourceAsStream(resource);         SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);         SqlSession session = factory.openSession();         //---------------         UserMapper userMapper = session.getMapper(UserMapper.class);         User user = userMapper.findUserById(2);         System.out.println(user);         //--------------         session.close();     }     @Test     public void findAll() throws Exception{         String resource = "SqlMapConfig.xml";         InputStream inputStream = Resources.getResourceAsStream(resource);         SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);         SqlSession session = factory.openSession();         //---------------------         UserMapper mapper = session.getMapper(UserMapper.class);         List<User> user = mapper.findUserAll();         for (User user2 : user) {                        System.out.println(user2);         }         //----------------------         session.close();     }     @Test     public void insertTest() throws Exception{         String resource = "SqlMapConfig.xml";         InputStream inputStream = Resources.getResourceAsStream(resource);         SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);         SqlSession session = factory.openSession();         //---------------------         User user = new User();         user.setUsername("lalala");         user.setPassword("asdf");         user.setAge(12);

        UserMapper mapper = session.getMapper(UserMapper.class);         mapper.insertUser(user);         session.commit();         //----------------------         session.close();     }     @Test     public void deleteUserById() throws Exception{         String resource = "SqlMapConfig.xml";         InputStream inputStream = Resources.getResourceAsStream(resource);         SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);         SqlSession session = factory.openSession();         //---------------------         UserMapper mapper = session.getMapper(UserMapper.class);         mapper.deleteUserById(2);         session.commit();         //----------------------         session.close();     }     @Test     public void updateUserPassword() throws Exception{         String resource = "SqlMapConfig.xml";         InputStream inputStream = Resources.getResourceAsStream(resource);         SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);         SqlSession session = factory.openSession();         //---------------------         User user = new User();         user.setId(4);         user.setPassword("newPassword3");

        UserMapper mapper = session.getMapper(UserMapper.class);         mapper.updateUserPassword(user);         session.commit();         //----------------------         session.close();     } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 我們看到,現在已經不需要再寫dao介面的實現類啦,而是框架通過對映檔案為我們生成代理類。而那些重複性的程式碼已經轉移到測試程式碼中了,我們在整合spring和Mybatis時,這些重複性程式碼都會在配置檔案中配置。 ---------------------  作者:name_s_Jimmy  來源:CSDN  原文:https://blog.csdn.net/qq_32166627/article/details/70741729  版權宣告:本文為博主原創文章,轉載請附上博文連結!