国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【計算機編程語言】JAVA-MyBatis(Eclipse)

這篇具有很好參考價值的文章主要介紹了【計算機編程語言】JAVA-MyBatis(Eclipse)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

MyBatis

官網(wǎng):https://mybatis.org/mybatis-3/zh/index.html

環(huán)境:

  • JDK1.8(盡量)
  • MySQL - 5.7(超經(jīng)典)
  • maven - 3.6.3
  • Eclipse

回顧:

  • JDBC
  • MySQL
  • Java基礎(chǔ)
  • maven
  • Junit

框架:配置文件、最好的方式:官網(wǎng)文檔

SSM框架:Spring SpringMVC Mybatis

1.簡介

1.1什么是Mybatis

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-BMmIzH2v-1690204448185)(MyBatis.assets/image-20210113203554906.png)]

  • MyBatis 是一款優(yōu)秀的持久層框架
  • 它支持自定義 SQL、存儲過程以及高級映射
  • MyBatis 免除了幾乎所有的 JDBC 代碼以及設(shè)置參數(shù)和獲取結(jié)果集的工作。
  • MyBatis 可以通過簡單的 XML 或注解來配置和映射原始類型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 對象)為數(shù)據(jù)庫中的記錄。
  • MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了[google code](https://baike.baidu.com/item/google code/2346604),并且改名為MyBatis 。2013年11月遷移到Github。

如何獲得Mybatis

  • maven倉庫
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.3</version>
</dependency>
  • github - https://github.com/mybatis/mybatis-3/releases
  • 中文文檔 - https://mybatis.org/mybatis-3/zh/index.html

1.2持久化

數(shù)據(jù)持久化

  • 持久化,就是將程序的數(shù)據(jù)在持久狀態(tài)和瞬時狀態(tài)轉(zhuǎn)化的過程
  • 內(nèi)存:斷電即失
  • 數(shù)據(jù)庫(JDBC)、IO文件持久化
  • 生活:冷藏(吃的時候再解凍)、罐頭

為什么需要持久化?

  • 有一些對象,不能讓他丟失
  • 內(nèi)存,太貴了

1.3持久層

Dao層、Service層、Controller層

什么叫持久層?

  • 完成持久化工作的代碼塊
  • 層的
  • 界限十分明顯

1.4為什么需要Mybatis

  • 幫助程序員將數(shù)據(jù)存入數(shù)據(jù)庫
  • 傳統(tǒng)的JDBC過于復(fù)雜、簡化、框架、自動化
  • 不用也行

最重要的一點:使用的人超級多

2.第一個Mybatis程序

思路:搭建環(huán)境 - 導(dǎo)入Mybatis - 編寫代碼 - 測試

全部文件:

mybatis-config.xml(會變)

MybatisUtil.java(不會變)

User.java(操作的表只要是user,就不會改變)

UserDao.java(接口)

UserMapper.xml(會變)

UserDaoTest.java(小部分改變)

2.1搭建環(huán)境

2.1.1.搭建數(shù)據(jù)庫:

想項目運行成功,一定保證數(shù)據(jù)庫正常連接?。?/p>

CREATE DATABASE `mybatis`;

use `mybatis`;

CREATE TABLE `user` (
	`id` INT(20) NOT NULL,
	`name` VARCHAR(30) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
	`pwd` VARCHAR(30) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
	PRIMARY KEY (`id`) USING BTREE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

INSERT INTO `user` (id,`name`,pwd) VALUES
(1,"陳雨晴",123456),(2,"付姍",123456789),(3,"馬雨雨",112233)
2.1.2.新建項目(工程)

第一步:新建一個普通的maven項目

  • 第一步:
    【計算機編程語言】JAVA-MyBatis(Eclipse),計算機編程語言,java,mybatis,eclipse

  • 第二步:刪除項目中的 src 文件夾,(作為父工程)
    【計算機編程語言】JAVA-MyBatis(Eclipse),計算機編程語言,java,mybatis,eclipse

2.1.3導(dǎo)入依賴

pom.xml

    <!-- mysql依賴 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.34</version>
    </dependency>

    <!--mybatis依賴 -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.3</version>
    </dependency>

    <!-- junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>

2.2創(chuàng)建一個模塊

第一步:創(chuàng)建Maven模塊

【計算機編程語言】JAVA-MyBatis(Eclipse),計算機編程語言,java,mybatis,eclipse

第二步:

【計算機編程語言】JAVA-MyBatis(Eclipse),計算機編程語言,java,mybatis,eclipse

2.2.1.編寫Mybatis的核心配置文件

src/main/resouce/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/mybatis?useSSl=true&amp;useUnicode=true&amp;characterEncoding=utf8" />
				<property name="username" value="root" />
				<property name="password" value="123456" />
			</dataSource>
		</environment>
	</environments>
</configuration>
2.2.2.編寫Mybatis的工具類
//sqlSessionFactory - sqlSession
public class MybatisUtil {
	private static SqlSessionFactory sqlSessionFactory;// 提升作用域

	static {

		try {
			// 使用mybatis第一步:獲取sqlSessionFactory對象
			String resource = "mybatis-config.xml";
			InputStream inputStream = Resources.getResourceAsStream(resource);
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static SqlSession getSqlSession() {
		return sqlSessionFactory.openSession();
	}
}

2.3編寫代碼

2.3.1實體類

mybatis/user 表一一對應(yīng)的實體類

package com.CYQ.pojo;

public class User {
	private int id;
	private String name;
	private String pwd;

	public User() {
		super();
	}

	public User(int id, String name, String pwd) {
		super();
		this.id = id;
		this.name = name;
		this.pwd = pwd;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", pwd=" + pwd + "]";
	}

}
2.3.2Dao接口
public interface UserDao {
	List<User> getUserList();
}
2.3.3接口實現(xiàn)類

由原來UserDaoImpl轉(zhuǎn)換為一個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">
<!-- namespace=綁定一個對應(yīng)的Dao/Mapper接口 -->
<mapper namespace="com.CYQ.dao.UserDao">
	<!-- select查詢語句 -->
	<select id="getUserList" resultType="com.CYQ.pojo.User">
		select * from mybatis.user;
	</select>
</mapper>
2.3.4.配置Mapper

mybatis-config.xml中進行配置

<!-- 每一個Mapper.xml都需要在mybatis-config的核心配置文件中注冊?。?! -->
<mappers>
	<mapper resource="com/CYQ/dao/UserMapper.xml"></mapper>
</mappers>

2.4測試

  • junit
public class UserDaoTest {
	
	@Test
	public void test() {
		//第一步:獲取sqlSession對象
		SqlSession sqlSession = MybatisUtil.getSqlSession();
		
		//方式一:getMapper
		UserDao userDao = sqlSession.getMapper(UserDao.class);//得到接口
		List<User> userList = userDao.getUserList();//得到接口內(nèi)的方法
		
		for (User user : userList) {
			System.out.println(user);
		}		
		//關(guān)閉sqlSession
		sqlSession.close();	
	}
}

2.5可能出現(xiàn)的問題

注意點:

出現(xiàn)異常:問題常出現(xiàn)在 -

1.查看UserDao的實現(xiàn)類UserMapper.xml問題

2.是否在mybatis-config.xml中配置

具體:

1.配置文件沒有注冊(mybatis-config.xml的問題)

2.綁定接口錯誤(UserMapper.xml的問題)

3.方法名稱不對(UserMapper.xml的問題)

4.返回類型不對(UserMapper.xml的問題)

所有的操作,均和接口(UserMapper.xml)和配置文件(Mybatis-config.xml)有關(guān)系

3.CRUD

mybatis-config.xml

<mapper namespace="com.CYQ.dao.UserMapper">
	<!-- select查詢語句 -->
	<select id="getUserList" resultType="com.CYQ.pojo.User">
		select * from mybatis.user;
	</select>
</mapper>

3.1namespace

namespace的包名要和接口(Dao/Mapper)的名字一致

3.2增刪改查

選擇:查詢語句

id:就是對應(yīng)的namespace中對應(yīng)的方法名

resultType:Sql語句執(zhí)行的返回值!

parameterType:參數(shù)的類型

步驟:

第一步:編寫接口

public interface UserMapper {
	//查詢?nèi)坑脩?/span>
	List<User> getUserList();
	//根據(jù)id查詢用戶
	User getUserById(int id);
	//insert一個用戶
	int addUser(User user);
	//修改用戶
	int updateUser(User user);
	//刪除用戶
	int deleteUser(int id);
}

第二步:編寫對應(yīng)的對應(yīng)的SQL語句

<mapper namespace="com.CYQ.dao.UserMapper">
	<!-- select查詢語句 -->
	<select id="getUserList" resultType="com.CYQ.pojo.User">
		select * from mybatis.user;
	</select>
	
	<select id="getUserById" parameterType="int" resultType="com.CYQ.pojo.User">
		select * from mybatis.user where id=#{id}
	</select>
	
	<!-- 對象中的屬性可以直接取出來 -->
	<insert id="addUser" parameterType="com.CYQ.pojo.User">
		insert into mybatis.user(id,name,pwd) values (#{id},#{name},#{pwd});
	</insert>
	
	<update id="updateUser" parameterType="com.CYQ.pojo.User">
		update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id};
	</update>
	
	<delete id="deleteUser" parameterType="int">
		delete from mybatis.user where id=#{id};
	</delete>
	
</mapper>

第三步:測試

增刪改:一定需要提交事務(wù)

查:不需要提交事務(wù)

public class UserDaoTest {
	//查詢
	@Test
	public void test() {
		//第一步:獲取sqlSession對象
		SqlSession sqlSession = MybatisUtil.getSqlSession();
		
		//方式一:getMapper(推薦使用?。?/span>
		UserMapper userDao = sqlSession.getMapper(UserMapper.class);//得到接口
		List<User> userList = userDao.getUserList();
		
		//方式二:(不推薦使用)
		//List<Object> userList = sqlSession.selectList("com.CYQ.dao.UserDao.getUserList");
		
		for (Object user : userList) {
			System.out.println(user);
		}		
		//關(guān)閉sqlSession
		sqlSession.close();	
	}
	//查詢
	@Test
	public void test01() {
		SqlSession sqlSession = MybatisUtil.getSqlSession();
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//獲得接口
		User user = userMapper.getUserById(3);
		System.out.println(user.toString());
		sqlSession.close();
	}
	
	//增刪改 - 需要提交事務(wù)!??!
	@Test
	public void test02() {
		SqlSession sqlSession = MybatisUtil.getSqlSession();
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//獲得接口
		userMapper.addUser(new User(4, "陳朋", "1995"));
		//提交事務(wù):
		sqlSession.commit();
		//關(guān)閉sqlSession
		sqlSession.close();
	}
	
	//修改
	@Test
	public void test03() {
		SqlSession sqlSession = MybatisUtil.getSqlSession();
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//獲得接口
		
		userMapper.updateUser(new User(1,"陳雨晴","1997"));
		
		//提交事務(wù):
		sqlSession.commit();
		//關(guān)閉sqlSession
		sqlSession.close();
	}
	
	//刪除
	@Test
	public void test04() {
		SqlSession sqlSession = MybatisUtil.getSqlSession();
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//獲得接口
		
		userMapper.deleteUser(4);
		
		//提交事務(wù):
		sqlSession.commit();
		//關(guān)閉sqlSession
		sqlSession.close();
	}
	
}

3.3萬能Map

假設(shè),我們的實體類(或者數(shù)據(jù)庫中的表),屬性(或字段)過多,我們應(yīng)當考慮使用map!

map傳遞參數(shù),直接在sql中取出key即可;對象傳遞參數(shù),需要直接在sql中取對象的屬性。

只有一個基本參數(shù)的情況下,可以直接在sql中取到

多個參數(shù)用Map,或者注解!

對象和map的對比(認真對比)

UserMapper.xml

對象

<insert id="addUser" parameterType="com.CYQ.pojo.User">
		insert into mybatis.user(id,name,pwd) values (#{id},#{name},#{pwd});
</insert>

map

<insert id="addUser2" parameterType="map">
		insert into mybatis.user(id,name,pwd) values (#{userId},#{userName},#{password});
</insert>

UserMapperTest.java

對象

@Test
	public void test02() {
		SqlSession sqlSession = MybatisUtil.getSqlSession();
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//獲得接口
		userMapper.addUser(new User(4, "陳朋", "1995"));
		//提交事務(wù):
		sqlSession.commit();
		//關(guān)閉sqlSession
		sqlSession.close();
	}

map

//增加
@Test
public void test002() {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//獲得接口
    HashMap<String,Object> map = new HashMap<String, Object>();
    map.put("userId", 4);
    map.put("userName", "楊帆");
    map.put("password", "1996");
    userMapper.addUser2(map);
    //提交事務(wù):
    sqlSession.commit();
    //關(guān)閉sqlSession
    sqlSession.close();
}

3.4模糊查詢

模糊查詢:一定要防止sql注入的問題

防止SLQ注入的寫法,在業(yè)務(wù)中使用多?。?!

第一步:接口

public interface UserMapper {
	//查詢?nèi)坑脩?	List<User> getUserLike();
}

第二步:SQL

<select id="getUserById" resultType="com.CYQ.pojo.User">
		select * from mybatis.user where name like #{value}
</select>

<!--有效防止sql注入的寫法-->
<select id="getUserById" resultType="com.CYQ.pojo.User">
		select * from mybatis.user where name like "%"#{value}"%"
</select>

第三步:測試

@Test
public void test01() {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//獲得接口
    List<User> userList = userMapper.getUserLike("%陳%");
    for (Object user : userList) {
        System.out.println(user);
    }
    sqlSession.close();
}

//防止sql注入
@Test
public void test01() {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//獲得接口
    List<User> userList = userMapper.getUserLike("陳");
    for (Object user : userList) {
        System.out.println(user);
    }
    sqlSession.close();
}

4.配置解析

4.1核心配置文件

  • mybatis-config.xml
  • MyBatis 的配置文件包含了會深深影響 MyBatis 行為的設(shè)置和屬性信息

configuration(配置)

  • properties(屬性)
  • settings(設(shè)置)
  • typeAliases(類型別名)
  • typeHandlers(類型處理器)
  • objectFactory(對象工廠)
  • plugins(插件)
  • environments(環(huán)境配置)
    • environment(環(huán)境變量)
      • transactionManager(事務(wù)管理器)
      • dataSource(數(shù)據(jù)源)
  • databaseIdProvider(數(shù)據(jù)庫廠商標識)
  • mappers(映射器)

4.2環(huán)境配置(environments)

  • MyBatis 可以配置成適應(yīng)多種環(huán)境
  • 不過要記住:盡管可以配置多個環(huán)境,但每個 SqlSessionFactory 實例只能選擇一種環(huán)境。
<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/mybatis?useSSl=true&amp;useUnicode=true&amp;characterEncoding=utf8"/>
            <property name="username" value="root"/>
            <property name="password" value="123456"/>
        </dataSource>
    </environment>		
</environments>

事務(wù)管理器transactionManager的type:JDBC和MANAGED兩種

數(shù)據(jù)源dataSource的type:UNPOOLED/POOLED/JNDI

Mybatis默認的事務(wù)管理器是:JDBC,連接池:POOLED

4.3屬性(Properties)

我們可通過properties屬性來實現(xiàn)引用配置文件

這些屬性可以在外部配置,并可以進行動態(tài)替換。既可以在典型的 Java 屬性文件中配置,也可以在 properties 元素的子元素中設(shè)置【db.properties】

4.3.1編寫配置文件

位置:src/main/resources/db.properties

driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/mybatis?useSSl=true&useUnicode=true&characterEncoding=utf8
username = root
password = 123456

4.3.2在核心配置文件mybatis-config.xml中引入

<!-- 引入外部配置文件 -->
<properties resource="db.properties" >
    <property name="username" value="root"/>
    <property name="password" value="1233456"/>
</properties>

兩種方式:1.直接引入配置文件 2.在中添加標簽。

? 如果兩個配置矛盾,優(yōu)先使用配置文件中的。

環(huán)境配置可更改為:

<environments default="development">
    <environment id="development">
        <transactionManager type="JDBC" />
        <dataSource type="POOLED">
            <property name="driver" value="${driver}" />
            <property name="url" value="${url}" />
            <property name="username" value="${username}" />
            <property name="password" value="${password}" />
        </dataSource>
    </environment>
</environments>

4.4類型別名(typeAliases)

  • 類型別名可為 Java 類型設(shè)置一個縮寫名字

  • 存在的意義:減少類完全限定名的冗余

第一步:修改mybatis-config.xml

<!-- 可以給實體類起別名 -->
<typeAliases>
    <typeAlias type="com.CYQ.pojo.User" alias="User"/>
</typeAliases>

<!-- 掃描實體類的包,默認別名為類名的首字母小寫 -->
<typeAliases>
    <package name="com.CYQ.pojo"/>
</typeAliases>

第二步:修改UserMapper.xml

<select id="getUserList" resultType="User">
    select * from mybatis.user;
</select>

<!--大寫也可以,即:“user”="User"-->
<select id="getUserList" resultType="user">
    select * from mybatis.user;
</select>

兩種方式:

  • typeAlias

  • package

實體類比較少的時候,使用第一種;實體類比較多的時候,使用第二種

第一種可以自定義別名;第二種不可以自定義別名,但是可以通過注解自定義別名。

4.5設(shè)置(settings)

  • 這是 MyBatis 中極為重要的調(diào)整設(shè)置,它們會改變 MyBatis 的運行時行為。

4.6映射器(mappers)

(推薦)方式一:通過***.xml文件

<!-- 每一個Mapper.xml都需要在mybatis的核心配置文件中注冊?。?! -->
<mappers>
    <mapper resource="com/CYQ/dao/UserMapper.xml"></mapper>
</mappers>

方式二:通過class文件

<mappers>
    <mapper class="com.CYQ.dao.UserMapper"/>
</mappers>

注意點:

  • 接口和它的Mapper配置文件必須同名
  • 接口和它的Mapper配置文件必須在同一個包下

4.7其他配置

  • typeHandlers(類型處理器)
  • objectFactory(對象工廠)
  • plugins(插件)
    • mybatis-genetator-core
    • mybatis-plus
    • 通用mapper

4.8生命周期和作用域

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-F1QZofHV-1690204448188)(MyBatis.assets/image-20210115155310926.png)]

生命周期和作用域,是至關(guān)重要的,因為錯誤的使用會導(dǎo)致非常嚴重的并發(fā)問題

SqlSessionFactoryBuilder

  • 一旦創(chuàng)建了SqlSessionFactory,就不再需要了
  • 局部變量

SqlSessionFactory

  • 想象成:數(shù)據(jù)庫連接池

  • 一旦創(chuàng)建就一直存在,沒有任何理由丟棄它或重新創(chuàng)建另一個實例

  • 最佳作用域:應(yīng)用作用域

  • 最簡單的就是使用單例模式或者靜態(tài)單例模式

SqlSession

  • 連接到連接池的一個請求

  • SqlSession的實例不是線程安全的,因此是不能被共享的,所以最佳作用域:請求/方法作用域

  • 需要關(guān)閉,否則資源被占用!

    [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-45erbNyG-1690204448189)(MyBatis.assets/image-20210115160635011.png)]

這里的每一個Mapper,就代表一個具體的業(yè)務(wù)

5.屬性名和字段名不一致

例子見:Mybatis-03 Module

5.1問題

新建一個項目,拷貝之前的,測試實體類字段不一致的情況

數(shù)據(jù)庫結(jié)構(gòu)

數(shù)據(jù)庫結(jié)構(gòu):
mybatis(數(shù)據(jù)庫)
		user(表)
			id(字段)
			name(字段)
			pwd(字段)

實體類構(gòu)造:構(gòu)造類的屬性和字段不對應(yīng)

public class User {
	private int id;
	private String name;
	private String password;
    ...
}

測試代碼

@Test
public void getUserById() {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);// 獲得接口
    User user = userMapper.getUserById(5);
    System.out.println(user.toString());
    sqlSession.close();
}

測試出現(xiàn)問題:查不出來pwd

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-MUDoEdO4-1690204448189)(MyBatis.assets/image-20210115190327962.png)]

