1. 程式人生 > >mybatis入門級02——基礎知識

mybatis入門級02——基礎知識

一、Mybatis框架原理

  1. Mybatis是一個持久層框架,是apache下的頂級專案。
  2. Mybatis託管到googlecode下,再後來託管到github下。
  3. Myabtis讓程式主要將精力放在sql上,通過mybatis提供的對映方式,自由靈活生成(半自動化,大部分需要程式猿編寫sql)滿足需要sql語句。
  4. Mybatis可以將向prepareStatement中輸入引數自動進行輸入對映,將查詢結果集靈活對映成java物件(輸出對映)。

圖解:

二、入門級程式淺析

1.3 Mybatis入門程式

  1. 環境
    Jdk1.8、eclispe Version: 2018-09 (4.9.0)、mysql 5.7
    Mysql驅動包
    Mybatis驅動包
    Mybatis依賴包
  2. log4j.properties
# Global logging configuration 
# 在開發環境中日誌級別設定成DEBUG,生產環境為info或error
log4j.rootLogger=DEBUG, stdout 
# Console output... 
log4j.appender.stdout=org.apache.log4j.ConsoleAppender 
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
  1. 工程目錄結構
    在這裡插入圖片描述
  2. 建立po類
com.kjgym.po.User
public class User {
	private int id;
	private String username;
	private String sex;
	private Date birthday;
    private String address;
  1. 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">

<!-- namespace名稱空間,作用是對sql進行分類華管理,理解sql隔離
注意:使用mapper代理方法開發,namespace有特殊重要的作用
 -->
< mapper namespace="test">
	
	<!-- 通過使用者id查詢使用者 -->
	<!-- 通過select執行資料庫查詢
	id:標識對映檔案中的sql,
	將sql語句封裝到mappedstatement物件中,稱為statement的id
	
	#{}:表示一個佔位符
	#{id}:其中的id表示接收輸入的引數,引數名稱就是id,如果輸入引數時簡單型別,#{}中的引數名可以任意,可以是value或其他名稱
	
	parameterType:指定輸入引數的型別
	resultType:指定sql輸出結果所對映的java物件。sqlect指定resultType表示將單挑記錄對映成的java物件
	 -->
	<select id="findUserById" parameterType="int" resultType="com.kjgym.po.User">
		SELECT * FROM t_user WHERE id=#{id}
	</select>
	
	
	<!-- 通過使用者使用者名稱模糊查詢使用者 -->
	<!-- resultType可能返回多條資料 ,但是將單挑記錄對映成的java物件
	${}:表示拼接sql,會引發sql注入。
		select * from t_user where username like '%' or 1=1 or '%'
	${value}:接收輸入引數的內容。如果傳入型別是簡單型別,${}中只能使用value
	-->
	<select id="findUserByName" parameterType="java.lang.String" resultType="com.kjgym.po.User">
		SELECT * FROM t_user WHERE username LIKE #{username} 
		<!--SELECT * FROM t_user WHERE username LIKE '%${username}%' -->
		<!--這種傳入時不需要加%了 
		-->
	</select>
	
	<!-- 新增使用者資訊 -->
	<insert id="insertUser" parameterType="com.kjgym.po.User">
	
