🏠 個人首頁:csdn春和
📚 推薦專欄:更多專欄盡在首頁!
Scala專欄(spark必學語言 已完結)
JavaWeb專欄(從入門到實戰超詳細!!!)
SSM專欄 (更新中…)
📖 本期文章:Mybatis(1)—— 快速入門使用持久層架構Mybatis
如果對您有幫助還請三連支援,定會一 一回訪!🙋🏻♂️
📌本文目錄
- 一、Mybatis簡介
-
- 1.1、原始jdbc操作
- 1.2、原始jdbc操作的缺點
- 1.3、Mybatis是什麼?
- 二、Mybatis的快速入門
- 三、mybatis映射檔案概述
-
- 3.1、mybatis插入資料操作
- 3.2、mybatis的修改資料操作
- 3.3、mybatis的删除資料操作
- 3.4、知識小結
- 四、mybatis核心配置檔案概述
-
- 4.1、mybatis核心配置檔案層級關系
- 4.2、mybatis常用配置解析
-
- 4.2.1、environments标簽
- 4.2.2、mapper标簽
- 4.2.3、Properties标簽
- 4.2.4、typeAliases标簽
- 4.2.5、知識小結
- 五、mybatis相應的API
-
- 5.1、SqlSession工廠建構起SqlSessionFactoryBuilder
- 6.2 SqlSession工廠對象SqlSessionFactory
- 6.3 SqlSession會話對象
- 六、Mybatis的Dao層實作
-
- 6.1、傳統開發方式
- 6.2、代理開發方式
- 6.3、知識小結
- 七、mybatis映射檔案深入
-
- 7.1、動态sql
- 7.2、開發環境搭建
- 7.3、動态Sql之if
- 7.4、動态Sql之foreach
- 7.5、Sql片段的抽取
- 7.6、知識小結
- 八、mybatis核心配置檔案深入
-
- 8.1、typeHandlers
- 8.2、plugins
- 8.3、知識小結
- 九、mybatis開發小細節
-
- 9.1、IDEA開發mybatis模闆設定
-
- 9.1.1、核心配置檔案模闆
- 9.1.2、mapper映射檔案模闆
- 9.2、封裝SqlSessionUtils工具類
- 9.3、mybatis擷取參數的兩種方式