5.2resultMap

結(jié)果集映射:

id	 name	 pwd
id 	 name    pasword
<mapper namespace="com.CYQ.dao.UserMapper">

	<!-- 結(jié)果集映射 -->
	<resultMap type="User" id="userMap">
		<!-- column-數(shù)據(jù)庫中的字段 property-實體類中的屬性 -->
		<result column="id" property="id" />
		<result column="name" property="name" />
		<result column="pwd" property="password" />
	</resultMap>

	<select id="getUserById" resultMap="userMap">
		select * from user where id=#{id}
	</select>

</mapper>
  • resultMap 元素是 MyBatis 中最重要最強大的元素。

  • ResultMap 的設(shè)計思想是:對簡單的語句做到零配置,對于復(fù)雜一點的語句,只需要描述語句之間的關(guān)系。

5.3解決方法

1.起別名:

<select id="getUserById" parameterType="int" resultType="User">
		select id,name,pwd as password from mybatis.user where id=#{id}
</select>

2.結(jié)果集映射

<mapper namespace="com.CYQ.dao.UserMapper">

	<!-- 結(jié)果集映射 -->
	<resultMap type="User" id="userMap">
		<!-- column-數(shù)據(jù)庫中的字段 property-實體類中的屬性 -->
		<result column="id" property="id" />
		<result column="name" property="name" />
		<result column="pwd" property="password" />
	</resultMap>

	<select id="getUserById" resultMap="userMap">
		select * from user where id=#{id}
	</select>