		insert into t_user(id, username,birthday,sex,address) value(#{id}, #{username}, #{birthday}, #{sex}, #{address})
		
		<!-- 將插入資料的主鍵返回,返回到user物件當中
			SELECT LAST_INSERT_ID():得到剛insert進去記錄的主鍵值,只適用於自增主鍵。
			
			keyProperty:將查詢到主鍵值設定到parameterType指定的物件的哪個屬性
			order:SELECT LAST_INSERT_ID()執行順序,相對於insert語句來說它的執行順序
			resultType:指定SELECT LAST_INSERT_ID()的結果型別
		 -->
		<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
			select LAST_INSERT_ID()
		</selectKey>	
		
		<!-- 使用mysql的uuid()生成主鍵
		執行過程:
			首先通過uuid()得到主鍵,將主鍵設定到user物件的id屬性中
			其次在insert執行時,從user物件中取出id屬性值
		 -->
		 <!-- 
		 <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
			select uuid()
		</selectKey>
		 
		  -->
	</insert>
	
	<!-- 根據id刪除使用者資訊 -->
	<delete id="deletetUserById" parameterType="int">
		delete from t_user where id = #{id}
	</delete>
	
	<!-- 更新使用者資訊 -->
	<insert id="updateUser" parameterType="com.kjgym.po.User">
		update t_user set username=#{username}, birthday=#{birthday}, sex=#{sex}, address=#{address} where id=#{id}
	</insert>
	
</ mapper>
  1. 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>
	<!-- 和spring整合後 environments將被廢除 -->
	<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/db_mybatis02?characterEncoding=utf-8"/>
				<property name="username" value="root"/>
				<property name="password" value="246626"/>
			</dataSource>
		</environment>
	</environments>
	
	<!-- 載入對映檔案 -->
	<mappers>
		<mapper resource="sqlmap/User.xml"/>
	</mappers>
</configuration>
  1. 新增junit包測試
    A、根據id查詢使用者資訊
    B、根據名字模糊查詢使用者資訊
    C、新增使用者
    D、刪除使用者
    E、更新使用者
    測試程式碼如下:
package com.kjgym.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.Test;

import com.kjgym.po.User;

import org.junit.After;
import org.junit.Before;
public class Test01 {

	private SqlSession sqlSession;
	
	@Before
	public void setUp() throws Exception {
		
		// 1.得到配置檔案流
		InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
		
		// 2.建立會話工廠,傳入mybatis的配置檔案資訊流
		SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		
		// 3.通過工廠得到sqlSession
		sqlSession = sessionFactory.openSession();
		
		// 4.通過sqlSession操作資料庫
		
		// 5.最後關閉SQLSession
		
	}

	@After
	public void tearDown() throws Exception {
		sqlSession.close();
	}

	/**
	 * 根據ID查詢使用者資訊
	 *  
	 * @author: kangjia  
	 * @date: 2018年11月6日下午5:25:54
	 * @return:
	 */
	@Test
	public void findUserByIdTest() {
		// sqlSession.selectOne(statement, parameter)
		// 引數一:對映檔案中statement的id,等同於namespace+“.”+statementid
		// 引數二:指定和對映檔案中所匹配的paramenterType型別的引數
		// selectOne結果是與對映檔案中所匹配的resultType型別的物件
		User user = sqlSession.selectOne("test.findUserById", 3);
		
		System.out.println(user);
		
	}
	/**
	 * 根據使用者名稱模糊查詢使用者資訊
	 * 可能會返回多條資料
	 *  
	 * @author: kangjia  
	 * @date: 2018年11月6日下午5:26:36
	 * @return:
	 */
	@Test
	public void findUserByNameTest() {
		// sqlSession.selectList(statement, parameter)
		// 引數一:對映檔案中statement的id,等同於namespace+“.”+statementid
		// 引數二:指定和對映檔案中所匹配的paramenterType型別的引數
		// selectOne結果是與對映檔案中所匹配的resultType型別的物件
		List<User> userList = sqlSession.selectList("test.findUserByName", "%k%");
		
		System.out.println(userList);
		
	}
	
	/**
	 * 插入使用者資訊
	 *  
	 * @author: kangjia  
	 * @date: 2018年11月6日下午6:03:08
	 * @return:
	 */
	@Test
	public void insertUserTest() {
		User user = new User();
		user.setUsername("cj");
		// 注意的是  在這裡插入時資料庫對應欄位時失敗了   插入了問號,解決方法:在mybatis-config.xml配置檔案中,對應行改為:
		// <property name="url" value="jdbc:mysql://localhost:3306/db_mybatis02?characterEncoding=utf-8"/>
		user.setAddress("河北");  
		user.setBirthday(new Date());
		user.setSex("1");
		
		sqlSession.insert("test.insertUser", user);
		
		// 提交事務
		sqlSession.commit();
		System.out.println(user);
	}
	
	/**
	 * 根據id刪除使用者資訊
	 *  
	 * @author: kangjia  
	 * @date: 2018年11月6日下午6:14:27
	 * @return:
	 */
	@Test
	public void deletetUserByIdTest() {
		sqlSession.delete("test.deletetUserById", 6);
		// 提交事務
		sqlSession.commit();
	}
	
	/**
	 * 更新使用者資訊
	 *  
	 * @author: kangjia  
	 * @date: 2018年11月6日下午9:48:57
	 * @return:
	 */
	@Test
	public void updateUserTest() {
		User user = new User();
		user.setId(8);
		user.setUsername("cj");
		// 注意的是  在這裡插入時資料庫對應欄位時失敗了   插入了問號,解決方法:在mybatis-config.xml配置檔案中,對應行改為:
		// <property name="url" value="jdbc:mysql://localhost:3306/db_mybatis02?characterEncoding=utf-8"/>
		user.setAddress("河北");  
		user.setBirthday(new Date());
		user.setSex("1");
		
		sqlSession.update("test.updateUser", user);
		
		// 提交事務
		sqlSession.commit();
	}

	
}

  1. 總結
    1) #{}表示一個佔位符,接收輸入引數,型別可以是簡單型別,pojo,hashmap。如果接受簡單型別,#{}中可以寫成value或其他名稱。如果接收pojo物件,通過OGNL讀取物件中的屬性值,通過屬性.屬性.屬性…的方式獲取物件屬性值。
    2) ${}表示一個拼接符號,會引起sql注入。不推薦使用。接收輸入引數,型別可以是簡單型別,pojo,hashmap。如果接受簡單型別,#{}中只能寫成value。如果接收pojo物件,通過OGNL讀取物件中的屬性值,通過屬性.屬性.屬性…的方式獲取物件屬性值。
    3) 可以使用selectOne的地方也可以使用selectList,反之不能。
    會報異常:org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: ……
    4) 自增主鍵mysql主鍵返回,執行insert提交之前自動生成一個自增主鍵。通過mysql函式獲取到剛插入記錄的自增主鍵LAST_INSERT_ID(),是insert執行之後執行該方法。
    5) 使用mysql的uuid()生成主鍵
    執行過程:首先通過uuid()得到主鍵,將主鍵設定到user物件的id屬性中;其次在insert執行時,從user物件中取出id屬性值
    6) parameterType
    7) resultType