Mybatis复习(包括基本应用、Mapper动态代理、多查询条件、动态SQL、关联关系查询、缓存)

1.基本应用

1.1 导入相关jar包或者Maven引入

注意一下MySQL的版本需要和jar包对应。
mysql-connector-java-8.0.17.jar与MySQL8.0版本以上对应,5.7的与5.7 的对应
同时8.0.17需要注意driver和serverTimezone

 jdbc.driver=com.mysql.cj.jdbc.Driver 
 ?serverTimezone=UTC

在这里插入图片描述

1.2 定义实体类

@Data
public class Student {
    
    
	private Integer id;
	private String name;
	private int age;
	private double score;
	private String time;
}

1.3数据库

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(5) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `age` int(3) DEFAULT NULL,
  `score` double DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

1.4 定义接口和映射文件

public interface IStudentDao {
    
    
	void insertStu(Student student);
}
<?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="test">
	<!-- parameterType属性可以省略 -->
	<insert id="insertStudent" parameterType="Student">
		insert into student(name,age,score,time) values(#{name}, #{age}, #{score},#{time,jdbcType=DATE})
	</insert>
</mapper>

1.5定义配置文件

<?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>
	<!-- 注册DB连接四要素属性文件 -->
	<properties resource="jdbc_mysql.properties"/>
	<!-- 定义类型别名 -->
	<typeAliases>
		<!-- <typeAlias type="com.rose.beans.Student" alias="Student"/> -->
		<!-- 将指定包中所有类的简单类名当作其别名 -->
		<package name="com.rose.beans"/>
	</typeAliases>
	
	<!-- 配置运行环境 -->
	<environments default="testEM">
		<environment id="testEM">
			<transactionManager type="JDBC"/>
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}"/>
				<property name="url" value="${jdbc.url}"/>
				<property name="username" value="${jdbc.user}"/>
				<property name="password" value="${jdbc.password}"/>
			</dataSource>
		</environment>
	</environments>
	
	<!-- 注册映射文件 -->
	<mappers>
		<mapper resource="com/rose/dao/mapper.xml"/>
	</mappers>
	
</configuration>

1.6 定义Dao的实现类与测试

public class StudentDaoImpl implements IStudentDao {
    
    

	private SqlSession sqlSession;

	@Override
	public void insertStu(Student student) {
    
    
		try {
    
    
			sqlSession = MyBatisUtils.getSqlSession();
			sqlSession.insert("insertStudent", student);
			sqlSession.commit();
		} finally {
    
    
			if(sqlSession != null) {
    
    
				sqlSession.close();
			}
		}
	}
}
public class MyTest {
    
    
	private IStudentDao dao;

	@Before
	public void before() {
    
    
		dao = new StudentDaoImpl();
	}
	
	@Test
	public void testInsert() {
    
    
		Student student = new Student("rose3", 23, 93.5);
		dao.insertStu(student);
	}
	
}

2.$与#的区别

#为占位符,而$为字符串拼接符
字符串拼接是将参数值直接以硬编码的方式直接拼接到了SQL语句中。字符串拼接就会引发两个问题:SQL注入问题与没有使用预编译所导致的执行效率低下的问题

3.Mapper动态代理

前面的例子中Dao接口实现类时候发现了一个问题:Dao的实现类并没有做什么实质性的工作,仅仅通过SqlSession的相关API定位到映射文件mapper中相应id的SQL语句,真正对DB进行的操作是通过Mapper的SQL完成的。
所以 Mybatis可以抛弃Dao的实现类,直接使用动态代理,无需在编写Dao的实现类。
简单的来说,通过接口名定位到映射文件

<mapper namespace="com.rose.dao.IStudentDao">
</mapper>
	

4.多查询条件

4.1将多个参数封装成Map

List<Student> selectStudentByMap(Map<String,object> map);

4.2 多个参数逐个接受

List<Student> selectStudentByConditions(String name,int age);

5.动态sql

动态sql用来解决查询条难吗不确定的情况;在程序运行的期间,根据用户提交的查询条件进行查询。提交的查询条件不同,执行的sql语句不同。如果将每种情况分别写sql,工作量大。可以使用动态sql。
常见的动态sql标签有