</mapper>

6.日志

6.1日志工廠

如果一個數(shù)據(jù)庫操作出現(xiàn)異常,我們需要排錯。日志就是最好的助手!

曾經(jīng):sout,dubug

現(xiàn)在:日志工廠

【計算機編程語言】JAVA-MyBatis(Eclipse),計算機編程語言,java,mybatis,eclipse

Mybatis中,包含的種類:

  • SLF4J

  • LOG4J 【掌握】

  • LOG4J2

  • JDK_LOGGING

  • COMMONS_LOGGING

  • STDOUT_LOGGING【掌握】

  • NO_LOGGING

在Mybatis中,具體使用哪個日志實現(xiàn),在設(shè)置中實現(xiàn)

<settings>
    <!-- 配置日志工廠 -->
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

STDOUT_LOGGING - 為標準日志輸出

結(jié)果顯示:

【計算機編程語言】JAVA-MyBatis(Eclipse),計算機編程語言,java,mybatis,eclipse

6.2LOG4J

什么是log4J

  • Log4j是Apache的一個開源項目
  • 可以控制日志信息輸送的目的地是控制臺、文件、GUI組件,甚至是套接口服務(wù)器、NT的事件記錄器、UNIX Syslog守護進程等
  • 可以控制每一條日志的輸出格式
  • 通過一個配置文件來靈活地進行配置,而不需要修改應(yīng)用的代碼

