以下内容如有侵权请联系删除
第一天–基础
第零章 对原生JDBC程序中问题总结
0.1 JDBC编程步骤
加载数据库驱动
创建并获取数据库连接
创建jdbc statement对象
设置sql语句
设置sql语句中的参数(使用preparedStatement)
通过statement执行sql并获取结果
对sql执行结果进行解析处理
释放资源(ResultSet、PreparedStatement、Connection)
0.2 JDBC问题总结
(1)数据库连接,使用时就创建,不使用立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响数据库性能。
设想:使用数据库连接池管理数据库连接。在mybatis中通过数据库连接池管理数据库连接,这个池中可以放很多数据库,当你需要连接哪个数据库时,支持从池中取出来用就行,例如你有两个数据库,一个Oracle的,一个是MySQL的,当使用JDBC时,你首先需要加载两个数据库的驱动,建立连接,最后释放,当再次需要连接时,你还必须加载驱动,建立连接,释放,这样肯定会增加服务器的负担,就像你的手机插头,一直插拔肯定会出现问题,所以在mybatis中提出了数据库连接池的概念,将数据库放入到一个池子中,这个池子负责管理数据库连接和释放,用户当需要某个数据库时,从池中取出来直接用就好,不需要像JDBC那样先加载驱动,建立连接,最后释放。
(2)将sql语句硬编写到java代码中,如果sql语句修改,需要重新编译java代码,不利于系统维护。
设想:将sql语句配置在xml配置文件中,即使sql变化,不需要对java代码进行重新编译。
(3)向PreparedStatement中设置参数,对占位符和设置参数值,硬编码在java代码中,不利于系统维护。
设想:将sql语句及占位符和参数全部配置在xml中。
(4)从ResultSet中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,不利于系统维护。
设想:将查询的结果集,自动映射成java对象。
第一章 框架简介
第二章 Mybatis简介
2.1 ORM概述
2.2 Mybatis介绍
第三章 Mybatis快速入门
3.1 步骤分析
3.2 代码实现
(1)准备数据库环境
(2)创建java项目,导入jar(mysql驱动、mybatis、log4j日志)log4j日志作用:在idea控制台输入SQL语句、传入的参数等日志信息
(3)创建User类
package cn.itcast.domain;
import java.util.Date;
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
public User() {
}
public User(Integer id, String username, Date birthday, String sex, String address) {
this.id = id;
this.username = username;
this.birthday = birthday;
this.sex = sex;
this.address = address;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
(4)编写映射文件UserMapper.xml作用:编写SQL
(5)编写mybatis核心文件SqlMapConfig.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="mysql">
<!--配置mysql环境-->
<environment id="mysql">
<!--事务管理器配置:JDBC类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据库连接池 POOLED:mybatis内置连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_db"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--加载映射文件-->
<mappers>
<mapper resource="cn/itcast/dao/UserMapper.xml"></mapper>
</mappers>
</configuration>
(6)编写测试代码测试功能
package cn.itcast.test;
import cn.itcast.domain.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.Test;
import java.io.InputStream;
import java.util.List;
public class MybatisDemoTest {
@Test
public void testFindAll() throws Exception{
//1、加载mybatis核心配置文件 SqlMapConfig.xml
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2、构建SqlSessionFactory工厂对象
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
//3、通过工厂创建SqlSession对象 (相当于:connection)
SqlSession sqlSession = sessionFactory.openSession();
//4、执行SQL语句
List<User> list = sqlSession.selectList("UserMapper.findAll");
for (User user : list) {
System.out.println(user);
}
//5、释放资源
sqlSession.close();
}
}
第四章 Mybatis映射文件概述
第五章 Mybatis增删改查
5.1 新增
(1)编写UserMapper.xml
(2)编写单元测试代码
(3)知识总结
5.2 修改
5.3 删除
第六章 Mybatis核心文件概述
6.1 核心配置文件层级关系
6.2 常用配置标签解析
environments标签
properties标签
typeAliases标签
为Java类型设置一个短的名字(类型别名)
mybatis框架内置了一些java类型的别名
mapper标签
6.3 核心配置文件标签顺序
第七章 Mybatis的API概述
7.1 API介绍
Resources
SqlSessionFactoryBuilder
SqlSessionFactory
SqlSession
7.2 工作原理【了解】
第八章 Mybatis实现Dao层
8.1 传统开发方式【了解】
(1)复制一个java工程,并导入idea
(2)编写UserMapper接口
(3)编写UserMapperImpl实现类
(4)编写UserMapper.xml映射文件
(5)编写单元测试功能,模拟service调用dao过程
8.2 接口代理开发方式【重点】
(1)将mybatis实现dao传统开发方式的java工程复制一份,并导入idea中
(2)编写UserMapper接口
(3)编写UserMapper.xml映射文件
(4)编写单元测试功能,模拟service调用dao过程
(5)注意:想要执行单元测试,需要修改两个地方
(6)了解基于接口代理方式的内部执行原理(了解)
第二天–查询和多表
第一章 Mybatis单表查询
1.0 初始化java工程环境:复制一个java工程,导入idea,将dao相关代码全部删除
1.1 resultMap标签
如果数据库返回结果的列名和要封装的实体的属性名完全一致的话用resultType 属性
如果数据库返回结果的列名和要封装的实体的属性名有不一致的情况用resultMap属性
使用resultMap手动建立对象关系映射
(1)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 当前文件唯一标记 -->
<mapper namespace="cn.itcast.dao.UserMapper">
<!--查询所有,数据库列表和java实体类属性名一致-->
<select id="findAll" resultType="cn.itcast.domain.User">
select * from user
</select>
<!--
resultMap标签:手动映射数据库表中的列表和java实体类属性名
id:当前resultMap标签唯一标记
type="cn.itcast.domain.User" 手动映射的java实体类型
id标签:映射主键列
column:数据库表列名
property:java实体类属性名
result:映射普通列
column:数据库表列名
property:java实体类属性名
-->
<resultMap id="userResultMap" type="cn.itcast.domain.User">
<id column="uid" property="id"></id>
<result column="name" property="username"></result>
<result column="bir" property="birthday"></result>
<result column="gender" property="sex"></result>
<result column="address" property="address"></result>
</resultMap>
<!--查询所有,数据库列表和java实体类属性名不一致-->
<select id="findAllResultMap" resultMap="userResultMap">
SELECT id AS uid,username AS `name`,birthday AS bir,sex AS gender,address FROM `user`
</select>
</mapper>
(2)UserMapper接口类
(3)单元测试类
package cn.itcast.test;
import cn.itcast.dao.UserMapper;
import cn.itcast.domain.User;
import cn.itcast.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.Date;
import java.util.List;
/**
* 模拟service调用dao过程
*/
public class MybatisDaoProxyTest {
private SqlSession sqlSession = null;
/**
* 单元测试执行前,获取SQLsession对象
* @throws Exception
*/
@Before
public void before(){
sqlSession = MybatisUtils.openSession();
}
/**
* 单元测试执行后,释放资源
* @throws Exception
*/
@After
public void after(){
MybatisUtils.close(sqlSession);
}
@Test
public void testFindAll() throws Exception{
//获取代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> list = mapper.findAll();
for (User user : list) {
System.out.println(user);
}
}
@Test
public void testFindAllResultMap() throws Exception{
//获取代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> list = mapper.findAllResultMap();
for (User user : list) {
System.out.println(user);
}
}
}
1.2 多条件查询(二种)
需求
根据id和username查询user表
(1)UserMapper接口
(2)UserMapper.xml映射文件
(3)单元测试
1.3 模糊查询(四种)
需求
根据username模糊查询user表
(1)UserMapper接口
(2)UserMapper.xml映射文件
<!--模糊查询实现方式一
缺点:java与SQL语句耦合
-->
<select id="findByUsername1" resultType="cn.itcast.domain.User" parameterType="String">
SELECT * FROM `user` WHERE username LIKE #{username}
</select>
<!--模糊查询实现方式二【了解】
通过在SQL语句中拼接占位符 %
mysql5.5版本之前,此拼接的SQL中不支持使用单引号
oracle数据库中,除了别名位置,其他地方不能使用双引号
-->
<select id="findByUsername2" resultType="cn.itcast.domain.User" parameterType="String">
SELECT * FROM `user` WHERE username LIKE "%" #{username} "%"
</select>
<!--
模糊查询实现方式三【了解】
${} 字符串拼接 如果接受的是简单数据类型,使用固定参数名:value
存在SQL注入的问题
-->
<select id="findByUsername3" resultType="cn.itcast.domain.User" parameterType="String">
SELECT * FROM `user` WHERE username LIKE '%${value}%'
</select>
<!--
模糊查询实现方式四【掌握】
concat函数拼接字符串
Oracle:concat()函数只能传递两个参数...
/* SELECT * FROM `user` WHERE username LIKE concat('%',#{username},'%')*/
-->
<select id="findByUsername4" resultType="cn.itcast.domain.User" parameterType="String">
SELECT * FROM `user` WHERE username LIKE concat(concat('%',#{username}),'%')
</select>
(3)单元测试
1.4 ${}和#{}区别【面试】
第二章 Mybatis多表查询
2.1 一对一(多对一)
(1)实体类和表映射关系分析
(2)准备订单实体类
package cn.itcast.domain;
import java.util.Date;
public class Order {
private Integer id;
private Date ordertime;
private Double money;
//订单关联用户
private User user;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getOrdertime() {
return ordertime;
}
public void setOrdertime(Date ordertime) {
this.ordertime = ordertime;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "Order{" +
"id=" + id +
", ordertime=" + ordertime +
", money=" + money +
", user=" + user +
'}';
}
}
(2)OrderMapper接口
package cn.itcast.dao;
import cn.itcast.domain.Order;
public interface OrderMapper {
public abstract Order findByIdWithUser(int id);
}
(3)OrderMapper.xml映射文件
<resultMap id="orderMap" type="cn.itcast.domain.Order">
<id column="id" property="id"></id>
<result column="ordertime" property="ordertime"></result>
<result column="money" property="money"></result>
<!--
一对一表关系 association标签
property="user": order关联的user实体类属性名
javaType="cn.itcast.domain.User" 关联的实体类型
-->
<association property="user" javaType="cn.itcast.domain.User">
<id column="uid" property="id"></id>
<result column="username" property="username"></result>
<result column="birthday" property="birthday"></result>
<result column="sex" property="sex"></result>
<result column="address" property="address"></result>
</association>
</resultMap>
<!--
询订单的同时,查询当前订单所属用户
resultType:单表映射封装
resultMap:多表查询,必须手动映射封装
-->
<select id="findByIdWithUser" resultMap="orderMap" parameterType="int">
SELECT * FROM orders o INNER JOIN `user` u ON o.`uid`=u.id WHERE o.id=#{id}
</select>
(4)测试
2.2 一对多
(1)修改user实体类,关联订单列表
package cn.itcast.domain;
import java.util.Date;
import java.util.List;
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
private List<Order> orderList;
public List<Order> getOrderList() {
return orderList;
}
public void setOrderList(List<Order> orderList) {
this.orderList = orderList;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
", orderList=" + orderList +
'}';
}
}
(2)编写UserMapper接口
(3)编写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 当前文件唯一标记 -->
<mapper namespace="cn.itcast.dao.UserMapper">
<resultMap id="userMap" type="cn.itcast.domain.User">
<id column="id" property="id"></id>
<result column="username" property="username"></result>
<result column="birthday" property="birthday"></result>
<result column="sex" property="sex"></result>
<result column="address" property="address"></result>
<!--
配置一对多关系
property="orderList":关联的实体类属性名称
ofType="cn.itcast.domain.Order":关联的实体类对象的java类型(集合中的泛型)
-->
<collection property="orderList" ofType="cn.itcast.domain.Order">
<id column="oid" property="id"></id>
<result column="ordertime" property="ordertime"></result>
<result column="money" property="money"></result>
</collection>
</resultMap>
<select id="findByIdWithOrder" parameterType="int" resultMap="userMap">
SELECT *,o.id AS oid FROM `user` u INNER JOIN orders o ON o.`uid`=u.id WHERE u.id=#{id}
</select>
</mapper>
(4)测试
2.3 多对多(由二个一对多组成)
(1)实体类与数据库查询结果映射封装截图演示
(2)User和Role实体类
(3)UserMapper接口
(4)UserMapper.xml映射文件
(5)测试
2.4 知识小结
第三章 Mybatis映射文件深入
3.1 返回主键
应用场景
向数据库保存一个user对象后,然后在控制台记录下此新增user的主键值(id)返回主键,主要应用在表关联时。例如︰保存订单时,需要关联到用户
(1)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 当前文件唯一标记 -->
<mapper namespace="cn.itcast.dao.UserMapper">
<!--
返回主键方式一
useGeneratedKeys:开启主键返回功能,默认不开启
keyColumn:user表中的主键列
keyProperty:user实体类主键属性名
注意:仅支持主键自增类型的数据库 mysql SQL server ,Oracle不支持
-->
<insert id="save1" parameterType="cn.itcast.domain.User" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into user(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address})
</insert>
<!--
返回主键方式二
<selectKey>执行返回主键SQL语句标签
keyColumn:user表中的主键列
keyProperty:user实体类主键属性名
resultType:user实体类中主键类型
order: 返回主键的查询语句是在insert插入数据语句前执行,还是在insert插入数据语句后执行
AFTER:主键自增往往使用AFTER
BEFORE :主键提前生成, 然后在将生成的主键插入的数据库表主键列
-->
<insert id="save2" parameterType="cn.itcast.domain.User">
<selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
insert into user(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>
(2)UserMapper接口
(3)测试
package cn.itcast.test;
import cn.itcast.dao.UserMapper;
import cn.itcast.domain.User;
import cn.itcast.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.Date;
import java.util.List;
/**
* 模拟service调用dao过程
*/
public class MybatisDaoProxyTest {
private SqlSession sqlSession = null;
/**
* 单元测试执行前,获取SQLsession对象
* @throws Exception
*/
@Before
public void before(){
sqlSession = MybatisUtils.openSession();
}
/**
* 单元测试执行后,释放资源
* @throws Exception
*/
@After
public void after(){
MybatisUtils.close(sqlSession);
}
@Test
public void testSave() throws Exception{
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//新增用户,返回主键方式一
User user = new User();
user.setUsername("赵云");
user.setSex("男");
user.setBirthday(new Date());
user.setAddress("河北保定");
mapper.save2(user);
System.out.println("返回新增用户的主键id是:"+user.getId());
}
}
3.2 动态SQL
什么是动态SQL
if条件判断
使用if进行判断时,只有变量类型是字符串类型才可以加上and item!=’’
需求
把id和username封装到user对象中,将user对象中不为空的属性作为查询条件
(1)UserMapper接口
(2)UserMapper.xml文件
(3)测试类
set用于update语句
需求
动态更新user表数据,如果该属性有值就更新,没有值不做处理
(1)UserMapper接口
(2)UserMapper.xml文件
(3)测试类
foreach用于循环遍历【重点】
(1)UserMapper接口
(2)UserMapper.xml文件
<!--
foreach标签,遍历普通list集合
collection="list" 取值属性只能是list或者collection
-->
<select id="findByList" resultType="cn.itcast.domain.User" parameterType="java.lang.Integer">
select * from user where id in
<foreach collection="list" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</select>
<!--
foreach标签,遍历普通数组
collection="array" 取值属性只能是array
-->
<select id="findByArray" resultType="cn.itcast.domain.User" parameterType="java.lang.Integer">
select * from user where id in
<foreach collection="array" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</select>
<!--
foreach标签,实体类中的集合属性
如果传递的是实体类中list集合属性,collection属性取值是:实体类中list集合属性名
-->
<select id="findByQueryVo" resultType="cn.itcast.domain.User" parameterType="cn.itcast.domain.QueryVo">
select * from user where id in
<foreach collection="ids" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</select>
(3)测试类
@Test
public void testFindByList() throws Exception{
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<Integer> ids = new ArrayList<>();
ids.add(41);
ids.add(42);
ids.add(43);
List<User> userList = mapper.findByList(ids);
for (User user : userList) {
System.out.println(user);
}
}
@Test
public void testFindByArray() throws Exception{
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int[] ids = {45,48,53};
List<User> userList = mapper.findByArray(ids);
for (User user : userList) {
System.out.println(user);
}
}
@Test
public void testFindByQueryVo() throws Exception{
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
QueryVo queryVo = new QueryVo();
List<Integer> ids = new ArrayList<>();
ids.add(57);
ids.add(58);
ids.add(59);
queryVo.setIds(ids);
List<User> userList = mapper.findByQueryVo(queryVo);
for (User user : userList) {
System.out.println(user);
}
}
使用foreach进行批量插入模板
trim的使用
3.3 SQL片段
应用场景
映射文件中可将重复的sql提取出来,使用时用include 引用即可,最终达到sql重用的目的
<!--
foreach标签,遍历普通数组
collection="array" 取值属性只能是array
-->
<select id="findByArray" resultType="cn.itcast.domain.User" parameterType="java.lang.Integer">
<include refid="selectUser"></include> where id in
<foreach collection="array" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</select>
<!--
foreach标签,实体类中的集合属性
如果传递的是实体类中list集合属性,collection属性取值是:实体类中list集合属性名
-->
<select id="findByQueryVo" resultType="cn.itcast.domain.User" parameterType="cn.itcast.domain.QueryVo">
<include refid="selectUser"></include> where id in
<foreach collection="ids" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</select>
<!--
sql片段,将映射文件中重复的内容抽取
-->
<sql id="selectUser">
select username,address from user
</sql>
第三天–Mybatis嵌套查询&缓存
第一章 Mybatis嵌套查询
1.1 什么是嵌套查询
嵌套查询就是将原来多表查询中的联合查询语句拆成多个单表的查询,再使用mybatis的语法嵌套在一起
1.2 一对一嵌套查询
(1)OrderMapper接口
(2)OrderMapper映射
(3)UserMapper接口
(4)UserMapper映射
(5)通过Mybatis进行嵌套组合
(6)测试
1.3 一对多嵌套查询
(1)UserMapper接口
(2)UserMapper映射
(3)OrderMapper接口
(4)OrderMapper映射
(5)通过Mybatis进行嵌套组合
(6)测试
1.4 多对多嵌套查询
(1)UserMapper接口
(2)UserMapper映射
(3)RoleMapper接口
(4)RoleMapper映射
(5)通过Mybatis进行嵌套组合
(6)测试
1.5 知识小结
第二章 Mybatis加载策略
2.1 什么是加载策略
2.2 配置延迟加载
全局
局部
2.3 触发(立即)加载
第三章 Mybatis缓存
什么是缓存?
服务器内存(硬盘)中的一块区域
为什么使用缓存?
提高查询效率的
什么样的数据适合做缓存?
经常访问但又不经常修改的数据…
缓存是用来提高查询效率的,所有的持久层框架基本上都有缓存机制Mybatis也提供了缓存策略,分为一级缓存,二级缓存
3.1 一级缓存
介绍
验证
需求:根据id查询用户
package cn.itcast.test;
import cn.itcast.dao.UserMapper;
import cn.itcast.domain.User;
import cn.itcast.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class MybatisCacheTest {
private SqlSession sqlSession = null;
/**
* 单元测试执行前,获取SQLsession对象
* @throws Exception
*/
@Before
public void before(){
sqlSession = MybatisUtils.openSession();
}
@After
public void after(){
MybatisUtils.close(sqlSession);
}
@Test
public void test01() throws Exception{
//获取第一个代理对象
UserMapper userMapper1 = sqlSession.getMapper(UserMapper.class);
User user1 = userMapper1.findById(41);
System.out.println(user1);
//清除一级缓存
//sqlSession.clearCache();
//获取第二个代理对象
UserMapper userMapper2 = sqlSession.getMapper(UserMapper.class);
User user2 = userMapper2.findById(41);
System.out.println(user2);
}
}
分析
第四章 核心配置文件回顾
4.1 properties标签
4.2 setting标签
4.3 typeAliases标签
4.4 mappers标签
4.5 environments标签
第四天–Mybatis嵌套查询&缓存
第一章 Mybatis注解
这几年来注解开发越来越流行,Mybatis也可以使用注解开发方式,这样我们就可以减少编写Mapper映射文件了。我们先围绕一些基本的CRUD来学习,再学习复杂映射多表操作。
1.1 Mybatis常用注解
1.2 Mybatis单表操作【重点】
需求:基于user模块通过注解实现,增删改查
(1)UserMapper接口
package itcast.dao;
import itcast.domain.User;
import org.apache.ibatis.annotations.*;
import org.omg.PortableInterceptor.INACTIVE;
import java.util.List;
public interface UserMapper {
/**
* 查询所有
* @return
*/
//@Select("select * from user")
@Select("SELECT id AS uid,username AS uname,birthday AS bir,sex AS gender,address AS addr FROM `user`")
@Results({ //相当于 <resultMap>
@Result(column ="uid" ,property ="id",id=true ), //相当于 <result> id=true表明当前列是主键列
@Result(column = "uname",property = "username"),
@Result(column = "bir",property = "birthday"),
@Result(column = "gender",property = "sex"),
@Result(column = "addr",property = "address")
})
List<User> findAll();
/**
* 基于id查询用户
*/
@Select("select * from user where id =#{id}")
User findById(Integer id);
/**
* 新增用户信息
*/
@Insert("insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})")
void save(User user);
/**
* 修改用户 动态SQL推荐使用xml映射文件方式完成编写
*/
@Update("update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}")
void update(User user);
/**
* 基于id删除用户
*/
@Delete("delete from user where id=#{id}")
void delete(Integer id);
}
(2)测试
package itcast.test;
import itcast.dao.UserMapper;
import itcast.domain.User;
import itcast.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
/**
* 模拟service调用dao过程
*/
public class MybatisDaoProxyTest {
private SqlSession sqlSession = null;
/**
* 单元测试执行前,获取SQLsession对象
* @throws Exception
*/
@Before
public void before(){
sqlSession = MybatisUtils.openSession();
}
@After
public void after(){
MybatisUtils.close(sqlSession);
}
@Test
public void test01() throws Exception{
//获取代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//查询所有
/*List<User> list = mapper.findAll();
for (User user : list) {
System.out.println(user);
}*/
//基于用户id查询
/* User user = mapper.findById(41);
System.out.println(user);*/
//新增用户
/*User user = new User();
user.setUsername("tom");
user.setBirthday(new Date());
user.setSex("女");
user.setAddress("北京");
mapper.save(user);*/
//修改用户
/* User user = new User();
user.setUsername("jerry");
user.setBirthday(new Date());
user.setSex("女");
user.setAddress("上海");
user.setId(60);
mapper.update(user);*/
//删除用户
mapper.delete(60);
}
}
1.3 Mybatis多表操作【了解】
一对一查询
(1)OrderMapper接口
(2)UserMapper接口
(3)注解嵌套
(4)测试
一对多查询
(1)UserMapper接口
(2)OrderMapper接口
(3)注解嵌套
(4)测试
多对多查询
(1)UserMapper接口
(2)RoleMapper接口
(3)注解嵌套
(4)测试