public interface IStudentDao {
    
    
	List<Student> selectStudentsByIf(Student student);
	List<Student> selectStudentsByWhere(Student student);
	List<Student> selectStudentsByChoose(Student student);
	List<Student> selectStudentsByForeach(int[] ids);
	List<Student> selectStudentsByForeach2(List<Integer> ids);
	List<Student> selectStudentsByForeach3(List<Student> ids);
	List<Student> selectStudentsBySqlFragment(List<Student> ids);
}
<mapper namespace="com.rose.dao.IStudentDao">
	
	<select id="selectStudentsByIf" resultType="Student">
		select id,name,age,score 
		from student 
		where 1 = 1
		<if test="name != null and name != ''">
			and name like '%' #{name} '%'
		</if>
		<if test="age > 0">
			and age > #{age}
		</if>
	</select>
	
	<select id="selectStudentsByWhere" resultType="Student">
		select id,name,age,score 
		from student 
		<where>
			<if test="name != null and name != ''">
				and name like '%' #{name} '%'
			</if>
			<if test="age > 0">
				and age > #{age}
			</if>
		</where>
	</select>
	
	<select id="selectStudentsByChoose" resultType="Student">
		select id,name,age,score 
		from student 
		<where>
			<choose>
				<when test="name != null and name !=''">
					and name like '%' #{name} '%'
				</when>
				<when test="age > 0">
					and age > #{age}
				</when>
				<otherwise>
					1 = 2
				</otherwise>
			</choose>
		</where>
	</select>
	
	<select id="selectStudentsByForeach" resultType="Student">
		<!-- select id,name,age,score from student where id in (1,3,5) -->
		select id,name,age,score 
		from student 
		<if test="array.length > 0">
			where id in 
			<foreach collection="array" item="myid" open="(" close=")" separator=",">
				#{myid}
			</foreach>
		</if>
	</select>
	
	<select id="selectStudentsByForeach2" resultType="Student">
		<!-- select id,name,age,score from student where id in (1,3,5) -->
		select id,name,age,score 
		from student 
		<if test="list.size > 0">
			where id in 
			<foreach collection="list" item="myid" open="(" close=")" separator=",">
				#{myid}
			</foreach>
		</if>
	</select>
	
	<select id="selectStudentsByForeach3" resultType="Student">
		<!-- select id,name,age,score from student where id in (1,3,5) -->
		select id,name,age,score 
		from student 
		<if test="list.size > 0">
			where id in 
			<foreach collection="list" item="stu" open="(" close=")" separator=",">
				#{stu.id}
			</foreach>
		</if>
	</select>
	
	<select id="selectStudentsBySqlFragment" resultType="Student">
		<!-- select id,name,age,score from student where id in (1,3,5) -->
		select <include refid="selectColumns"/>
		from student 
		<if test="list.size > 0">
			where id in 
			<foreach collection="list" item="stu" open="(" close=")" separator=",">
				#{stu.id}
			</foreach>
		</if>
	</select>
	
	<sql id="selectColumns">
		id,name,age,score 
	</sql>
	
</mapper>

6.关联关系查询

6.1 一对多

一对多关联查询值得是查询一方的时候,同时将其所关联的多方对象也都查询出来。下面以Country与部长Minister一对多演示。

public class Country {
    
    
	private Integer cid;
	private String cname;
	// 关联属性
	private Set<Minister> ministers;
}
public class Minister {
    
    
	private Integer mid;
	private String mname;
}

使用resultMap collection,将多方放入 collection当中

<mapper namespace="com.rose.dao.ICountryDao">
	
	<resultMap type="Country" id="countryMapper">
		<id column="cid" property="cid"/>
		<result column="cname" property="cname"/>
		<collection property="ministers" ofType="Minister">
			<id column="mid" property="mid"/>
			<result column="mname" property="mname"/>
		</collection>
	</resultMap>
	
	<select id="selectCountryById" resultMap="countryMapper">
		select cid,cname,mid,mname
		from country,minister
		where countryId=cid and cid=#{xxx} 
	</select>
	
</mapper>

6.2多对一

public class Minister {
    
    
	private Integer mid;
	private String mname;
	// 关联属性
	private Country country;
}

使用 association

<mapper namespace="com.rose.dao.IMinisterDao">
	
	<resultMap type="Minister" id="ministerMapper">
		<id column="mid" property="mid"/>
		<result column="mname" property="mname"/>
		<association property="country" javaType="Country">
			<id column="cid" property="cid"/>
			<result column="cname" property="cname"/>
		</association>
	</resultMap>
	
	<select id="selectMinisterById" resultMap="ministerMapper">
		select mid,mname,cid,cname
		from minister, country
		where countryId=cid and mid=#{xxx}
	</select>
	
</mapper>

7.缓存

7.1一级缓存

Mybatis一级查询缓存本质上基于HashMap的本地缓存,作用域是SqlSession。在同一个SqlSession中执行两次相同的sql查询语句,第一次执行完之后,会将查询结果写入到缓存中,第二次直从缓存中获取数据。不到数据库中查询。

当一个sqlsession结束后,该sqlSession中的一级查询也不存在了。mybatis默认一级缓存开启,且不能关闭。

増、删、改操作,无论是否提交sqlSession.commit(),均会清空一级查询缓存,使查询再次从DB中select。

7.2二级缓存

(1)要求涉及的实体类要实现java.io.Serializable接口
(2)mapper映射中添加 标签

<cache/>  

猜你喜欢

转载自blog.csdn.net/qq_21561833/article/details/124767454