第一步:導(dǎo)入依賴

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

第二步:配置properties文件

log4j.properties

#將等級為DEBUG的日志信息輸出到console和file這兩個目的地,console和file的定義在下面的代碼
log4j.rootLogger=DEBUG,console,file

#控制臺輸出的相關(guān)設(shè)置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#文件輸出的相關(guān)設(shè)置
log4j.appender.file = org.apache.log4j.RollingFileAppender
		#日志文件生成位置,可以自定義
log4j.appender.file.File=./log/CYQ.log  
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd HH:mm:ss}][%c]%m%n

#日志輸出級別
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

第三步:配置log4J為日志工廠實現(xiàn)

<settings>
    <!-- 配置LOG4J實現(xiàn) -->
    <setting name="logImpl" value="LOG4J"/>
</settings>

第四步:測試使用

直接junit測試UserMapperTest.java

【計算機編程語言】JAVA-MyBatis(Eclipse),計算機編程語言,java,mybatis,eclipse

6.3LOG4J簡單使用

第一步:導(dǎo)包(一定是log4j的Logger)

import org.apache.log4j.Logger;

第二步:日志對象,參數(shù)為當前類的class

static Logger logger = Logger.getLogger(UserDaoTest.class);

第三步:日志級別

@Test
public void testLog4j() {
    logger.info("info:進入了testLog4j方法");
    logger.debug("debug:進入了testLog4j方法");
    logger.error("error:");
}

7.分頁

思考:為什么要分頁?

  • 減少數(shù)據(jù)的處理量

7.1使用Limit分頁

SELECT * FROM user limit startindex,pagesize

SELECT * FROM user limit 3;--[0,3]

使用Mybatis實現(xiàn)分頁?。ê诵模篠QL)

1.接口

public interface UserMapper {
    //Mybatis實現(xiàn)分頁
    List<User> getUserByLimit(Map<String, Integer> map);
}

2.UserMapper.xml

<!-- Limit分頁 -->
<select id="getUserByLimit" parameterType="map"
    resultMap="userMap">
    SELECT * FROM user limit #{startIndex},#{pageSize}
</select>

3.測試

@Test
public void getUserByLimit() {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    HashMap<String,Integer> map = new HashMap<String, Integer>();
    map.put("startIndex", 0);
    map.put("pageSize", 2);

    List<User> users = userMapper.getUserByLimit(map);
    for (User user : users) {
        System.out.println(user);
    }	
    sqlSession.close();
}

7.2 RowBounds分頁

不再使用SQL實現(xiàn)分頁

1.接口:

public interface UserMapper {
    //rouBounds實現(xiàn)分頁
    List<User> getUserByRowBounds();
}

2.UserMapper.xml

<!-- RowBounds分頁 -->
<select id="getUserByRowBounds" resultMap="userMap">
    SELECT * FROM user
</select>

3.測試

@Test
public void getUserByRowBounds() {
    SqlSession sqlSession = MybatisUtil.getSqlSession();

    //RowBounds實現(xiàn)
    //每頁顯示兩個,從第二個對象開始
    RowBounds rowBounds = new RowBounds(1,2);//底標從0開始

    //通過java代碼實現(xiàn)分頁
    List<Object> userList = sqlSession.selectList("com.CYQ.dao.UserMapper.getUserByRowBounds",null,rowBounds);
    for (Object object : userList) {
        System.out.println(object);
    }
    sqlSession.close();
}

7.3分頁插件(了解)

8.注解開發(fā)

Mybatis-04

8.1面向接口編程

  • 大家之前都學過面向?qū)ο缶幊?,也學習過接口,但在真正的開發(fā)中,很多時候我們會選擇面向接口編程
  • 根本原因 : 解耦 , 可拓展 , 提高復(fù)用 , 分層開發(fā)中 , 上層不用管具體的實現(xiàn) , 大家都遵守共同的標準 , 使得開發(fā)變得容易 , 規(guī)范性更好
  • 在一個面向?qū)ο蟮南到y(tǒng)中,系統(tǒng)的各種功能是由許許多多的不同對象協(xié)作完成的。在這種情況下,各個對象內(nèi)部是如何實現(xiàn)自己的,對系統(tǒng)設(shè)計人員來講就不那么重要了;
  • 而各個對象之間的協(xié)作關(guān)系則成為系統(tǒng)設(shè)計的關(guān)鍵。小到不同類之間的通信,大到各模塊之間的交互,在系統(tǒng)設(shè)計之初都是要著重考慮的,這也是系統(tǒng)設(shè)計的主要工作內(nèi)容。面向接口編程就是指按照這種思想來編程。

