MyBatis的基本使用
1、MyBatis的基本介紹
1.1、MVC三層架構
MVC三層架構:M 數據訪問層、V 界面層、C 業務邏輯層。
三層的職責:
- V 界面層:View 對數據的展示代碼,比如JSP、html頁面,就是專門用來展示數據,美化頁面的。
- C 業務邏輯層:Controller 控制,接收界面層傳遞的數據,計算邏輯,調用數據訪問層來獲取數據并且交付給界面層展示。比如:Servlet、service
- M 數據訪問層:Model 模型,代表著業務邏輯代碼與數據庫代碼,就是訪問數據,對數據庫進行增刪改查等等。
三層的處理請求的交互:
用戶 ---> 界面層 ---> 業務邏輯層 ---> 數據訪問層 ---> DB數據庫
1.2、mybatis的基本介紹
為什么使用 mybatis ?在傳統的 JDBC 中,我們除了需要自己提供 SQL 外,還必須操作 Connection、Statment、ResultSet,不僅如此,為了訪問不同的表,不同字段的數據,我們需要些很多雷同模板化的代碼,顯得繁瑣又枯燥。
而我們在使用了 MyBatis 之后,只需要提供 SQL 語句就好了,其余的諸如:建立連接、操作 Statment、ResultSet、釋放資源、處理 JDBC 相關異常等等都可以交給 MyBatis 去處理,我們的關注點于是可以就此集中在 SQL 語句上,關注在增刪改查這些操作層面上。mybatis 提供了循環 SQL,可以將查詢的結果集封裝為 java 對象、list 集合。并且 MyBatis 支持使用簡單的 XML 或注解來配置和映射原生信息,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對象)映射成數據庫中的記錄。
2、mybatis 的基本使用
新建一個 maven JavaSE 項目。先需要添加依賴,除了 mybatis 依賴外還需要添加 mysql 的驅動依賴:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.12</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.1</version> </dependency>
新建一個 resources 目錄,在該目錄下添加 mybatis 的配置文件 mybatis-config.xml。
項目的最終目錄結構如下:

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> <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/test"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <mappers> <mapper resource="sqlmap/user.xml"/> </mappers> </configuration>
上面的配置文件中,我們指定了一個 sql 映射文件 sqlmap/user.xml 文件。我們在 resources 目錄下新建一個 sqlmap 目錄,在該文件夾下建立 sql 的映射文件。
在 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="user"> <select id="findUserById" resultType="entity.User"> select * from user where id = #{id} </select> <select id="findUserInfo" resultType="entity.User"> select id,name,password from user where id = #{id} </select> </mapper>
sql 映射文件中在 mapper 標簽下寫 sql 語句,mapper 標簽的 namespace 指定命名空間,命名空間應該唯一,名稱可以自定義。sql 語句中通過 id 唯一標識該語句,在使用 sql 時通過 “命名空間.id” 形式來使用。resultType 指定的是 select 語句的查詢結果類型。
然后建一個實體類。我們要查詢的是 user 表信息,該表結構如下:

所以我們建一個 User 實體類,該實體類必須有無參構造函數,否則可能會有問題。
package entity; public class User { private Integer id; private String name; private String password; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", password='" + password + '\'' + '}'; } }
然后是 UserDao 接口類:
package dao; import entity.User; import java.io.IOException; public interface UserDao { User finUserById(Integer userId) throws IOException; }
UserDaoImpl 實現類:
package dao.impl; import dao.UserDao; import entity.User; 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; public class UserDaoImpl implements UserDao { @Override public User finUserById(Integer userId) throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); //獲取sqlsession對象 SqlSession session = factory.openSession(); //執行sql語句。通過sql映射文件中,sql語句的標識來指定需要執行的sql語句 User resultUser = session.selectOne("user.findUserById", userId); //參數一:namespace.id //關閉sqlsession對象 session.close(); return resultUser; } }
最后通過一個單元測試類來測試:
package test; import dao.UserDao; import dao.impl.UserDaoImpl; import entity.User; import org.junit.Test; import java.io.IOException; public class Test01 { @Test public void test01() throws IOException { UserDao userDao = new UserDaoImpl(); User user = userDao.finUserById(1); System.out.println(user); } }
2.1、mybatis 查詢
大致流程跟上面一樣,只需修改 sql 映射文件如下:
<?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="user"> <select id="findUserById" parameterType="int" resultType="entity.User"> select * from user where id = #{id} </select> <select id="listUser" resultType="entity.User"> select * from user </select> </mapper>
使用單元測試類來查詢,查詢語句如下:
public class Test01 { @Test public void test02() throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); //獲取sqlsession對象 SqlSession session = factory.openSession(); //查詢對象 User resultUser = session.selectOne("user.findUserById", 1); //參數一:namespace.id System.out.println("查詢對象的結果:" + resultUser); //查詢list集合 List list = session.selectList("user.listUser"); System.out.println("查詢集合的結果:" + list); //關閉sqlsession對象 session.close(); } }
查詢結果:

