MyBatis的學習總結一
一、MyBatis的介紹:
MyBatis本是apache的一個開源專案iBatis,2010年這個專案由apache software foundation遷移到google code,並改名為MyBatis。
冊驅動、 建立connection、建立statement、手動設定引數、結果集檢索等jdbc繁雜的過程程式碼。MyBtis是一個優秀的持久層框架,它對jdbc的操作資料庫的過程進行封裝,使開發者只需關注sql本身,而不需要花費精力去處理如注
MyBatis通過xml或註解的方式將要執行的各種statement(statement、preparedStatement、Callablestatement)配置起來,並通過Java
物件和statement中的sql進行對映生成最終的執行sql語句,最後由MyBatis框架執行sql並將結果對映成java物件並返回。
二、MyBatis的入門案例以及基本配置:
需求:使用MyBatis完成增刪改查的基本功能
1、建立資料庫,加入測試資料(以下是sql執行檔案)
/* Navicat MySQL Data Transfer Source Server : RBAC_permission Source Server Version : 50527 Source Host : localhost:3306 Source Database : mybatis Target Server Type : MYSQL Target Server Version : 50527 File Encoding : 65001 Date: 2018-01-27 20:08:42 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; 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=31 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES ('1', '王五', null, '2', null); INSERT INTO `user` VALUES ('10', '張三', '2014-07-10', '1', '北京市'); INSERT INTO `user` VALUES ('16', '張小明', null, '1', '河南鄭州'); INSERT INTO `user` VALUES ('24', '張三丰', null, '1', '河南鄭州'); INSERT INTO `user` VALUES ('25', '狗剩', null, '1', '北海道'); INSERT INTO `user` VALUES ('26', '王五', null, null, null); INSERT INTO `user` VALUES ('28', '李逍遙', '2017-11-23', '男', '青島'); INSERT INTO `user` VALUES ('30', '菜呀', '2017-11-23', '男', '中國');
2、建立java工程,加入mybtis的核心包、依賴包、資料驅動包(專案結構圖如下)
3、建立SqlMapConfig.xml配置檔案。SqlMapConfig是MyBatis的核心配置檔案,配置檔案內容為資料來源、事務管理。
4.建立實體類<?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> <typeAliases> <!-- typeAlias: 起別名 type: 指定pojo的型別 alias: 別名,大小寫不敏感 <typeAlias type="com.heima.pojo.User" alias="user"/> --> <!-- package: 批量起別名, name: 指定掃描的報名 別名: 就是類名,大小寫不敏感 --> <package name="com.evil.pojo"/> </typeAliases> <!-- 和spring整合後 environments配置將廢除 --> <environments default="development"> <environment id="development"> <!-- 使用jdbc事務管理 --> <transactionManager type="JDBC" /> <!-- 資料庫連線池 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" /> <property name="username" value="root" /> <property name="password" value="root" /> </dataSource> </environment> </environments> <!-- 載入對映檔案 --> <mappers> <!-- mapper標籤: 引入對映檔案 url: 絕對路徑,不推薦使用 resource: 相對路徑 --> <!-- <mapper resource="User.xml"/> --> <!-- class: 指定介面的全路徑名稱 1: 介面檔案和對映檔案必須在同一個包下 2: 介面檔案和對映檔名稱必須相同,除了副檔名 <mapper class="com.evil.mapper.UserMapper"/> --> <!-- package標籤: 批量掃描對映檔案 name: 指定掃描的包名 1: 介面檔案和對映檔案必須在同一個包下 2: 介面檔案和對映檔名稱必須相同,除了副檔名 --> <package name="com.evil.mapper"/> </mappers> </configuration>
package com.evil.pojo;
import java.util.Date;
public class User {
/**
*
*/
private Integer id;
private String username;// 使用者姓名
private String sex;// 性別
private Date birthday;// 生日
private String address;// 地址
..............getXXX/setXX略
5.建立介面(相當於Dao,採用的是Mybatis的動態代理方式)
Mapper介面開發方法只需要我們編寫Mapper介面(相當於Dao介面),由Mybatis框架根據介面定義建立介面的動態代理物件。
Mapper介面開發需要遵循以下規範:
1、對映檔案的Namespace必須等於介面的全路徑名稱
2、對映檔案的sql唯一標示id必須等於介面方法的名稱
3、對映檔案的parameterType必須等於介面方法的引數型別
4、對映檔案的resultType必須等於介面方法的返回型別
package com.evil.mapper;
import java.util.List;
import com.evil.pojo.User;
public interface UserMapper {
//根據使用者id查詢一個使用者資訊
public User findUserById(Integer id);
//根據使用者名稱稱模糊查詢使用者資訊列表
public List<User> findByUserUsername(String Username);
//新增使用者資訊
public void addUser(User user);
}
6.建立介面的對映檔案
<?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.evil.mapper.UserMapper">
<!--
mybatis動態代理的開發規範
1: 對映檔案的namespace必須等於介面的全路徑名稱
2: 對映檔案的sql唯一標示id必須等於 介面方法的名稱
3: 對映檔案的parameterType必須等於介面方法的 引數型別
4: 對映檔案的resultType必須等於介面方法的返回型別
-->
<select id="findUserById" parameterType="int" resultType="com.evil.pojo.User">
select * from user where id = #{id}
</select>
<select id="findByUserUsername" parameterType="string" resultType="com.evil.pojo.User">
select * from user where username like '%${value}%';
</select>
<insert id="addUser" parameterType="com.evil.pojo.User">
insert into user(username,sex,birthday,address) values(#{username},#{sex},#{birthday},#{address});
</insert>
</mapper>
7.測試
只需要定義一個全域性的變數,建立一次就好。說明:@Before是在執行JUnit的@Test之前例項化SqlSessionFactory。沒必要每次訪問Mybatis的時候都要建立一個SqlSessionFactory,
package com.evil.test;
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.Before;
import org.junit.Test;
import com.evil.mapper.UserMapper;
import com.evil.pojo.User;
public class UserMapperTest {
SqlSessionFactory sessionFactory;
@Before
public void testName() throws Exception {
String resource="SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
//新增使用者資訊
@Test
public void addUser(){
SqlSession session = sessionFactory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User();
user.setUsername("菜呀");
user.setSex("男");
user.setBirthday(new Date());
user.setAddress("中國");
userMapper.addUser(user);
session.commit();
}
//模糊查詢使用者資訊列表
@Test
public void findUserByUsername(){
SqlSession session = sessionFactory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
List<User> list = userMapper.findByUserUsername("張");
for (User user : list) {
System.out.println(user);
}
}
@Test
public void findById(){
SqlSession session = sessionFactory.openSession();
UserMapper usermapper = session.getMapper(UserMapper.class);
User user = usermapper.findUserById(1);
System.out.println(user);
}
}
三、具體的執行流程?
MyBatis流程圖(圖片來自網路:侵刪)
1、mybatis的配置
對應一個MappedStatement物件,sql的id即是MappedStatement的id。SqlMapConfig.xml,此檔案作為mybatis的全域性配置檔案,配置了myatis的執行環境等資訊。
mapper.xml檔案即sql對映檔案,檔案中配置了操作資料庫的sql語句。此檔案需要在SqlMapConfig中載入。
2、通過mybatis環境資訊構造SqlSessionFactory工廠即會話工廠,它是由SqlSessionFactoryBuilder物件呼叫build()方法建立的。
3、由會話工廠建立sqlSession即會話,該會話的作用就是完成資料庫的訪問和結果的對映。
4、mybatis底層自定義了Executor執行器介面來操作資料庫,Executor介面有兩個實現,一個是基本執行器、一個是快取執行器。
5、MappedStatement也是mybatis一個底層封裝物件,它包裝了mybatis配置資訊以及sql對映資訊等。Mapper.xml檔案中一個sql
將輸入的java物件對映到sql中.6、MappedStatement對sql執行輸入引數進行定義,包括HashMap、基本型別、pojo,Executor通過MappedStatement在執行sql前
輸出結果對映至java物件中。7、MappedStatement對sql執行輸出結果進行定義,包括HashMap、基本型別、pojo,Excutor通過MappedStatement在執行sql後將
四、小問題?
會導致sql注入攻擊,能用#號的地方就不要使用$,寫OrderBy子句時應該用$而不是#。1.MyBatis是怎麼樣完成實體和表之間的對映?
<select id="findUserById" parameterType="int" resultType="com.heima.pojo.User">
select * from user where id = #{id}
</select>
parameterType:引數型別,將傳入的java物件,對映成表中的欄位,加入到sql語句中。
resultType:將執行sql的的返回結果對映成Java物件。2.MyBatis中使用#{}和${}書寫佔位符有什麼區別?
#將傳入的資料都當成一個字串,會對傳入的資料自動加上引號;$將傳入的資料直接顯示生成在SQL中。注意:使用$佔位符可能