關(guān)于接口的理解

  • 接口從更深層次的理解,應(yīng)是定義(規(guī)范,約束)與實現(xiàn)(名實分離的原則)的分離。
  • 接口的本身反映了系統(tǒng)設(shè)計人員對系統(tǒng)的抽象理解。
  • 接口應(yīng)有兩類:
    • 第一類是對一個個體的抽象,它可對應(yīng)為一個抽象體(abstract class);
    • 第二類是對一個個體某一方面的抽象,即形成一個抽象面(interface);
  • 一個體有可能有多個抽象面。抽象體與抽象面是有區(qū)別的。

三個面向區(qū)別

  • 面向?qū)ο笫侵?,我們考慮問題時,以對象為單位,考慮它的屬性及方法 .
  • 面向過程是指,我們考慮問題時,以一個具體的流程(事務(wù)過程)為單位,考慮它的實現(xiàn) .
  • 接口設(shè)計與非接口設(shè)計是針對復(fù)用技術(shù)而言的,與面向?qū)ο螅ㄟ^程)不是一個問題.更多的體現(xiàn)就是對系統(tǒng)整體的架構(gòu)

8.2使用注解開發(fā)

1.注解直接在接口上實現(xiàn)

public interface UserMapper {
	
	@Select("select * from user")
	List<User> getUsers(); 
}

2.在核心配置文件(mybatis-config.xml)中綁定接口

<!-- 綁定接口 -->
<mappers>
    <mapper class="com.CYQ.dao.UserMapper"/>
</mappers>

3.測試

@Test
public void test() {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<User> users = mapper.getUsers();
    for (User user : users) {
        System.out.println(user);
    }
    sqlSession.close();
}
}

本質(zhì):反射機制實現(xiàn)

底層:動態(tài)代理

代理模式示意圖:

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-DoWoD8yc-1690204448192)(MyBatis.assets/image-20210116182759016.png)]

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-96BVGasS-1690204448192)(MyBatis.assets/image-20210116185705344.png)]

8.3CRUD

我們可以在工具類創(chuàng)建的時候,實現(xiàn)自動提交事務(wù)!

第一步:設(shè)置自動提交事務(wù)為true

在MybatisUtil.java中設(shè)置

public static SqlSession getSqlSession() {
    //默認為false,我們設(shè)置為true,true - 代表自動提交
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    return sqlSession;
}

第二步:接口

public interface UserMapper {
	
	//方法存在多個參數(shù),所有的參數(shù)前面必須加上:@Param注解
	@Select("select * from user where id=#{id}")
	User getUserById(@Param("id")int id);
	
	@Insert("insert into user (id,name,pwd) values (#{id},#{name},#{password})")
	int addUser(User user);
	
	@Update("update user set name=#{name},pwd=#{password} where id=#{id}")
	int updateUser(User user);
	
	@Delete("delete from user where id=#{id}")
	int deleteUser(@Param("id")int id);
	
}

第三步:測試

public class UserDaoTest {

	@Test
	public void test() {
		SqlSession sqlSession = MybatisUtil.getSqlSession();
		UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//		List<User> users = mapper.getUsers();

//		User user = mapper.getUserById(4);

//		 mapper.addUser(new User(6,"汪蘇瀧","1989"));

		mapper.updateUser(new User(5, "許嵩", "1987"));

		sqlSession.close();
	}
}

關(guān)于@Param()注解

1.基本類型的參數(shù),無論有多少個,每個都需要加

2.引用類型不用加

3.如果只有一個基本類型,可以忽略,但是建議大家寫上

4.我們在SQL中引用的,就是我們在@Param()中設(shè)定的屬性名!??!

#{},${}區(qū)別

  • #{ }不存在sql注入的問題,但是${}存在

9.LomBok

9.1使用步驟:

第一步:安裝LomBok插件

具體步驟參考:安裝LomBok

第二步:在項目中導(dǎo)入lombok的jar包(Maven倉庫形式)

  <!-- lombok - 此處導(dǎo)入的版本是使用人數(shù)最多的! -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
    <scope>provided</scope>
</dependency>

第三步:寫注解

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
	private int id;
	private String name;
	private String password;
}
@Getter/@Setter
@FiledNameConstants
@ToString
@EqualsAndHashCode
@AllArgsConstructor/@RequiredArgsConstructor/@NoArgsConstructor
@Data
@Builder
@Singular
@Delegate
@value
@Accessors
@wither
@NonNull
@Cleanup
@Synchronized
@Log
@SneakyThrows

說明部分:

@Data:無參構(gòu)造/Getter&Setter/toString/hashCode/equals

@AllArgsConstructor:全參構(gòu)造

@NoArgsConstructor:無參構(gòu)造

9.2優(yōu)缺點

優(yōu)點:

  • 提升開發(fā)效率
  • 屬性做修改時,也簡化了維護這些屬性所生成的getter/setter方法等

缺點:

  • 不支持多種參數(shù)構(gòu)造器的重載(可手動去添加)
  • 雖省略了getter/setter,但降低了代碼的可讀性

10 多對一 處理

Mybatis-05

多對一:

  • 多個學生,對應(yīng)一個老師
  • 對于學生而言, 關(guān)聯(lián) 多個學生關(guān)聯(lián)一個老師【多對一】
  • 對于老師二眼,集合 ,一個老師有很多學生【一對多】

創(chuàng)建相關(guān)表

