您好,登錄后才能下訂單哦!
這篇文章主要介紹“MyBatis簡(jiǎn)單使用實(shí)例”,在日常操作中,相信很多人在MyBatis簡(jiǎn)單使用實(shí)例問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”MyBatis簡(jiǎn)單使用實(shí)例”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!
使用MyBatis可以分以下幾個(gè)關(guān)鍵點(diǎn)
引入MyBatis依賴
配置mybatis-config.xml配置文件
創(chuàng)建數(shù)據(jù)庫實(shí)體類與Mapper映射文件
通過SqlSessionFactoryBuilder加載配置并使用
以下按步驟寫一個(gè)單元測(cè)試:
引入依賴
<!-- mybatis依賴包 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.4</version> </dependency> <!-- 數(shù)據(jù)庫驅(qū)動(dòng) 需要使用 5.1.40以上才可解決mysql json格式亂碼問題 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.40</version> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.6</version> </dependency>
編寫配置文件
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> <properties resource="db.properties"></properties> <settings> <!-- 打印查詢語句 --> <setting name="logImpl" value="STDOUT_LOGGING" /> <!-- 控制全局緩存(二級(jí)緩存),默認(rèn) true--> <setting name="cacheEnabled" value="false"/> <!-- 延遲加載的全局開關(guān)。當(dāng)開啟時(shí),所有關(guān)聯(lián)對(duì)象都會(huì)延遲加載。默認(rèn) false --> <setting name="lazyLoadingEnabled" value="false"/> <!-- 當(dāng)開啟時(shí),任何方法的調(diào)用都會(huì)加載該對(duì)象的所有屬性。默認(rèn) false,可通過select標(biāo)簽的 fetchType來覆蓋--> <setting name="aggressiveLazyLoading" value="true"/> <!-- Mybatis 創(chuàng)建具有延遲加載能力的對(duì)象所用到的代理工具,默認(rèn)JAVASSIST --> <!--<setting name="proxyFactory" value="CGLIB" />--> <!-- STATEMENT級(jí)別的緩存,使一級(jí)緩存,只針對(duì)當(dāng)前執(zhí)行的這一statement有效,相當(dāng)于關(guān)閉一級(jí)緩存 --> <!-- <setting name="localCacheScope" value="STATEMENT"/> --> <setting name="localCacheScope" value="SESSION"/> </settings> <typeAliases> <typeAlias alias="user" type="com.freecloud.plug.mybatis.entity.User" /> <typeAlias alias="myBatisJson" type="com.freecloud.plug.mybatis.entity.MyBatisJson" /> <typeAlias alias="department" type="com.freecloud.plug.mybatis.entity.Department" /> <typeAlias alias="userAndDepartment" type="com.freecloud.plug.mybatis.entity.UserAndDepartment" ></typeAlias> </typeAliases> <!-- 自定義類型轉(zhuǎn)換器 --> <typeHandlers> <typeHandler handler="com.freecloud.plug.mybatis.type.JsonTypeHandler"></typeHandler> </typeHandlers> <plugins> <plugin interceptor="com.freecloud.plug.mybatis.plugins.SQLExecuteTimeInterceptor"> <property name="name" value="zhangsan" /> </plugin> <plugin interceptor="com.freecloud.plug.mybatis.plugins.SimpleTableInterceptor"></plugin> </plugins> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/><!-- 單獨(dú)使用時(shí)配置成MANAGED沒有事務(wù) --> <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="mapper/UserMapper.xml"/> <mapper resource="mapper/MyBatisJsonMapper.xml"/> <mapper resource="mapper/DepartmentMapper.xml"/> </mappers> </configuration>
db.properties數(shù)據(jù)庫連接配置
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/data_test?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true jdbc.username=root jdbc.password=123456
初始化數(shù)據(jù),用于后邊的單元測(cè)試。
## 部門表 CREATE TABLE `department` ( `id` int(5) NOT NULL, `name` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, `parent_id` int(5) NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; ## 員工表 CREATE TABLE `user_department` ( `id` int(5) NOT NULL, `name` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, `age` int(4) DEFAULT NULL, `default_department_id` int(5) NOT NULL, `all_department_id` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; ## 初始化部門 insert into department values (1,'部門1',null); insert into department values (2,'部門2',1); insert into department values (3,'部門3',null); ## 初始化員工 insert into user_department values (1,'張三',18,1,'2,3'); insert into user_department values (2,'李4',18,2,'1,2'); insert into user_department values (3,'王5',18,3,'3'); insert into user_department values (4,'趙6',18,1,'1');
數(shù)據(jù)庫實(shí)體類與mapper配置
/** * 業(yè)務(wù)實(shí)體對(duì)象 */ @Data @NoArgsConstructor @AllArgsConstructor public class User implements Serializable { /** 主鍵ID */ private Long id; /** 姓名 */ private String name; /** 年齡 */ private Integer age; }
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 namespace="com.freecloud.plug.mybatis.dao.UserMapper"> <!-- 聲明這個(gè)namespace使用二級(jí)緩存 --> <!-- <cache/>--> <!-- 使用Redis作為二級(jí)緩存 --> <!-- <cache type="org.mybatis.caches.redis.RedisCache" eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/> --> <cache type="org.apache.ibatis.cache.impl.PerpetualCache" size="1024" eviction="LRU" flushInterval="120000" readOnly="false"/> <resultMap id="BaseResultMap" type="user"> <id column="id" property="id" jdbcType="INTEGER"/> <result column="name" property="name" jdbcType="VARCHAR"/> <result column="age" property="age" jdbcType="INTEGER"/> </resultMap> <!-- 對(duì)象關(guān)聯(lián)查詢,一條sql直接查詢 --> <resultMap id="UserAndDepartmentResultMap" type="userAndDepartment"> <id column="id" property="id" jdbcType="INTEGER"/> <result column="name" property="name" jdbcType="VARCHAR"/> <result column="age" property="age" jdbcType="INTEGER"/> <association property="defaultDepartment" javaType="com.freecloud.plug.mybatis.entity.Department" > <id column="department_id" property="id"></id> <result column="department_name" property="name" ></result> </association> </resultMap> <!-- 聯(lián)合查詢,會(huì)產(chǎn)生 N+1的問題 --> <resultMap id="UserAndDepartmentResultMap1" type="userAndDepartment"> <id column="id" property="id" jdbcType="INTEGER"/> <result column="name" property="name" jdbcType="VARCHAR"/> <result column="age" property="age" jdbcType="INTEGER"/> <!-- 此處可以夸namespace調(diào)用,但要保證當(dāng)前應(yīng)用加載對(duì)應(yīng)mapper --> <association property="defaultDepartment" column="default_department_id" javaType="com.freecloud.plug.mybatis.entity.Department" select="com.freecloud.plug.mybatis.dao.DepartmentMapper.byId" ></association> </resultMap> <!-- 聯(lián)合查詢,一對(duì)多 --> <resultMap id="UserAndDepartmentResultMap2" type="userAndDepartment"> <id column="id" property="id" jdbcType="INTEGER"/> <result column="name" property="name" jdbcType="VARCHAR"/> <result column="age" property="age" jdbcType="INTEGER"/> <!-- 此處可以夸namespace調(diào)用,但要保證當(dāng)前應(yīng)用加載對(duì)應(yīng)mapper --> <!-- <association property="defaultDepartment" column="default_department_id"--> <!-- javaType="com.freecloud.plug.mybatis.entity.Department"--> <!-- select="com.freecloud.plug.mybatis.dao.DepartmentMapper.byId" ></association>--> <collection property="departmentList" column="all_department_id" ofType="com.freecloud.plug.mybatis.entity.Department" select="com.freecloud.plug.mybatis.dao.DepartmentMapper.byIds"></collection> </resultMap> <select id="byId" resultMap="BaseResultMap" statementType="PREPARED" > select * from user_department where id = #{id} </select> <insert id="save" parameterType="user" > insert into user_department (id,name,age) values (#{id},#{name},#{age}) </insert> <update id="update" parameterType="user"> update user_department <set> <if test="name != null"> name = #{name} </if> <if test="age != null"> ,age = #{age} </if> </set> where id = #{id} </update> <select id="getUserAndDepartmentById" parameterType="long" resultMap="UserAndDepartmentResultMap" > select a.id,a.name,a.age,b.id as department_id,b.name as department_name from user_department a left join department b on a.default_department_id = b.id where a.id = #{id} </select> <select id="getUserAndDepartmentById1" parameterType="long" resultMap="UserAndDepartmentResultMap1" > select * from user_department a where a.id = #{id} </select> <select id="getUserAndDepartmentById2" parameterType="long" resultMap="UserAndDepartmentResultMap2" > select * from user_department a where a.id = #{id} </select> </mapper>
mapper調(diào)用接口,方法名要到Mapper.xml文件中的配置的Id相同,否則無法映射成功。
public interface UserMapper { /** * 根據(jù)主鍵查詢 * @param id * @return */ public User byId(Long id); /** * 新增 * @param user * @return */ public void save(User user); /** * 修改 * @param user */ public void update(User user); /** * 多表關(guān)聯(lián)查詢 * @param id * @return */ public UserAndDepartment getUserAndDepartmentById(Long id); /** * 關(guān)聯(lián)查詢,有N + 1問題 * @param id * @return */ public UserAndDepartment getUserAndDepartmentById1(Long id); /** * 關(guān)聯(lián)查詢,1對(duì)多 * @param id * @return */ public UserAndDepartment getUserAndDepartmentById2(Long id); }
單元測(cè)試
package com.freecloud.plug.mybatis; import com.freecloud.common.LoggerUtil; import com.freecloud.plug.mybatis.dao.UserMapper; import com.freecloud.plug.mybatis.entity.User; import com.freecloud.plug.mybatis.entity.UserAndDepartment; 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 java.io.IOException; import java.io.InputStream; /** * @Author: maomao * @Date: 2021-04-08 11:36 */ public class MyBatisTest { private SqlSessionFactory sqlSessionFactory; @Before public void init() throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } /** * 使用mybatis api 方式硬編碼方式 */ @Test public void testApiStatement(){ SqlSession sqlSession = sqlSessionFactory.openSession(); try { sqlSession.selectOne("com.freecloud.plug.mybatis.dao.UserMapper.byId",1); }finally { sqlSession.close(); } } /** * 測(cè)試使用mapper包裝直接使用接口調(diào)用 */ @Test public void testMapperInterface(){ SqlSession sqlSession = sqlSessionFactory.openSession(); try { UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.byId(1L); LoggerUtil.printThread(user.toString()); }finally { sqlSession.close(); } } /** * 多表關(guān)聯(lián)查詢 */ @Test public void testUserAndDepartment(){ SqlSession sqlSession = sqlSessionFactory.openSession(); try { UserMapper userMapper = sqlSession.getMapper(UserMapper.class); UserAndDepartment user = userMapper.getUserAndDepartmentById(1L); LoggerUtil.printThread(user.toString()); }finally { sqlSession.close(); } } /** * 關(guān)聯(lián)查詢,有N + 1問題 */ @Test public void testUserAndDepartment1(){ SqlSession sqlSession = sqlSessionFactory.openSession(); try { UserMapper userMapper = sqlSession.getMapper(UserMapper.class); UserAndDepartment user = userMapper.getUserAndDepartmentById1(1L); LoggerUtil.printThread(user.toString()); }finally { sqlSession.close(); } } /** * 關(guān)聯(lián)查詢,1對(duì)多 */ @Test public void testUserAndDepartment2(){ SqlSession sqlSession = sqlSessionFactory.openSession(); try { UserMapper userMapper = sqlSession.getMapper(UserMapper.class); UserAndDepartment user = userMapper.getUserAndDepartmentById2(1L); LoggerUtil.printThread(user.toString()); }finally { sqlSession.close(); } } }
使用以上例子,就可以運(yùn)行起來MyBatis??磫卧獪y(cè)試中的使用方法,分別描述了幾種常見方式。
使用傳統(tǒng)硬編碼直接通過Mapper映射器中配置的ID訪問
使用一個(gè)空接口實(shí)現(xiàn)方法調(diào)用(無實(shí)現(xiàn)類),使用sqlSession.getMapper(UserMapper.class);方式獲取實(shí)例執(zhí)行
對(duì)象關(guān)聯(lián)性查詢一對(duì)多、一對(duì)一形式
在單元測(cè)試類中我們看到了MyBatis里面的幾個(gè)核心對(duì)象:
SqlSessionFactoryBuiler
SqlSessionFactory
SqlSession
Mpper
這幾個(gè)核心對(duì)象在MyBatis的整個(gè)工作流程里面的不同環(huán)節(jié)發(fā)揮作用。如果我們不用容器,自己去管理這些對(duì)象的話,我們必須考慮一個(gè)問題:什么時(shí)候創(chuàng)建和銷毀這些對(duì)象?
在一些分布式應(yīng)用里,多線程高并發(fā)場(chǎng)景中,如果要寫出高效的代碼,就必須了解這四個(gè)對(duì)象的生命周期。
它是用來構(gòu)建SqlSessionFactory與解析mybatis-config等配置的,而SqlSessionFactory只需要一個(gè),所以只要構(gòu)建了一個(gè)SqlSessionFactory之后它的使命就完成了,也就沒有存在的必要了。所以它的生命周期只存在于方法的局部。
SqlSessionFactory是用來創(chuàng)建SqlSession的,每次訪問數(shù)據(jù)庫都需要?jiǎng)?chuàng)建一個(gè)回話。因?yàn)槲覀円恢庇袆?chuàng)建會(huì)話的需要,所以SqlSessionFactory應(yīng)該存在于應(yīng)用的整個(gè)生命周期中(作用域是應(yīng)用作用域)。創(chuàng)建SqlSession只需要一個(gè)實(shí)例來做這件事就可以了,否則會(huì)造成混亂和資源浪費(fèi)。所以我們應(yīng)該采用單例模式。
一般工廠類在都應(yīng)該是單例模式。
SqlSession是一個(gè)會(huì)話,因?yàn)樗皇蔷€程安全的,不能在線程間共享。所以我們?cè)谡?qǐng)求開始的時(shí)候創(chuàng)建一個(gè)SqlSession對(duì)象,在請(qǐng)求結(jié)束時(shí)要及時(shí)關(guān)閉它。也可以把它理解成Jdbc 的Connection連接。
實(shí)際是Mapper是一個(gè)代理對(duì)象,是從SqlSession中獲取的。
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
它的作用是發(fā)送Sql來操作數(shù)據(jù)庫的數(shù)據(jù)。它應(yīng)該在一個(gè)SqlSession事務(wù)方法之內(nèi)。
對(duì)象 | 作用域 |
---|---|
SqlSessionFactoryBuilder | 方法局部(method) |
SqlSessionFactory | 應(yīng)用級(jí)別(application) |
SqlSession | 請(qǐng)求和操作(request、method) |
Mapper | 方法(method) |
以上就是四個(gè)核心對(duì)象的生命周期。
到此,關(guān)于“MyBatis簡(jiǎn)單使用實(shí)例”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。