一、Mybatis簡介
1.1、原始jdbc操作
使用·原是jdbc的方式查詢資料
public class SelectData {
public static void main(String[] args) {
try {
// 1、注冊驅動
Class.forName("com.mysql.jdbc.Driver");
// 2、獲得連接配接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/study", "root", "123456");
// 3、獲得satement
Statement statement = connection.createStatement();
// 4、定義sql
String sql = "select * from user";
// 5、之心sql
ResultSet resultSet = statement.executeQuery(sql);
// 6、周遊結果集
while (resultSet.next()){
int id = resultSet.getInt(1);
String name = resultSet.getString(2);
String passwd = resultSet.getString(3);
System.out.println(id + "---" + name +"---" + passwd);
}
// 7、釋放資源
resultSet.close();
statement.close();
connection.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
1.2、原始jdbc操作的缺點
原始jdbc開發存在的問題如下:
①資料庫連接配接建立、釋放頻繁造成系統資源浪費進而影響系統性能
②sql 語句在代碼中寫死,造成代碼不易維護,實際應用 sql 變化的可能較大,sql 變動需要改變java代碼。
③查詢操作時,需要手動将結果集中的資料手動封裝到實體中。插入操作時,需要手動将實體的資料設定到sql語句的占位符位置
應對上述問題給出的解決方案:
①
②
使用資料庫連接配接池初始化連接配接資源
③
将sql語句抽取到xml配置檔案中
使用反射、内省等底層技術,自動将實體與表進行屬性與字段的自動映射
1.3、Mybatis是什麼?
mybatis 是一個優秀的基于java的持久層架構,它内部封裝了jdbc,使開發者
隻需要關注sql語句本身
,而不需要花費精力去處理加載驅動、建立連接配接、建立statement等繁雜的過程。
mybatis通過xml或注解的方式将要執行的各種 statement配置起來,并通過java對象和statement中sql的動态參數進行映射生成最終執行的sql語句。
最後mybatis架構執行sql并将結果映射為java對象并傳回。采用ORM思想解決了實體和資料庫映射的問題,對jdbc 進行了封裝,屏蔽了jdbc api 底層通路細節,使我們不用與jdbc api 打交道,就可以完成對資料庫的持久化操作。
Mybatis官網位址:http://www.mybatis.org/mybatis-3/
二、Mybatis的快速入門
開發步驟:
①添加MyBatis的坐标
②建立user資料表
③編寫User實體類
④編寫映射檔案UserMapper.xml
⑤編寫核心檔案SqlMapConfig.xml
⑥編寫測試類
1、環境準備
建立一個新的module。導入相應的依賴坐标
<dependencies>
<!-- mysql連接配接驅動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
<!-- mybatis坐标 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!-- junit單元測試-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- log4j日志列印 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
2、建立一張表
3、建立實體類
public class User {
private int id; // 使用者id
private String username; // 使用者名
private String password; // 密碼
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
4、編寫UserMapper映射檔案
<?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="userMapper">
<select id="findAll" resultType="com.zhou.mybatis.domain.User">
select * from user
</select>
</mapper>
5、編寫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>
<!-- 配置資料源的環境 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/study"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 加載映射檔案 -->
<mappers>
<mapper resource="com/zhou/mybatis/mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
6、編寫測試代碼
public class MybatisTest {
@Test
public void test1() throws IOException {
// 1、加載核心配置檔案
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
// 2、獲得session工廠對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
// 3、獲得session會話對象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 4、執行操作 參數就是 namespace + id
List<User> userList = sqlSession.selectList("userMapper.findAll");
// 5、列印資料
System.out.println(userList);
// 6、釋放資源
sqlSession.close();
}
}
7、測試
三、mybatis映射檔案概述
3.1、mybatis插入資料操作
1、編寫UserMapper映射檔案
<mapper namespace="userMapper">
<!-- 查詢操作 -->
<select id="findAll" resultType="com.zhou.mybatis.domain.User">
select *
from user
</select>
<!-- 插入操作 parameterType是傳入的參數類型 參數是User類型 -->
<insert id="addUser" parameterType="com.zhou.mybatis.domain.User">
insert into user
values (#{id}, #{usernaame}, #{password})
</insert>
</mapper>
2、編寫測試代碼
@Test // 插入操作
public void test2() throws IOException {
// 模拟user對象
User user = new User();
user.setId(3);
user.setUsername("張無忌");
user.setPassword("123");
// 1、加載核心配置檔案
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
// 2、擷取session工廠對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
// 3、獲得session會話對象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 4、執行操作
sqlSession.insert("userMapper.addUser",user);
// 5、釋放資源
sqlSession.close();
}
3、測試
這是由于mybatis預設是不送出事務的,當你進行增删改操作的時候,需要手動送出事務
插入操作需要注意的問題
• 插入語句使用insert标簽
• 在映射檔案中使用parameterType屬性指定要插入的資料類型
•Sql語句中使用
#{實體屬性名}
方式引用實體中的屬性值
•插入操作使用的API是sqlSession.insert(“命名空間.id”,實體對象);
•插入操作涉及資料庫資料變化,是以要使用sqlSession對象顯示的送出事務,即
sqlSession.commit()
3.2、mybatis的修改資料操作
1、編寫UserMapper映射檔案
<!-- 修改操作 -->
<update id="updateUser" parameterType="com.zhou.mybatis.domain.User">
update user
set username=#{username},
password=#{password}
where id = #{id}
</update>
2、編寫測試代碼
@Test // 修改操作
public void test3() throws IOException {
// 模拟user對象
User user = new User();
user.setId(3);
user.setUsername("孫悟空");
user.setPassword("000");
// 1、加載核心配置檔案
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
// 2、擷取session工廠對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
// 3、獲得session會話對象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 4、執行操作
sqlSession.update("userMapper.updateUser",user);
// TODO 注意 mybatis在執行更新操作的時候 需要送出事務
sqlSession.commit();
// 5、釋放資源
sqlSession.close();
}
3、測試
更新操作注意的問題:
• 修改語句使用update标簽
• 修改操作使用的API是sqlSession.update(“命名空間.id”,實體對象);
3.3、mybatis的删除資料操作
1、編寫UserMapper映射檔案
2、編寫測試代碼
@Test // 删除操作
public void test4() throws IOException {
// 1、加載核心配置檔案
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
// 2、擷取session工廠對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
// 3、獲得session會話對象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 4、執行操作
sqlSession.delete("userMapper.deleteUser",3);
// TODO 注意 mybatis在執行更新操作的時候 需要送出事務
sqlSession.commit();
// 5、釋放資源
sqlSession.close();
}
3、測試
删除操作注意問題;
• 删除語句使用delete标簽
•Sql語句中使用#{任意字元串}方式引用傳遞的單個參數
•删除操作使用的API是sqlSession.delete(“命名空間.id”,Object);
3.4、知識小結
增删改查映射配置與API:
查詢資料: List<User> userList = sqlSession.selectList("userMapper.findAll");
<select id="findAll" resultType="com.itheima.domain.User">
select * from User
</select>
添加資料: sqlSession.insert("userMapper.add", user);
<insert id="add" parameterType="com.itheima.domain.User">
insert into user values(#{id},#{username},#{password})
</insert>
修改資料: sqlSession.update("userMapper.update", user);
<update id="update" parameterType="com.itheima.domain.User">
update user set username=#{username},password=#{password} where id=#{id}
</update>
删除資料:sqlSession.delete("userMapper.delete",3);
<delete id="delete" parameterType="java.lang.Integer">
delete from user where id=#{id}
</delete>
四、mybatis核心配置檔案概述
4.1、mybatis核心配置檔案層級關系
4.2、mybatis常用配置解析
4.2.1、environments标簽
資料庫環境的配置,支援多環境配置
其中,**事務管理器(transactionManager)**類型有兩種:
•JDBC:這個配置就是直接使用了JDBC 的送出和復原設定,它依賴于從資料源得到的連接配接來管理事務作用域。
•MANAGED:這個配置幾乎沒做什麼。它從來不送出或復原一個連接配接,而是讓容器來管理事務的整個生命周期(比如 JEE 應用伺服器的上下文)。 預設情況下它會關閉連接配接,然而一些容器并不希望這樣,是以需要将 closeConnection 屬性設定為 false 來阻止它預設的關閉行為。
其中,資料源(dataSource)類型有三種:
•UNPOOLED:這個資料源的實作隻是每次被請求時打開和關閉連接配接。
•POOLED:這種資料源的實作利用“池”的概念将 JDBC 連接配接對象組織起來。
•JNDI:這個資料源的實作是為了能在如 EJB 或應用伺服器這類容器中使用,容器可以集中或在外部配置資料源,然後放置一個 JNDI 上下文的引用。
4.2.2、mapper标簽
該标簽的作用是加載映射檔案的
,加載方式有如下幾種:
1、使用相對于類路徑的資源引用,例如:
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
2、使用完全限定資源定位符(URL),例如:
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
3、使用映射器接口實作類的完全限定類名,例如:
<mapper class="org.mybatis.builder.AuthorMapper"/>
4、将包内的映射器接口實作全部注冊為映射器,包掃描,例如:
<package name="org.mybatis.builder"/>
4.2.3、Properties标簽
實際開發中,習慣将資料源的配置資訊單獨抽取成一個properties檔案,該标簽可以加載外部配置的properties檔案
比如我們将資料源資訊抽取到外部檔案中;
4.2.4、typeAliases标簽
自定義别名:
在mybatis核心配置檔案中自定義别名
上面我們是自定義的别名,mybatis架構已經為我們設定好的一些常用的類型的别名
4.2.5、知識小結
properties标簽:該标簽可以加載外部的properties檔案
typeAliases标簽:設定類型别名
mappers标簽:加載映射配置
environments标簽:資料源環境配置标簽
五、mybatis相應的API
5.1、SqlSession工廠建構起SqlSessionFactoryBuilder
常用API:SqlSessionFactory build(InputStream inputStream)
通過加載mybatis的核心檔案的輸入流的形式建構一個SqlSessionFactory對象
String resource = "org/mybatis/builder/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);
其中, Resources 工具類,這個類在
org.apache.ibatis.io
包中。Resources 類幫助你從類路徑下、檔案系統或一個 web URL 中加載資源檔案。
6.2 SqlSession工廠對象SqlSessionFactory
SqlSessionFactory 有多個個方法建立SqlSession 執行個體。常用的有如下兩個:
6.3 SqlSession會話對象
SqlSession 執行個體在 MyBatis 中是非常強大的一個類。在這裡你會看到·
所有執行語句、送出或復原事務和擷取映射器執行個體
的方法。
執行語句的方法主要有:
<T> T selectOne(String statement, Object parameter) // 查詢一個
<E> List<E> selectList(String statement, Object parameter) // 查詢所有
int insert(String statement, Object parameter) // 添加資料
int update(String statement, Object parameter) // 修改資料
int delete(String statement, Object parameter) // 删除資料
操作事務的方法主要有:
void commit() // 送出事務
void rollback() // 復原事務
六、Mybatis的Dao層實作
6.1、傳統開發方式
建立一個module
依賴坐标:
<dependencies>
<!-- mysql連接配接驅動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
<!-- mybatis坐标 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!-- junit單元測試-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- log4j日志列印 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
編寫好User實體,編寫好UserMapper映射檔案
編寫好mybatis核心配置檔案
1、編寫UserMapper接口
public interface UserMapper {
public List<User> findAll();
}
2、編寫UserMapper實作類
public class UserMapperImpl implements UserMapper {
public List<User> findAll() throws IOException {
// 1、加載mybatis核心配置檔案
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
// 2、擷取sqlsessionFactory工廠對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
// 3、擷取session會話對象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 4、執行操作
List<User> userList = sqlSession.selectList("userMapper.findAll");
// 5、釋放資源
sqlSession.close();
// 6、傳回查詢結果
return userList;
}
}
3、測試傳統方式
public class UserService {
public static void main(String[] args) throws IOException {
// 建立dao層對象 目前dao層實作是手動實作的
UserMapper userMapper = new UserMapperImpl();
List<User> all = userMapper.findAll();
System.out.println(all);
}
}
傳統開發方式需要自己手動建立實作類
6.2、代理開發方式
什麼是代理開發方式?
采用 Mybatis 的代理開發方式實作 DAO 層的開發,這種方式是我們後面進入企業的主流。
Mapper 接口開發方法隻需要程式員編寫Mapper 接口(相當于Dao 接口),由Mybatis 架構根據接口定義建立接口的動态代理對象,代理對象的方法體同上邊Dao接口實作類方法。
Mapper 接口開發需要遵循以下規範:
1、Mapper.xml檔案中的namespace與mapper接口的全限定名相同
2、Mapper接口方法名和Mapper.xml中定義的每個statement的id相同
3、Mapper接口方法的輸入參數類型和mapper.xml中定義的每個sql的parameterType的類型相同
4、Mapper接口方法的輸出參數類型和mapper.xml中定義的每個sql的resultType的類型相同
實踐:
編寫測試代碼:
public class UserService {
public static void main(String[] args) throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.findAll();
System.out.println(userList);
User user = mapper.findById(1);
System.out.println(user);
}
}
6.3、知識小結
mybatis的dao層實作有兩種方式:
1、傳統開發方式 手動實作
2、代理方式 自動生成代理對象
七、mybatis映射檔案深入
7.1、動态sql
Mybatis 的映射檔案中,前面我們的 SQL 都是比較簡單的,有些時候業務邏輯複雜時,我們的 SQL是動态變化的,此時在前面的學習中我們的 SQL 就不能滿足要求了。
7.2、開發環境搭建
1、建立一個子產品
2、導入依賴坐标
3、編寫實體類User
4、編寫UserMapper映射檔案
5、編寫sqlMapConfig mybatis的核心配置檔案
6、編寫測試類進行測試。
7、導入log4j.properties檔案,将消息級别改為
debug
可以看到日志列印中的sql語句
7.3、動态Sql之if
我們根據實體類的不同取值,使用不同的 SQL語句來進行查詢。比如在 id如果不為空時可以根據id查詢,如果username 不同空時還要加入使用者名作為條件。這種情況在我們的多條件組合查詢中經常會碰到。
<!-- 采用動态sql if -->
<select id="findByCondition" parameterType="user" resultType="user">
select * from user where 1=1
<if test="id!=0">
and id=#{id}
</if>
<if test="username!=null">
and username=#{username}
</if>
<if test="password!=null">
and password=#{password}
</if>
</select>
我們可以不用自己寫where 1 = 1,mybatis提供了一個where标簽 作用和where1=1一樣
<!-- 采用動态sql if -->
<select id="findByCondition" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=0">
and id=#{id}
</if>
<if test="username!=null">
and username=#{username}
</if>
<if test="password!=null">
and password=#{password}
</if>
</where>
</select>
7.4、動态Sql之foreach
在實際中比如我們有這樣的需求該如何實作?
循環執行sql的拼接操作,例如:SELECT * FROM USER WHERE id IN(1,2,3);
<!-- 動态sql之 foreach -->
<select id="findByIds" parameterType="list" resultType="user">
select * from user
<where>
<foreach collection="list" open="id in(" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
測試代碼
@Test
public void test2() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 模拟ids資料
ArrayList<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(2);
ids.add(3);
List<User> userListByIds = mapper.findByIds(ids);
System.out.println(userListByIds);
}
查詢結果:
foreach标簽的屬性的具體含義如下:
•collection:代表要周遊的集合元素,注意編寫時不要寫#{}
•open:代表語句的開始部分
•close:代表結束部分
•item:代表周遊集合的每個元素,生成的變量名
•sperator:代表分隔符
7.5、Sql片段的抽取
Sql 中可将重複的 sql 提取出來,使用時用 include 引用即可,最終達到 sql 重用的目的
<!-- sql語句的抽取 -->
<sql id="selectUser">
select *
from user
</sql>
<select id="findByIds" parameterType="list" resultType="user">
-- select * from user
-- 采用抽取的sql片段
<include refid="selectUser"></include>
<where>
<foreach collection="list" open="id in(" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
7.6、知識小結
mybatis映射檔案配置:
标簽 | 作用 |
---|---|
查詢 | |
插入 | |
修改 | |
删除 | |
where條件 相當于where1=1 | |
判斷 拼接sql | |
循環拼接sql | |
sql片段抽取 提高複用性 |
八、mybatis核心配置檔案深入
8.1、typeHandlers
無論是 MyBatis 在預處理語句(PreparedStatement)中設定一個參數時,還是從結果集中取出一個值時, 都會用
類型處理器
将擷取的值以合适的方式轉換成 Java 類型。下表描述了一些預設的類型處理器(截取部分)。
但是有些資料類型不支援的時候,就需要我們
自定義類型轉換器
你可以重寫類型處理器或建立自己的類型處理器來處理不支援的資料類型或者非标準的類型
具體做法為:實作 org.apache.ibatis.type.TypeHandler 接口, 或繼承一個很便利的類 org.apache.ibatis.type.BaseTypeHandler, 然後可以選擇性地将它映射到一個JDBC類型。
例如需求:一個Java中的Date資料類型,我想将之存到資料庫的時候存成一個1970年至今的毫秒數,取出來時轉換成java的Date,即java的Date與資料庫的varchar毫秒值之間轉換。
開發步驟:
①定義轉換類繼承類BaseTypeHandler
②覆寫4個未實作的方法,其中setNonNullParameter為java程式設定資料到資料庫的回調方法,getNullableResult為查詢時 mysql的字元串類型轉換成 java的Type類型的方法
③在MyBatis核心配置檔案中進行注冊
具體我們來編碼看看:
1、準備環境
【1】建表
建立一張user表 生日字段存儲毫秒值
【2】編寫實體類User
package com.zhou.config.domain;
import java.util.Date;
public class User {
private int id;
private String username;
private String password;
private Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", birthday=" + birthday +
'}';
}
}
【3】編寫mapper接口的方法
public interface UserMapper {
public void addUser(User user);
}
2、編寫自定義類型處理器
package com.zhou.config.handler;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
// 繼承BaseTypeHandler類并制定要轉換的類型
public class MyDateTypeHandler extends BaseTypeHandler<Date> {
// 将java類型轉為資料庫所需要的類型
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {
long time = date.getTime(); // getTime()方法擷取毫秒值
preparedStatement.setLong(i,time);
}
// 将資料庫中的類型轉為java類型
/** 根據字段名稱轉換
* @param resultSet 查詢結果集
* @param s 要轉換的字段名稱
* @return 傳回轉換後的日期
* @throws SQLException
*/
public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
// 擷取結果集中的我們所需要的資料 轉為Date類型 傳回
long time = resultSet.getLong(s);
Date date = new Date(time);
return date;
}
// 将資料庫中的類型轉為java類型
/**
* 根據字段位置轉換
* @param resultSet 查詢結果集
* @param i 字段所在的索引位置
* @return 傳回的轉換後的日期
* @throws SQLException
*/
public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
long aLong = resultSet.getLong(i);
Date date = new Date(aLong);
return date;
}
// 将資料庫中的類型轉為java類型
public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
long aLong = callableStatement.getLong(i);
Date date = new Date(aLong);
return date;
}
}
3、注冊類型處理器
<!-- 注冊自定義類型處理器 -->
<typeHandlers>
<typeHandler handler="com.zhou.config.handler.MyDateTypeHandler"></typeHandler>
</typeHandlers>
8.2、plugins
MyBatis可以使用第三方的插件來對功能進行擴充,分頁助手PageHelper是将分頁的複雜操作進行封裝,使用簡單的方式即可獲得分頁的相關資料
①導入通用PageHelper的坐标
②在mybatis核心配置檔案中配置PageHelper插件
③測試分頁資料擷取
1、導入坐标
<!-- 分頁助手 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>3.7.5</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>0.9.1</version>
</dependency>
2、在mybatis核心配置檔案中配置分頁助手插件
<!-- 配置分頁助手插件 -->
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 指定方言 因為每種sql的分頁查詢條件關鍵字不同 -->
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
3、測試
我們隻需要在查詢全部前面加上分頁相關參數 即可
@Test
public void test1() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 設定分頁相關參數 目前頁 + 每頁顯示條數
PageHelper.startPage(1,3);
List<User> userList = mapper.findAll();
for (User user : userList) {
System.out.println(user);
}
System.out.println(userList);
sqlSession.close();
}
從第一頁開始 每頁顯示3條資料
獲得分頁相關的其他參數
System.out.println("----------------------- 擷取其他相關參數 ----------------------------");
// 獲得分頁其他相關參數
PageInfo<User> userPageInfo = new PageInfo<User>(userList);
System.out.println("目前頁:" + userPageInfo.getPageNum());
System.out.println("每頁顯示條數:" + userPageInfo.getPageSize());
System.out.println("總條數:" + userPageInfo.getTotal());
System.out.println("總頁數:" + userPageInfo.getPages());
System.out.println("上一頁:" + userPageInfo.getPrePage());
System.out.println("下一頁:" + userPageInfo.getNextPage());
System.out.println("是否第一頁:" + userPageInfo.isIsFirstPage());
System.out.println("是否最後一頁:" + userPageInfo.isIsLastPage());
8.3、知識小結
mybatis核心配置檔案常用标簽:
1、properties标簽:該标簽可以加載外部的properties檔案
2、typeAliases标簽:設定類型别名
3、environments标簽:資料源環境配置标簽
4、typeHandlers标簽:配置自定義類型處理器
5、plugins标簽:配置MyBatis的插件
6、settings标簽:開啟延遲加載、将表中字段的下劃線自動轉為駝峰功能等
九、mybatis開發小細節
9.1、IDEA開發mybatis模闆設定
我們在IDEA中開發的時候,需要從其他地方比如官網copymybatis的限制頭下來 顯得比較繁瑣,我們可以直接将mybatis的一些通用配置設定為模闆,通過模闆建立即可。
9.1.1、核心配置檔案模闆
首先我們看看哪些是通用的設定:
<?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檔案 -->
<properties resource="jdbc.properties"></properties>
<!-- 自定義别名 -->
<typeAliases>
<!-- 通過全限定名來指定别名 如果不指定alias則預設是類的大小寫節課 即這個類的别名可以是User或者user -->
<!-- <typeAlias type="com.zhou.config.domain.User" alias="user"></typeAlias>-->
<!-- 直接為一個包下的所有類起别名 -->
<package name="com.zhou.config.domain"/>
</typeAliases>
<!-- 配置資料源環境 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<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>
<!-- 加載映射檔案 -->
<mappers>
<mapper resource="com/zhou/config/mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
我們就以上述配置為模闆
點選+号 建立一個模闆
點選 apply 點選ok 退出,測試
9.1.2、mapper映射檔案模闆
同樣先看看哪些是固定的配置
<?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>
相同的操作步驟,将上述配置copy進去即可
測試:
9.2、封裝SqlSessionUtils工具類
在之前所有的開發測試中我們都需要擷取sqlsession對象,具有大量重複的代碼需要我們編寫,是以我們可以将擷取sqlsession對象的代碼單獨抽取出來封裝成一個工具類
package com.zhou.config.utils;
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 SqlSessionUtils {
public static SqlSession getSqlSession() {
SqlSession sqlSession = null; // 防止空指針異常
try {
// 讀取mybatis核心配置檔案
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
// 擷取SqlSessionFactory對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
// 通過SqlSessionFactory對象打開一個SQLSession
sqlSession = sqlSessionFactory.openSession(true); // 自動送出事務
} catch (IOException e) {
e.printStackTrace();
}
return sqlSession;
}
}
測試工具類:
@Test
public void test3(){
// 通過工具類擷取SqlSession對象
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.findAll();
for (User user : users) {
System.out.println(user);
}
}
9.3、mybatis擷取參數的兩種方式
${} 本質就是字元串拼接
#{} 本質就是占位符指派
第一種情況:當mapper傳遞過來的參數隻有一個參數的時候
可以通過${}和#{} 以任意的名稱擷取參數值,但是要注意
${}的單引号問題
第二種情況:當mapper傳遞過來的參數有多個的時候
此時mybatis會将這些參數放在一個map集合中,以兩種方式進行存儲
一種是arg0 、arg1分别表示第一個參數和第二個參數
select * from user1 where username='${arg0}' and password='${arg1}'
另一種就是param1、param2分别表示第一個參數和第二個參數
select * from user1 where username='${param1}' and password='${param2}'
可以通過#{} 也可以通過${}來擷取參數
但是需要注意${}的引号問題
第三種情況:若mapper接口中方法的參數為多個的時候,我們可以手動将這些參數放在一個map集合最終存儲
隻需要通過#{} 或者${}通過我們自己定義的鍵去擷取即可,接下來示範以下:
【1】首先編寫一個方法
【2】再編寫測代碼
@Test
public void test6(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String,Object> map = new HashMap<>();
map.put("username","張天愛");
map.put("password","123");
User user = mapper.loginByMap(map);
System.out.println(user);
}
【3】編寫mapper映射檔案
<select id="loginByMap" resultType="user">
select * from user1 where username = #{username} and password = #{password}
</select>
這裡username就是我們在map中自定義的鍵
【4】測試
第四種情況:mapper接口的參數是實體類型的時候
實體類型以屬性名進行通路 需要我們标注參數類型parameterType
第五種情況:使用@Param注解來命名參數
此時mybatis會自動将參數放在一個map集合中,以兩種方式存儲
第一種 以@Param注解為鍵,參數為值
第二種 以param1、param2為鍵 參數為值
<select id="loginByParam" resultType="user">
select * from user1 where username = #{username} and password = #{password}
</select>
@Test
public void test7(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.loginByParam("張天愛","123");
System.out.println(user);
}