2.2、mybatis 增刪改
增刪改操作跟查詢操作差不多,但是 mybatis 中默認是不會自動提交事務的,所以在進行增刪改操作時一定要手動去提交事務,否則不會生效。
sql 映射文件如下:
<?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="user"> <insert id="adduser" parameterType="entity.User"> insert into user (id, name, password) values (#{id},#{name},#{password}) </insert> <delete id="deleteuser" parameterType="entity.User"> delete from user where id = #{id} </delete> <update id="updateuser" parameterType="entity.User"> update user set name=#{name} where id=#{id} </update> </mapper>
在 sqlmapper 映射文件中,parameterType 指定的是要求輸入參數的類型,resultType 指定的是輸出的結果類型。
使用單元測試類來進行增刪改,語句如下:
public class Test01 { @Test public void test03() throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); //獲取sqlsession對象。 SqlSession session = factory.openSession(); //通過openSession()獲取的是非自動提交的對象,可以通過openSession(true)來獲取自動提交的sqlsession對象,這樣就不用再手動commit了。 //增加操作 User user1 = new User(); user1.setId(6); user1.setName("newUser"); user1.setPassword("123"); int addResult = session.insert("user.adduser", user1); //一定要手動提交事務。或者最后再一起提交也行 session.commit(); System.out.println("增加操作的結果:" + addResult); //刪除操作 User user2 = new User(); user2.setId(2); int delResult = session.delete("user.deleteuser", user2); //手動提交事務 session.commit(); System.out.println("刪除操作的結果:" + delResult); //修改操作 User user3 = new User(); user3.setId(3); user3.setName("newName"); int updateResult = session.update("user.updateuser", user3); //手動提交事務 session.commit(); System.out.println("刪除操作的結果:" + updateResult); //關閉sqlsession對象 session.close(); } }
mybatis 中通過 openSession() 默認獲取的是非自動提交的對象,可以通過 openSession(true) 來獲取自動提交的 sqlsession 對象,這樣就不用再手動 commit 了。
操作結果:

3、mybaits 的配置文件
3.1、mybatis 配置文件
MyBatis 的配置文件 mybatis-config.xml 包含了數據庫連接信息,同時還包含了 Mapper 映射文件的加載路徑、全局參數以及類別別名等一系列MyBatis的核心配置信息。
<?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> <!--環境配置,即數據庫的連接信息,可以配置多個。 default指定默認使用哪個數據庫配置信息 --> <environments default="development"> <!--environment:一個數據庫的配置信息。id指定該配置的名稱,名稱可自定義--> <environment id="development"> <!--transactionManager指定mybatis的事務管理器。type:jdbc 表示使用jdbc中的connection對象的commit、rollback做事務管理--> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <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="123456"/> </dataSource> </environment> </environments> <mappers> <!--每個mapper標簽指定一個sql映射文件的位置--> <mapper resource="sqlmap/user.xml"/> </mappers> </configuration>
MyBatis 使用場景: 在進行 MyBatis 開發時,我們的大部分精力都放在了 SQL 映射文件上。 MyBatis 的特點就是以 SQL 語句為核心的不完全的 ORM(關系型映射)框架。與 Hibernate 相比,Hibernate 的學習成本比較高,而 SQL 語句并不需要開發人員完成,只需要調用相關 API 即可。這對于開發效率是一個優勢,但是缺點是沒辦法對 SQL 語句進行優化和修改。而 MyBatis 雖然需要開發人員自己配置 SQL 語句,MyBatis 來實現映射關系,但是這樣的項目可以適應經常變化的項目需求。所以使用 MyBatis 的場景是:對 SQL 優化要求比較高,或是項目需求或業務經常變動。
3.1.1、使用獨立的JDBC配置文件
我們可以把 jdbc 的配置單獨作為一個配置文件,然后再在 mybatis 的配置文件中引入 jdbc 的配置文件作為 jdbc 的配置。
在 resource 目錄下新建一個 jdbc.properties 配置文件:

該文件內容如下:
prop.driverClass=com.mysql.jdbc.Driver prop.url=jdbc:mysql://localhost:3306/test prop.username=root prop.password=123456s
在 mybatis 中引入該配置文件中的配置:
<?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> <!--引入jdbc配置文件。文件路徑是相對于類根路徑--> <properties resource="jdbc.properties"></properties> <!--環境配置,即數據庫的連接信息,可以配置多個。 default指定默認使用哪個數據庫配置信息 --> <environments default="development"> <!--environment:一個數據庫的配置信息。id指定該配置的名稱,名稱可自定義--> <environment id="development"> <!--transactionManager指定mybatis的事務管理器。type:jdbc 表示使用jdbc中的connection對象的commit、rollback做事務管理--> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${prop.driverClass}"/> <property name="url" value="${prop.url}"/> <property name="username" value="${prop.username}"/> <property name="password" value="${prop.password}"/> </dataSource> </environment> </environments> <mappers> <!--每個mapper標簽指定一個sql映射文件的位置--> <mapper resource="sqlmap/user.xml"/> <mapper resource="sqlmap/student.xml"/> </mappers> </configuration>
3.2、配置日志
在使用 mybatis 進行開發的時候,如果我們要想從 sql 的映射文件中找出最終執行的完整的 sql 會非常的難,這個時候我們可以通過配置日志來將最終執行的完整的 sql 打印出來。
配置日志只需在 mybatis 的配置文件中添加以下配置:
<!--配置日志--> <settings> <setting name="logImpl" value="STDOUT_LOGGING" /> </settings>
配置文件示例:
<?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> <!--配置日志--> <settings> <setting name="logImpl" value="STDOUT_LOGGING" /> </settings> <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/test"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <mappers> <mapper resource="sqlmap/user.xml"/> </mappers> </configuration>
屬性名:logImpl
描述:指定 MyBatis 所用日志的具體實現,未指定時將自動查找。
有效值:SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING
配置日志之后,我們通過 mybatis 執行 sql,可以在控制臺看到日志輸出信息,類似如下:

4、mapper代理開發模式
通過使用 Mapper 代理的開發方式,程序員只需要編寫 mapper 的接口類(相當于dao接口)即可,而不用再寫 dao 的實現類,這樣能讓代碼更加方便簡潔。Mybatis 會自動地為接口類生成動態代理實現類
不過要實現 mapper 代理的開發方式,需要遵循一些開發規范:
- sql mapper 映射文件的 namespace 寫成接口類的完整類名。即 接口類的完整類名 == 映射文件的 namespace
- sql mapper 映射文件中的 sql 語句的 id 和接口類的方法名稱相同。即 接口類的方法名 == 映射文件的 sql 的id
- 接口類的方法參數只能有一個,且類型要和 sql mapper 映射文件中 sql 語句的 parameterType 的值保持一致。即 接口類的方法的參數 == 映射文件的 sql 的 parameterType
- 接口類方法的返回值類型要和 sql mapper 映射文件中 sql 語句的 resultType 值或 resultMap 中的 type 值保持一致。即 接口類的返回值 == 映射文件的 sql 的 resultType
Mybatis 會自動地為接口類生成動態代理實現類,并創建該類的對象。
在調用方法時,mybatis 會根據接口類的方法名來找到 sql 映射文件中對應的 sql 語句。并且 mybatis 通過接口類中方法的返回值可以確定應該調用 sqlsession 中的那個方法來進行 sql 操作,比如如果返回值是 list,則調用 selectList() 方法
4.1、mapper 代理開發模式的使用
mapper 代理開發模式跟正常使用 mybatis 差不多,只不過 sql mapper 映射文件和接口類需要符合一定的規范。
實現示例:
下面操作的是 student 表,表結構如下:

首先建立 sql 映射文件,映射文件 namespace 應該是接口類的完整類名。映射文件 student.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="dao.StudentDao"> <select id="findStudentById" parameterType="int" resultType="entity.Student"> select * from student where id = #{id} </select> <select id="findStudentAll" resultType="entity.Student"> select * from Student </select> <insert id="insertStudent" parameterType="entity.Student"> insert into Student(id,name,age) values(#{id},#{name},#{age}) </insert> <delete id="deleteStudentById" parameterType="int"> delete from Student where id=#{id} </delete> <update id="updateStudentName" parameterType="entity.Student"> update Student set name=#{name} where id=#{id} </update> </mapper>
下面建立 StudentDao 接口類,只需要接口類接口,無需書寫實現類,Mybatis 會自動地為接口類生成動態代理實現類。
接口類的方法名、參數和返回值要和 sql 映射文件中定義的對應,StudentDao 接口類代碼:
package dao; import entity.Student; import java.util.List; public interface StudentDao { public Student findStudentById(int id); public List<Student> findStudentAll(); public void insertStudent(Student Student); public void deleteStudentById(int id); public void updateStudentName(Student Student); }
然后就可以使用 mybatis 進行操作 sql 了。下面使用單元測試類進行測試:
public class Test02 { @Test public void test01() throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session = factory.openSession(); StudentDao studentDao = session.getMapper(StudentDao.class); //查詢對象 Student student = studentDao.findStudentById(2); System.out.println(student); //查詢集合 List list = studentDao.findStudentAll(); System.out.println(list); //增加 Student student1 = new Student(); student1.setName("aa"); student1.setAge(33); studentDao.insertStudent(student1); //刪除 studentDao.deleteStudentById(2); //修改 Student student2 = new Student(); student2.setId(1); student2.setName("newName"); studentDao.updateStudentName(student2); //需要手動提交事務 session.commit(); session.close(); } }

浙公網安備 33010602011771號