CREATE TABLE `teacher` (
  `id` INT(10) NOT NULL,
  `name` VARCHAR(30) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=UTF8;

INSERT INTO teacher(`id`, `name`) VALUES (1, '秦老師'); 

CREATE TABLE `student` (
  `id` INT(10) NOT NULL,
  `name` VARCHAR(30) DEFAULT NULL,
  `tid` INT(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fktid` (`tid`),
  CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=UTF8;
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小紅', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小張', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');

10.1測試環(huán)境搭建:

第一步:導(dǎo)入lombok

第二步:新建實體類:Teacher/Student

//實體類:學生
@Data
public class Student {
	private int id;
	private String name;	
	//學生需要關(guān)聯(lián)一個老師
	private Teacher teacher;
}

//實體類:老師
@Data
public class Teacher {
	private int id;
	private String name;
}

第三步:編寫接口文件:TeacherMapper.java StudentMapper.java

? 編寫對應(yīng)xml文件:TeacherMapper.xml StudentMapper.xml

第四步:核心文件(mybatis-config.xml)中配置

第五步:測試

10.2按照查詢嵌套處理

StudentMapper.xml

<mapper namespace="com.CYQ.dao.StudentMapper">

	<!-- 思路: 
	1.查詢所有的學生信息 
	2.根據(jù)查詢出來的學生的tid,尋找對應(yīng)的老師 
	-->

	<select id="getStudent" resultMap="StudentTeacher">
		select * from student
	</select>

	<resultMap type="Student" id="StudentTeacher">
		<result property="id" column="id" />
		<result property="name" column="name" />
		<!-- 復(fù)雜的屬性:我們需要單獨處理  對象:association  集合:collection-->
		<association property="teacher" column="tid" javaType="Teacher" select="getTeacher" />
	</resultMap>

	<select id="getTeacher" resultType="Teacher">
		select * from teacher where id=#{tid}
	</select>
    
</mapper>

10.3按照結(jié)果嵌套處理(常用)

<mapper namespace="com.CYQ.dao.StudentMapper">

	<!-- 按照結(jié)果嵌套處理 -->
	<select id="getStudent2" resultMap="StudentTeacher2">
		select s.id sid,s.name sname,t.name tname
		from student s ,teacher t
		where s.tid=t.id	
	</select>
	
	<resultMap type="Student" id="StudentTeacher2">
		<result property="id" column="sid"/>
		<result property="name" column="sname"/>
		<association property="teacher" javaType="Teacher">
			<result property="name" column="tname"/>
		</association>
	</resultMap>
    
</mapper>

回顧MySQL多對一查詢方式

  • 子查詢
  • 聯(lián)表查詢

11.一對多處理

Mybatis-06

比如:一個老師擁有多個學生!

對于老師而言,就是一對多的關(guān)系!

11.1環(huán)境搭建:

第一步:導(dǎo)入lombok

第二步:新建實體類:Teacher/Student

//實體類:學生
@Data
public class Student {
	private int id;
	private String name;
	private int tid;
}

//實體類:老師
@Data
public class Teacher {
	private int id;
	private String name;
	// 一個老師有多個學生
	private List<Student> students;
}

第三步:編寫接口文件:TeacherMapper.java StudentMapper.java

? 編寫對應(yīng)xml文件:TeacherMapper.xml StudentMapper.xml

第四步:核心文件(mybatis-config.xml)中配置

第五步:測試

11.2按照查詢嵌套處理

TeacherMapper.xml

<mappers>
    <select id="getTeacher2" resultMap="TeacherStudent2">
		select * from teacher where id=#{tid}
	</select>
	<resultMap type="teacher" id="TeacherStudent2">
		<collection property="students" javaType="ArrayList" ofType="Student" select="getStduentByTeacherId" column="id">
		
		</collection>
	</resultMap>
	
	<select id="getStduentByTeacherId" resultType="Student">
		select * from student where tid=#{id}
	</select>
</mappers>

11.3按照結(jié)果嵌套處理(常用)

TeacherMapper.xml

<mapper namespace="com.CYQ.dao.TeacherMapper">

	<select id="getTeacher" resultMap="TeacherStudent">
		select s.id sid,s.name sname,t.name tname,t.id tid 
		from student s,teacher t 
		where s.tid=t.id and t.id=#{tid}
	</select>
	
	<resultMap type="Teacher" id="TeacherStudent">
		<result property="id" column="tid"/>
		<result property="name" column="tname"/>
		<collection property="students" ofType="Student">
			<result property="id" column="sid"/>
			<result property="tid" column="tid"/>
		</collection>
	</resultMap>

</mapper>

11.4小結(jié)

1.關(guān)聯(lián) - association 【多對一】

2.集合:collection 【一對多

3.javaType & ofType

  • javaType:用來指定實體類中屬性的類型
  • ofType:用來指定映射到List或者集合中的pojo類型 - 泛型中的約束類型

注意點:

  • 保證sql的可讀性
  • 注意【一對多】,【多對一】,屬性名和字段的問題
  • 問題不好排查錯誤,建議使用日志

面試高頻

  • MySLQ 引擎
  • InnoDB 底層原理
  • 索引
  • 索引優(yōu)化

12.動態(tài)SQL

Mybatis-07

什么是動態(tài)SQL

? 動態(tài)SQL就是指根據(jù)不同的條件,生成不同的SQL語句

if
choose(when,otherwise)
trim(where,set)
foreach

12.1搭建環(huán)境

創(chuàng)建相關(guān)表

CREATE TABLE `blog`(
`id` VARCHAR(50) NOT NULL COMMENT '博客id',
`title` VARCHAR(100) NOT NULL COMMENT '博客標題',
`author` VARCHAR(30) NOT NULL COMMENT '博客作者',
`create_time` DATETIME NOT NULL COMMENT '創(chuàng)建時間',
`views` INT(30) NOT NULL COMMENT '瀏覽量'
)ENGINE=INNODB DEFAULT CHARSET=utf8

第一步:導(dǎo)包

第二步:編寫實體類

@Data
public class Blog {
	private String id;
	private String title;
	private String author;
	private Date createTime;
	private int views;
}

第三步:

編寫接口BlogMapper.java

ublic interface BlogMapper {
	//插入數(shù)據(jù):
	int addBlog(Blog blog);
}

編寫*Mapper.xml

<mapper namespace="com.CYQ.dao.BlogMapper">
<!-- ...-->
</mapper>

第四步:核心配置文件(mybatis-config.xml)中配置

<mappers>
    <mapper class="com.CYQ.dao.BlogMapper"/>
</mappers>

第五步:測試

12.2 IF

BlogMapper.xml

<mapper>
	<select id="queryBlogIf" parameterType="map" resultType="Blog">
		select * from blog where 1=1
		<if test="title!=null">
			and title = #{title}
		</if>
		<if test="author!=null">
			and author=#{author}
		</if>
	</select>
</mapper>

測試:

@Test
public void queryBlogIf() {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    HashMap<Object, Object> map = new HashMap<Object, Object>();
    map.put("title", "大娛樂家");
    map.put("author", "汪蘇瀧");

    List<Blog> blogs = mapper.queryBlogIf(map);
    for (Blog blog : blogs) {
        System.out.println(blog);
    }

    sqlSession.close();
}

12.3 choose(when,otherwise)

相當于case … switch …

<mapper>
    <select id="queryBlogChoose" parameterType="map"
		resultType="Blog">
		select * from blog
		<where>
            <!--choose下的,只執(zhí)行一個,要么執(zhí)行when的,要么執(zhí)行otherwise的-->
			<choose>
				<when test="title!=null">
					title = #{title}
				</when>
				<when test="author!=null">
					and author=#{author}
				</when>
                <!--至少會執(zhí)行:otherwise內(nèi)部的-->
				<otherwise>
				 and views=#{views}
				</otherwise>	
			</choose>
		</where>
	</select>
</mapper>

12.4 trim(where,set)

where

<mapper>
    <select id="queryBlogIf" parameterType="map" resultType="Blog">
        select * from blog
        <where>
            <if test="title!=null">
                and title = #{title}
            </if>
            <if test="author!=null">
                and author=#{author}
            </if>
        </where>
    </select>
</mapper>

set

<mapper>
    <update id="updateBlog" parameterType="map">
            update blog
            <set>
                <if test="title!=null">
                    title = #{title},
                </if>
                <if test="author!=null">
                    author=#{author}
                </if>
            </set>
            where id=#{id}
    </update>
</mapper>

所謂的動態(tài)SQL,本質(zhì)還是SQL語句,只是我們可以在sql層面,去執(zhí)行一個邏輯代碼

12.5 SQL片段

有時候,我們會將一些功能的 部分,提取出來,方便復(fù)用!

第一步:使用標簽,抽取出公共的部分

第二步:在需要使用sql的部分,使用標簽引用即可

<mapper namespace="com.CYQ.dao.BlogMapper">
	<!-- 使用sql抽出公共的部分 -->
	<sql id="if-title-author">
		<if test="title!=null">
			and title = #{title}
		</if>
		<if test="author!=null">
			and author=#{author}
		</if>
	</sql>

	<select id="queryBlogIf" parameterType="map" resultType="Blog">
		select * from blog
		<where>
			<!-- 在需要使用sql的部分,使用include -->
			<include refid="if-title-author"/>
		</where>
	</select>
</mapper>

注意:

  • 最好基于單表,來定義SQL片段
  • 標簽中不要存在標簽
  • 中盡量只包含一些

12.6 foreach

select * from user where 1=1 and (id=1 or id=2 or id=3)
<select id="queryBlogForeach" parameterType="map" resultType="Blog">
    select * from blog
    <where>
        <foreach collection="ids" item="id" open="and (" close=")" separator="or">
            id=#{id}
        </foreach>
    </where>
</select>

測試:

@Test
public void queryBlogForeach() {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    HashMap<Object, Object> map = new HashMap<Object, Object>();

    int[] ids = {1,2,3};

    map.put("ids", ids);
    mapper.queryBlogForeach(map);
    sqlSession.close();
}

動態(tài)SQL就是在拼接SQL語句,我們只要保證SQL的正確性,按照SQL的格式,去排列組合就可以了

建議:現(xiàn)在MySQL中寫出完整的SQL,再對應(yīng)的去修改成我們的動態(tài)SQL

13.緩存

13.1簡介

查詢  :  連接數(shù)據(jù)庫,耗資源
	一次查詢的結(jié)果,暫存在可以直接取到的地方?。?!	 - 內(nèi)存   - 放在內(nèi)存中的這些數(shù)據(jù)就叫“緩存”
	
	我們再次查詢相同的數(shù)據(jù)的時候,直接走“緩存”就可以,不用走數(shù)據(jù)庫

1、什么是緩存 [ Cache ]?

  • 存在內(nèi)存中的臨時數(shù)據(jù)。
  • 將用戶經(jīng)常查詢的數(shù)據(jù)放在緩存(內(nèi)存)中,用戶去查詢數(shù)據(jù)就不用從磁盤上(關(guān)系型數(shù)據(jù)庫數(shù)據(jù)文件)查詢,從緩存中查詢,從而提高查詢效率,解決了高并發(fā)系統(tǒng)的性能問題。

2、為什么使用緩存?

  • 減少和數(shù)據(jù)庫的交互次數(shù),減少系統(tǒng)開銷,提高系統(tǒng)效率。

3、什么樣的數(shù)據(jù)能使用緩存?

  • 經(jīng)常查詢并且不經(jīng)常改變的數(shù)據(jù)。

13.2Mybatis緩存

  • MyBatis包含一個非常強大的查詢緩存特性,它可以非常方便地定制和配置緩存。緩存可以極大的提升查詢效率。
  • MyBatis系統(tǒng)中默認定義了兩級緩存:一級緩存二級緩存
    • 默認情況下,只有一級緩存開啟。(SqlSession級別的緩存,也稱為本地緩存)
    • 二級緩存需要手動開啟和配置,他是基于namespace級別的緩存。
    • 為了提高擴展性,MyBatis定義了緩存接口Cache。我們可以通過實現(xiàn)Cache接口來自定義二級緩存

13.3一級緩存

一級緩存也叫本地緩存:

  • 與數(shù)據(jù)庫同一次會話期間查詢到的數(shù)據(jù)會放在本地緩存中。
  • 以后如果需要獲取相同的數(shù)據(jù),直接從緩存中拿,沒必須再去查詢數(shù)據(jù)庫;

測試步驟:

第一步:開啟日志 mybatis-config.xml

<settings>
    <!-- 標準日志工廠 -->
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

第二步:測試,在同一個Session中查詢兩次相同記錄

@Test
public void getUserById() {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    User user = mapper.getUserById(3);
    System.out.println(user);
    User user2 = mapper.getUserById(3);
    System.out.println(user2);
    System.out.println(user==user2);

    sqlSession.close();
}

第三步:查看日志輸出

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-LQNmyCsa-1690204448193)(MyBatis.assets/image-20210119123231303.png)]

緩存失效的情況

1.增刪改操作,可能會改變原來的數(shù)據(jù),所以必定會刷新緩存!

2.查詢不同的東西

3.查詢不同的***Mapper.xml

4.手動清理緩存

@Test
public void getUserById() {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    User user = mapper.getUserById(3);
    System.out.println(user);
    sqlSession.clearCache();//手動請理緩存

    sqlSession.close();
}

小結(jié):一級緩存是默認開啟的,只在一次Sqlsession中有效,也就是拿到 連接到關(guān)閉 這個時間段內(nèi)的緩存!?。?/p>

一級緩存相當于map(或者說:一級緩存就是一個map)

13.4二級緩存

  • 二級緩存也叫全局緩存,一級緩存作用域太低了,所以誕生了二級緩存
  • 基于namespace級別的緩存,一個名稱空間,對應(yīng)一個二級緩存;
  • 工作機制
    • 一個會話查詢一條數(shù)據(jù),這個數(shù)據(jù)就會被放在當前會話的一級緩存中;
    • 如果當前會話關(guān)閉了,這個會話對應(yīng)的一級緩存就沒了;但是我們想要的是,會話關(guān)閉了,一級緩存中的數(shù)據(jù)被保存到二級緩存中;
    • 新的會話查詢信息,就可以從二級緩存中獲取內(nèi)容;
    • 不同的mapper查出的數(shù)據(jù)會放在自己對應(yīng)的緩存(map)中;

第一步:開啟全局緩存 - mybatis-config.xml

<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>

第二步:在要使用二級緩存的***Mapper.xml中配置

<!-- 在*Mapper.xml中使用二級緩存 -->
	<!-- 60s 512個 -->
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>

<!--一般最簡單的寫法-->
<cache />

第三步:測試

實體類要記得序列化

小結(jié):

1.只要開啟了二級緩存,在同一個Mapper下就有效

2.所有的數(shù)據(jù)都會先放在一級緩存中

3.只有當會話提交或關(guān)閉的時候,才會提交到二級緩存

13.5緩存原理

先訪問二級緩存,再訪問一級緩存

13.6自定義緩存-ehcache

使用步驟:

第一步:導(dǎo)包

<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.1.0</version>
</dependency>

第二步:配置ehcache.xml文章來源地址http://www.zghlxwxcb.cn/news/detail-605089.html

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="false">
    
    <diskStore path="./tmpdir/Tmp_EhCache"/>

    <defaultCache
            eternal="false"
            maxElementsInMemory="10000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="259200"
            memoryStoreEvictionPolicy="LRU"/>

    <cache
            name="cloud_user"
            eternal="false"
            maxElementsInMemory="5000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="1800"
            memoryStoreEvictionPolicy="LRU"/>
</ehcache>

到了這里,關(guān)于【計算機編程語言】JAVA-MyBatis(Eclipse)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 在我掉入計算機的大坑并深陷其中時,一門名為“C語言”的編程語言讓我沉迷

    在我掉入計算機的大坑并深陷其中時,一門名為“C語言”的編程語言讓我沉迷

    各位CSDN的uu們你們好呀,小雅蘭好久沒有更新博客啦,今天來小試牛刀!??! 上一篇博客小雅蘭是說自己原本是自動化專業(yè)的學生,但是因為一次偶然的機會對計算機的相關(guān)知識產(chǎn)生了濃厚的興趣。那么,小雅蘭的編程之旅就是從C語言開始的。C語言是一門面向過程的、抽象

    2024年02月11日
    瀏覽(23)
  • 如何學習及計算機編程,入門看這一篇就夠了---以c語言為例

    如何學習及計算機編程,入門看這一篇就夠了---以c語言為例

    用計算機爬取信息(爬蟲) 進行數(shù)據(jù)分析,數(shù)據(jù)可視化(大數(shù)據(jù)的某個方面) 處理海量的數(shù)據(jù),如excel(百萬條數(shù)據(jù)) example1. 來看下面一段代碼 大家一定會說 這太簡單了 輸出hello world 學習計算機的入門程序嘛??! 那么請問 這是什么?我們第一次編程應(yīng)該不會知道這是什

    2024年02月08日
    瀏覽(27)
  • 【socket】從計算機網(wǎng)絡(luò)基礎(chǔ)到socket編程——Windows && Linux C語言 + Python實現(xiàn)(TCP+UDP)

    【socket】從計算機網(wǎng)絡(luò)基礎(chǔ)到socket編程——Windows && Linux C語言 + Python實現(xiàn)(TCP+UDP)

    簡單講一下基礎(chǔ)知識,便于后面代碼的理解,建議大概瀏覽一下這一小節(jié)內(nèi)容。這里講的只是冰山一角,建議大家學習計算機網(wǎng)絡(luò)相關(guān)知識,推薦幾本書: 《計算機網(wǎng)絡(luò)》(謝希仁) 《計算機網(wǎng)絡(luò) 自頂向下方法》 《計算機網(wǎng)絡(luò)技術(shù)》 《計算機網(wǎng)絡(luò)基礎(chǔ)及應(yīng)用》 《Linux C從入

    2024年02月08日
    瀏覽(22)
  • 模擬計算器編程教程,中文編程開發(fā)語言工具編程實例

    模擬計算器編程教程,中文編程開發(fā)語言工具編程實例

    模擬計算器編程教程,中文編程開發(fā)語言工具編程實例 中文編程系統(tǒng)化教程,不需英語基礎(chǔ)。學習鏈接 ??????https://edu.csdn.net/course/detail/39036 課程安排:初級1 1 ?初級概述 2 ?熟悉構(gòu)件取值賦值 3 折疊式菜單滑動面板編程 4 自定義圖形窗口自定義標題欄編程 5 多行文本

    2024年02月08日
    瀏覽(25)
  • C語言編程練習(經(jīng)過確定分鐘后,計算現(xiàn)在的時間)

    C語言編程練習(經(jīng)過確定分鐘后,計算現(xiàn)在的時間)

    題目是在某大學教育平臺上聽的一道題,但是沒有答案。自己琢磨的 題目大概意思:現(xiàn)在是11:20,經(jīng)過110分鐘,是幾點幾分? 首先貼上老師的解題思路: ? 解題思路:首先將目前時間 11:20分為兩個部分,如何分開兩部分? 1. 1120/100=11(c語言兩個整數(shù)相除 結(jié)果是整數(shù));1120%100

    2023年04月24日
    瀏覽(22)
  • C語言編程實現(xiàn),計算每天進步一點點一年后的效果

    C語言編程實現(xiàn),計算每天進步一點點一年后的效果

    本來的基數(shù)為1,如果好好學習時能力值相比前一天提高1%,當放任時相比前一天下降1%。1年(365天)后的效果相差多少呢? 原基數(shù)為1,努力一天進步1%,效果1*(1+0.01),努力兩天是在前一天的基礎(chǔ)上進步1%,結(jié)果是1*(1+0.01)*(1+0.01),一年后天天向上的力量是(1+0.01)的365次方。

    2024年02月11日
    瀏覽(25)
  • 【C語言編程基礎(chǔ)】根據(jù)日期求星期(基姆拉爾森計算公式)

    【C語言編程基礎(chǔ)】根據(jù)日期求星期(基姆拉爾森計算公式)

    任意給出一個年月日,求出是星期幾。 輸入: ? ? 年? ?月? ?日 輸出: ? 0~6 星期日用 0 表示,星期一用 1 表示,星期二用 2 表示......星期六用 6 表示。 這里采用基姆拉爾森計算公式: w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7 在公式中d表示日期中的日數(shù),m表示月份數(shù),y表示年數(shù)

    2024年02月06日
    瀏覽(20)
  • 計算機網(wǎng)絡(luò)編程

    計算機網(wǎng)絡(luò)編程

    說起網(wǎng)絡(luò),相信大家都不陌生,把分散在不同地點的計算機設(shè)備,通過傳輸介質(zhì)、通信設(shè)施和網(wǎng)絡(luò)通信協(xié)議,實現(xiàn)資源共享和信息傳輸?shù)南到y(tǒng),我們稱之為: 計算機網(wǎng)絡(luò)系統(tǒng) 。 計算機網(wǎng)絡(luò)的最簡單的定義是:一些 互 相 連 接的、 自治 的計算機的 集合 。 互連:是指計算機

    2024年01月21日
    瀏覽(23)
  • Unity編程之簡易計算機

    Unity編程之簡易計算機

    效果如下 實現(xiàn)計算器的主要思路: 將(點擊按鍵)輸入的式子 存儲 起來并 計算 。 計算式子 輸入:式子的字符串 輸出:計算結(jié)果 這是一個經(jīng)典的隊列數(shù)據(jù)結(jié)構(gòu)應(yīng)用的問題,具體的解法無需贅述(網(wǎng)絡(luò)上有很多資源) 核心思想:用兩個隊列分別維護數(shù)字和運算符,對于不

    2024年02月01日
    瀏覽(29)
  • 樹莓派計算機視覺編程:1~5

    樹莓派計算機視覺編程:1~5

    原文:Raspberry Pi Computer Vision Programming 協(xié)議:CC BY-NC-SA 4.0 譯者:飛龍 本文來自【ApacheCN 計算機視覺 譯文集】,采用譯后編輯(MTPE)流程來盡可能提升效率。 當別人說你沒有底線的時候,你最好真的沒有;當別人說你做過某些事的時候,你也最好真的做過。 OpenCV 是用于計算

    2024年02月13日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包