文章目录
- 前言
- 1 Mybatis学习
- 2.动态Sql
- 3 Mybatis 关联关系
- 4.1 Mybatis缓存实现
- 数据自动回显
- 常用注解
前言
本人发布的一系列资料都是学习备份使用,以及方便日后复习,随着技术的不断提升,每个文章都会持续添加内容,或者是扩展文章,本是秉承着分享的心态,互相学习,互相提升,也希望提出更好的意见,以及学习思路,欢迎留言,欢迎评论,谢谢!!
1 Mybatis学习
1.1 根据ID查询数据
1.1.1 编辑测试方法
/**
* 业务需求: 根据ID查询数据
* 参数: id = 1
*/
@Test
public void test02(){
int id = 1;
User user = userMapper.findUserById(id);
System.out.println(user);
}
1.1.2 编辑接口方法
User findUserById(int id);
1.1.3 编辑映射文件
<!--根据id查询用户数据
语法: 动态获取数据 #{属性名称}
#号效果: 有预编译的效果 防止Sql注入攻击问题
所以以后取值使用#号
-->
<select id="findUserById" resultType="com.jt.pojo.User">
select * from demo_user where id= #{id}
</select>
1.2 完成用户入库操作
1.2.1 编辑测试类
/**
* 实现用户入库操作
*/
@Test
public void saveUser(){
User user = new User();
user.setName("元旦快乐").setAge(2022).setSex("女");
//如果需要返回值 则int接收
int rows = userMapper.saveUser(user);
//如果不需要返回值 则void标识
//userMapper.saveUser(user);
System.out.println("入库成功:影响:"+rows+"行");
}
1.2.2 编辑Mapper接口
int saveUser(User user);
1.2.3 编辑Mapper映射文件
<!--
规则:
1.如果接口方法中,有int类型的返回值,则入库之后,mybatis自动回传数据
2.如果接口中传递的是POJO对象.则通过#{属性}取值
大小问题:
1.windows系统中程序运行不区分大小写.
2.Linux系统 严格区分大小写.
3.程序猿口头禅: 我在我本机上没问题呀!!!!
-->
<insert id="saveUser">
insert into demo_user(id,name,age,sex) values (null,#{name},#{age},#{sex})
</insert>
1.3 作业练习
1.3.1 编辑测试类方法
/**
* 3.修改操作 将name="元旦快乐" 改为age=17,sex=男
*/
@Test
public void updateUser(){
User user = new User();
user.setName("元旦快乐").setAge(17).setSex("男");
userMapper.updateUser(user);
System.out.println("修改操作成功!!!");
}
//4.删除操作 将name="春节快乐"的数据删除
@Test
public void deleteUser(){
String name = "春节快乐";
userMapper.deleteUser(name);
System.out.println("删除成功!!!");
}
1.3.2 编辑Mapper接口方法
void updateUser(User user);
void deleteUser(String name);
1.3.3 编辑Mapper映射文件
<update id="updateUser">
update demo_user set age=#{age}, sex=#{sex}
where name=#{name}
</update>
<delete id="deleteUser">
delete from demo_user where name=#{name}
</delete>
1.4 Map集合封装数据
1.4.1 编辑测试方法
/**
* 业务: 查询age> 18岁 and age <100的用户.
* 知识点:
* 1.mybatis的参数可以是基本类型或者字符串.
* 2.如果遇到多个参数,应该使用对象(POJO)进行封装.
* 3.如果通过pojo封装不方便.则使用功能最为强大的Map进行封装
* 4.Mybatis的接口方法中只允许传递单值
*/
@Test
public void testFindUserByAge(){
Map<String,Object> map = new HashMap<>();
map.put("minAge",18);
map.put("maxAge",100);
List<User> userList = userMapper.findUserByAge(map);
System.out.println(userList);
}
1.4.2 编辑Mapper接口方法
List<User> findUserByAge(Map<String, Object> map);
1.4.3 编辑Mapper 映射文件
<!--
知识点1: 通过 #{参数名称/对象中的属性/Map中的key}
知识点2: xml文件中有些字符需要转义
> > < <
& &
-->
<select id="findUserByAge" resultType="com.jt.pojo.User">
select * from demo_user where age>#{minAge} and age < #{maxAge}
</select>
1.5 @Param注解
1.5.1 需求说明
说明: 根据下列的代码,不能非常直观去了解业务. 能否优化该操作.
List<User> findUserByAge(Map<String, Object> map);
1.5.2 编辑测试类
@Test
public void testFindUserByAge2(){
int minAge = 18;
int maxAge = 100;
List<User> userList = userMapper.findUserByAge2(minAge,maxAge);
System.out.println(userList);
}
1.5.3 编辑Mapper接口
//如果参数是多值,则需要封装为单值Map
//@Param将参数封装为Map集合
List<User> findUserByAge2(@Param("minAge") int minAge,
@Param("maxAge") int maxAge);
1.5.4 编辑Mapper映射文件
<select id="findUserByAge2" resultType="com.jt.pojo.User">
select * from demo_user where age>#{minAge} and age < #{maxAge}
</select>
1.6 Mybatis 模糊查询写法
1.6.1 编辑测试方法
/**
* 需求: 查询name中 包含"君"字的数据
* Sql: where name like "%君%"
*/
@Test
public void findByLike(){
String key = "君";
List<User> userList = userMapper.findByLike(key);
System.out.println(userList);
}
1.6.2 编辑接口方法
List<User> findByLike(String key);
1.6.3 编辑映射文件
<!--
知识点1: 通过 #{参数名称/对象中的属性/Map中的key}
知识点2: xml文件中有些字符需要转义
> > < <
& &
-->
<select id="findUserByAge" resultType="com.jt.pojo.User">
select * from demo_user where age>#{minAge} and age < #{maxAge}
</select>
1.7 Mybatis属性优化
1.7.1 别名包用法
其中resultType中的属性com.jt.pojo.User 定义别名.简化其操作.
<select id="findByLike" resultType="com.jt.pojo.User">
select * from demo_user where name like "%"#{key}"%"
</select>
- 标识注解
- 使用别名
- 定义别名包 定义别名包之后,以后的数据只需要写类名即可,使用时会自动的拼接前缀
#3.配置Mybatis
mybatis:
#定义别名包
type-aliases-package: com.jt.pojo
1.7.2 Sql标签用法
<!--Sql标签作用: 抽取公共的部分,可以被其它的Sql引用-->
<sql id="findColumn">
select id,name,age,sex from demo_user
</sql>
<select id="findByLike" resultType="User">
<include refid="findColumn"/> where name like "%"#{key}"%"
</select>
1.8 Mybatis中集合参数用法 array/list
1.8.1 Array类型的参数说明
说明: 一般业务逻辑可能会用到array进行数据的封装. 问题: xml映射文件中如何解析数组
格式如下: Integer[] ids = {1,3,4,5,6};
1.8.2 测试代码
/**
* 业务说明: 集合参数的用法
* 需求: 查询id=1,3,4,5,6的数据
* Sql: where id in (1,3,4,5,6)
*/
@Test
public void findIn(){
Integer[] ids = {1,3,4,5,6};
List<User> list = userMapper.findIn(ids);
System.out.println(list);
}
1.8.3 编辑Mapper接口
List<User> findIn(Integer[] ids);
1.8.4 编辑Mapper 映射文件
<!--
需求: Integer[] ids 中的数据一个一个取出来.拼接Sql
知识点: mybatis中如何遍历数组
foreach标签用法:
1. collection:需要遍历的集合的类型
1.1 数组类型 关键字:array
1.2 list类型 关键字:list
1.3 map类型 关键字:Map中的key
2. open/close 循环开始和结束标签,一般自己写
3. item 遍历数据的变量名称
4. separator 参数之间的分隔符
-->
<select id="findIn" resultType="User">
select * from demo_user where id in (
<foreach collection="array" item="id" separator=",">
#{id}
</foreach>
)
</select>
1.9 Mybatis中集合参数用法Map封装
1.9.1 测试代码
@Test
public void findInMap(){
//准备2个集合,测试map集合封装
Integer[] ids1 = {1,3,4,5,6};
Integer[] ids2 = {1,3,4,5,6};
List<User> list = userMapper.findInMap(ids1,ids2);
System.out.println(list);
}
1.9.2 编辑Mapper接口
List<User> findInMap(@Param("ids1") Integer[] ids1,
@Param("ids2") Integer[] ids2);
1.9.3 编辑Mapper映射文件
<!--参数传递是Map集合,所以关键字使用key-ids1 -->
<select id="findInMap" resultType="User">
select * from demo_user where id in (
<foreach collection="ids1" item="id" separator=",">
#{id}
</foreach>
)
</select>
2.动态Sql
2.1 动态Sql-where条件
2.1.1 编辑测试类
package com.jt;
import com.jt.mapper.UserMapper2;
import com.jt.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
public class TestMybatis2 {
@Autowired
private UserMapper2 userMapper;
/**
* 需求: 根据用户不为null的属性充当where条件
*/
@Test
public void testSqlWhere(){
User user = new User();
user.setAge(3000).setSex("男");
List<User> userList = userMapper.findSqlWhere(user);
System.out.println(userList);
}
}
2.1.2 编辑Mapper接口
@Mapper //将接口的代理对象交给Spring容器管理
public interface UserMapper2 {
List<User> findSqlWhere(User user);
}
2.1.3 编辑Mapper 映射文件
<?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.jt.mapper.UserMapper2">
<!--
问题说明: 前端数据传递时可能会有null数据.
如果数据为null则不能充当where条件
解决方案: 动态Sql实现
语法:
<if test="判断条件"> id = #{id}</if>
true: 则拼接标签内容
false: 则不拼接标签内容
<where>标签: 去除where后边多余的and/or
-->
<select id="findSqlWhere" resultType="User">
select * from demo_user
<where>
<if test="id != null"> id = #{id}</if>
<if test="name !=null">and name = #{name}</if>
<if test="age !=null"> and age = #{age}</if>
<if test="sex !=null"> and sex = #{sex}</if>
</where>
</select>
</mapper>
2.2 动态Sql-Set标签
2.2.1 编辑测试类
/**
* 需求: 修改id=1 的数据 name="北极熊",age=4000 sex="男"
*/
@Test
public void testUpdateUser(){
User user = new User();
user.setId(1).setAge(5000);
userMapper.updateUser(user);
System.out.println("更新成功!!!");
}
2.2.2 编辑Mapper接口
void updateUser(User user);
2.2.3 编辑Mapper.xml映射文件
<!--根据对象中不为null的属性 当做set条件
语法: set标签 去除多余1个,号
-->
<update id="updateUser">
update demo_user
<set>
<if test="name !=null">name=#{name},</if>
<if test="age !=null"> age=#{age},</if>
<if test="sex !=null"> sex=#{sex},</if>
</set>
where id = #{id}
</update>
2.3 动态Sql-choose、when、otherwise
2.3.1 编辑测试类
/**
* 如果name有值,则根据name查询.
* 如果name没有值,则根据age查询.
* 如果name/age都没有值,则根据sex查询
*/
@Test
public void testChoose(){
User user = new User();
user.setSex("男");
List<User> userList = userMapper.findChoose(user);
System.out.println(userList);
}
2.3.2 编辑接口
List<User> findChoose(User user);
2.3.3 编辑xml映射文件
<!--
* 如果name有值,则根据name查询.
* 如果name没有值,则根据age查询.
* 如果name/age都没有值,则根据sex查询
语法类似: if->else-if->else
-->
<select id="findChoose" resultType="User">
select * from demo_user
<where>
<choose>
<when test="name !=null"> name=#{name}</when>
<when test="age !=null"> age = #{age}</when>
<!--必须保证sex必须有值 -->
<otherwise>sex=#{sex}</otherwise>
</choose>
</where>
</select>
2.4 ResultMap语法
2.4.1 封装数据表-POJO对象
- 创建dog表
- 编辑POJO对象
package com.jt.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class Dog implements Serializable {
private Integer dogId;
private String dogName;
private Integer age;
}
2.4.2 准备Mapper接口/映射文件
2.4.3 需求说明
1.经过demo_user测试,发现如果字段名称与对象属性的名称一致,Mybatis可以实现自动化的映射
2.如果遇到字段名称与属性的名称不一致的现象,则mybatis如何映射!!!
2.4.4 案例测试
package com.jt;
import com.jt.mapper.DogMapper;
import com.jt.pojo.Dog;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
public class TestMybatis3 {
@Autowired
private DogMapper dogMapper;
@Test
public void testFindAll(){
List<Dog> dogList = dogMapper.findAll();
System.out.println(dogList);
}
}
2.4.5 编辑Mapper接口
@Mapper
public interface DogMapper {
List<Dog> findAll();
}
2.4.6 编辑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.jt.mapper.DogMapper">
<!--
规则:
1.如果数据库中的表字段名称与POJO属性的名称不一致
则mybatis无法自动完成映射.
2.Mybatis提供了一个属性resultMap(使用最多的).
支持用户手动映射.
-->
<select id="findAll" resultMap="dogRM">
select * from dog
</select>
<!--
属性说明: id="唯一标识,不能重复"
type="映射的POJO对象的类型"
简化说明: 如果字段名称与属性名称一致则可以省略
autoMapping="true" 开启自动映射
-->
<resultMap id="dogRM" type="Dog" autoMapping="true">
<!--1.标识主键-->
<id column="dog_id" property="dogId"/>
<!--2.映射结果集-->
<result column="dog_name" property="dogName"/>
<!--<result column="age" property="age"/>-->
</resultMap>
</mapper>
2.5 驼峰映射规则
2.5.1 业务说明
Mybatis中的结果集的字段名称如果与属性的名称满足驼峰映射的规则. 如果开启驼峰映射.,则可以实现自动化的映射.
字段: dog_id, dog_name
属性: dogId, dogName 满足驼峰规则.
配置信息:
#3.配置Mybatis
mybatis:
#定义别名包
type-aliases-package: com.jt.pojo
#将所有的映射文件全部加载
mapper-locations: classpath:/mappers/*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
3 Mybatis 关联关系
3.1 常见关联关系
思路:看问题从一头出发看向另一头
- 一对一 一个员工对应一个部门
- 一对多 一个部门下对应多个员工
- 多对一 本质是一对一
- 多对多 老师和学生 双向的一对多
一个老师对应多个学生.
一个学生对应多个老师.
3.2 一对一映射
3.2.1 创建表
表名 dept
字段: dept_id, int 主键 自增
dept_name, varchar(40)
表名 emp
字段: emp_id, int 主键 自增
emp_name, varchar(40)
dept_id int
造表数据
3.2.2 测试准备
根据表 创建POJO/Mapper接口/xml映射文件
3.2.3 关于一对一业务说明
表关系: 一个员工对应一个部门.
需求: 将部门信息与员工信息绑定.
如图所示:
3.2.4 关联查询方式
- 笛卡尔积的形式
- 连接查询 左连接,右连接,内连接
- 子查询
3.2.5 编辑测试类
package com.jt;
import com.jt.mapper.DeptMapper;
import com.jt.mapper.DogMapper;
import com.jt.mapper.EmpMapper;
import com.jt.pojo.Dog;
import com.jt.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
public class TestMybatis4 {
@Autowired
private DeptMapper deptMapper;
@Autowired
private EmpMapper empMapper;
//完成一对一测试
@Test
public void testEmp(){
List<Emp> empList = empMapper.findAll();
System.out.println(empList);
}
}
3.2.6 编辑EmpMapper接口
@Mapper
public interface EmpMapper {
List<Emp> findAll();
}
3.2.7 编辑EmpMapper.xml映射文件
<!--
知识点:
1.如果单表查询首选resultType
2.如果进行关联查询 首选resultMap
3.如果sql的结果集出现了重名字段,则mybatis映射必然报错.
-->
<select id="findAll" resultMap="empRM">
SELECT emp.*,dept.dept_name FROM emp,dept
WHERE emp.dept_id = dept.dept_id
</select>
<!-- 完成一对一封装
目的: 一个员工中封装一个部门对象
语法:
1.association 表示一对一封装
2.property 当前主对象的属性名称
3.javaType 指定属性的类型
-->
<resultMap id="empRM" type="Emp" autoMapping="true">
<!-- 标识主键信息 -->
<id column="emp_id" property="empId"/>
<!--<result column="emp_name" property="empName"/>-->
<!--完成一对一映射-->
<association property="dept" javaType="Dept" autoMapping="true">
<id column="dept_id" property="deptId"/>
</association>
</resultMap>
3.2.8 连接查询
SELECT emp.*,dept.dept_name FROM
emp
LEFT JOIN
dept
ON emp.dept_id = dept.dept_id
3.3 一对多查询
3.3.1 业务需求
需求: 一个部门对应多个员工
表现形式:
3.3.2 编辑测试代码
@Test
public void testDept(){
List<Dept> deptList = deptMapper.findAll();
System.out.println(deptList);
}
3.3.3 编辑Mapper接口
@Mapper
public interface DeptMapper {
List<Dept> findAll();
}
3.3.4 编辑DeptMapper.xml文件
<mapper namespace="com.jt.mapper.DeptMapper">
<select id="findAll" resultMap="deptRM">
SELECT dept.*,emp.emp_id,emp.emp_name
FROM dept,emp
WHERE dept.dept_id=emp.dept_id
</select>
<!--
一对多封装:
1.collection: 封装集合类型
2.ofType: 指定集合内部(泛型)的对象类型
-->
<resultMap id="deptRM" type="Dept" autoMapping="true">
<!--主键必须标识-->
<id column="dept_id" property="deptId"/>
<!--一对多封装-->
<collection property="emps" ofType="Emp" autoMapping="true">
<id column="emp_id" property="empId"/>
</collection>
</resultMap>
</mapper>
3.4 Mybatis的注解形式
//鸡肋: 1.大公司一般不用, 2.只适用于单表操作.多表操作必须写映射文件
// 注解和映射文件二选一
@Select("select * from dept")
List<Dept> selectAll();
@Insert("insert into dept values (null,#{deptName})")
void saveDept(Dept dept);
3.5 @MapperScan
4.1 Mybatis缓存实现
4.1.1 缓存机制
如果有大量相同的请求查询数据库,则数据库需要执行多次重复的sql,那么并发压力高,查询效率低. 如果引入缓存机制,则可以极大的提升用户的查询的效率
4.2 Mybatis-一级缓存
4.2.1 一级缓存说明
说明: 在同一个SqlSession内,实现数据库的共享.
解释: 用户使用同一个SqlSession时,进行多次数据库的查询,由于一级缓存的存在.所以数据库只查询一次.
开关状态: 一级缓存Mybatis默认开启.无需配置.
4.2.2 一级缓存测试说明
package com.jt;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@SpringBootTest
public class TestMybatisCache5 {
@Autowired
private UserMapper userMapper; //底层实现中包含了SqlSession
/**
* 测试:mybatis的一级缓存, SqlSession级别
* SpringBoot测试说明:
* SpringBoot中用户在使用userMapper接口时,用户每调用一次.
* SpringBoot就会新创建一个SqlSession.
* 如何解决多个SqlSession的问题?
* 解决方案:
* 利用@Transactional的事务的注解,将多个SqlSession控制为一个.
*/
@Test
@Transactional //事务的注解
public void testCache1(){
List<User> list1 = userMapper.findAll(); //sqlSession1
List<User> list2 = userMapper.findAll(); //sqlSession2
List<User> list3 = userMapper.findAll(); //SqlSession3
}
}
4.3 Mybatis-二级缓存
4.3.1 二级缓存说明
说明: 由同一个SqlSessionFactory(类比:链接池)生产的SqlSession(类比:数据库链接),可以实现数据共享
解释说明: 由同一个SqlSessionFactory生产多个SqlSession(多线程).可以在多线程的条件下,可以实现数据共享.
默认开关: 二级缓存默认条件下是开启的. 但是需要指定哪里使用二级缓存
4.3.2 标识二级缓存
4.3.3 Mybatis二级缓存测试
/**
* 测试二级缓存
* 总结: 多线程条件下共享数据,要求数据必须序列化.
*/
@Test
public void testCache2(){
//第一次查询数据库获取的list1的集合对象,该对象需要保存到缓存中,为了后续线程使用,该对象必须序列化
List<User> list1 = userMapper.findAll(); //sqlSession1 线程A
//第二个线程查询数据.有二级缓存的存在.所以从缓存中获取数据.所以直接反序列化该对象获取结果.
List<User> list2 = userMapper.findAll(); //sqlSession2 线程B
//第三个线程查询数据,所以直接反序列化该对象获取结果.
List<User> list3 = userMapper.findAll(); //SqlSession3 线程C
}
4.3.4 关于对象序列化问题
说明: 在多线程条件下.数据如果需要共享,必须序列化
4.4 关于Mybatis一二级缓存的说明
- 默认条件下一二级缓存是开启的. 但是二级缓存需要标记 cache
- 一级缓存在同一个SqlSession中共享数据(单线程)
- 二级缓存在同一个SqlSessionFactory生产的多个SqlSession内共享数据(多线程). 对象必须序列化
- 在真实的生产环境中(集群:多个服务器)使用二级缓存可能存在问题,使用Redis高级缓存服务器代替.
4.5关于缓存的作用域问题
一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。 一级缓存的作用域是同一个SqlSession,在第一个sqlSession执行相同的sql语句后结果放在内存中,第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。
本地缓存不能被关闭,可以调用clearCache()来清空本地缓存,或者改变缓存的作用域
二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区域,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。
Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。
如果缓存中有数据就不用从数据库中获取,大大提高系统性能。
4.6 Mybatis底层实现原理(了解)
重点知识: 1.了解SqlSessionFactory/SqlSession如何创建的!!!
package com.jt;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
class MybatisApplicationTests {
/*
* Mysql入门实现步骤:
* 1.编辑mybatis-config.xml核心配置文件
* 1.1执行数据源配置
* 2.编辑POJO实体对象.要求与数据库表中的字段一一对应
* 3.编辑Mapper接口. 添加接口方法
* 4.编辑接口的实现类(配置文件方式) 要求namespace id resultType
* 5.mybatis加载指定的mapper映射文件
* 6.创建SqlSessionFactory工厂对象
* 7.获取SqlSession,开启数据库链接
* 8.获取接口对象(代理对象)
* 9.调用接口方法,获取返回值结果
* 10.关闭sqlSession链接.
* */
@Test
public void testDemo1() throws IOException {
/*创建SqlSessionFactory 类比:链接池 */
String resource = "mybatis/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//设计模式1:建造者模式-Builder-.build()
//设计模式2:工厂模式-Factory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
/*从SqlSessionFactory中获取sqlSession*/
SqlSession sqlSession = sqlSessionFactory.openSession();
/*SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
SqlSession sqlSession3 = sqlSessionFactory.openSession();*/
/*获取mapper接口,执行接口方法*/
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
/*Mybatis为接口创建了一个代理对象
知识点: 框架中通过接口调用方法时,如果没有实现类,则为其创建代理对象
代理对象~实现类
*/
System.out.println(userMapper.getClass());
List<User> userList = userMapper.findAll();
System.out.println(userList);
/*执行之后关闭SqlSession*/
sqlSession.close();
}
}
数据自动回显
useGeneratedKeys="true" keyColumn="字段" keyProperty="属性名"
常用注解
- @Configuration 标识当前类是配置类
- @ComponentScan 包扫描注解 扫描注解 需要在配置类上面添加
- @Bean 标识该方法的返回值交给Spring容器管理 通常写在配置类中
方法名类型首字母小写,返回值:需要被管理的对象" - @Scope 控制多例和单例 通常与@bean一起使用
@Scope(“singleton”) //标识单例对象
@Scope(“prototype”) //标识多例对象 - @Lazy 懒加载 通常与@bean一起使用 来设置单例下的饿汉式与懒汉式
注意:多例模式是懒加载,单例模式是饿汉式 - @PostConstruct 初始化方法 通常写在被Spring管理的对象里面
- @PreDestroy 销毁方法 通常写在被Spring管理的对象里面
- @Component 将当前类未来的对象交给容器管理 一般情况下用了此标签,就不需要在配置类里面配置@bean了
- @Autowired 按照类型进行注入
- @Qualifier 按照名称进行注入 通常跟@Autowired注解一起使用
- @Repository 标识持久层注解
- @Service 标识Service层
- @Controller 标识Controller层
- @Value 为属性赋值 @Value("${key}") 为对象中的属性赋值
- @PropertySource 加载指定路径的配置文件properties 标注在有@Value标签的类上
@PropertySource(value = “classpath:/addUser.properties”,encoding = “UTF-8”)
spring根据指定的路径,加载properties配置文件 数据添加到spring容器中 - @Aspect 标识当前类是一个切面类 注意切面类需要被 Spring管理
- @Pointcut 用于定义切入点表达式 表达式写法4种 如果方法上有此标签 我们把这个方法视为目标方法,也就是被代理的对象需要执行的业务逻辑方法
- @EnableAspectJAutoProxy 让AOP的注解有效果 添加到配置类上
- @Before AOP-前置通知
- @AfterReturning AOP-后置通知
- @AfterThrowing AOP-异常通知
- @After AOP-最终通知
- @Around AOP-环绕通知
- @Order(1) //可以利用order关键字 实现AOP的排序 数字越小越先执行. 意为:当一个方法需要执行多个AOP时,我们可以设置切面的执行顺序,此标签通常加在切面类上 如果遇到排序的数字一样,则还是按照文件夹的上下顺序执行
- @ResponseBody 将返回的数据转化为JSON串, 如果是字符串本身 原数据返回
- @RequestMapping("/hello") 实现浏览器的请求路径与方法的映射
- @PathVariable restFul结构,接收参数的注解.
- @GetMapping("") 只能接收GET请求类型
- @DeleteMapping("") 只能接收DELETE请求类型
- @PostMapping("") 只能接收POST请求类型
- @PutMapping("") 只能接收PUT请求类型
- @RestController 表示Controller类,同时要求返回值为JSON
- @CrossOrigin 允许跨域访问
- @RequestBody 参数接收时,将JSON串转化为java对象 json中的key与对象的属性一致.
- @Data lombok动态生成get/set/toString/equals/hashcode等方法
- @Accessors 控制是否开启链式加载结构
- @NoArgsConstructor 生成无参构造方法
- @AllArgsConstructor 生成全参构造方法
- @Mapper mybatis将当前的接口交给Spring容器管理. Map<类名小写,JDK动态代理对象>
- @SpringBootTest 该注解的作用在进行代码测试时启动spring容器,之后动态的获取对象 注意包路径 主启动类的同包及子包中.
- @Param Mybatis中将参数封装为Map集合.
@Param(“maxAge”) int maxAge - @Alias Mybatis中定义对象的别名 @Alias(“User”)
- @MapperScan Mybatis中扫描指定包路径的接口 为其创建代理对象.
- @Insert Mybatis 新增操作注解
- @Update Mybatis 修改操作注解
- @Delete Mybatis 删除操作注解
- @Select Mybatis 查询操作注解