配置文件CRUD就是把sql语句写到配置文件中,注解CRUD就是吧sql语句写到注解上。




create database mybatis;
use mybatis;drop table if exists tb_user;create table tb_user(id int primary key auto_increment,username varchar(20),password varchar(20),gender char(1),addr varchar(30)
);INSERT INTO tb_user VALUES (1, 'zhangsan', '123', '男', '北京');
INSERT INTO tb_user VALUES (2, '李四', '234', '女', '天津');
INSERT INTO tb_user VALUES (3, '王五', '11', '男', '西安');
public class Brand {// id 主键private Integer id;// 品牌名称private String brandName;// 企业名称private String companyName;// 排序字段private Integer ordered;// 描述信息private String description;// 状态:0:禁用 1:启用private Integer status;//省略 setter and getter。自己写时要补全这部分代码}
注意:安装完毕后需要重启IDEA 插件效果。--看到小鸟出来了,蓝色的小鸟是mapper接口,红色的小鸟是sql映射文件。在statement这个位置,我想要找到selectAll()方法,直接点击那个鸟(蓝色的小鸟)就可以直接跳转过来,如果想要看这个方法对应的sql语句,还是直接点击那个鸟(红色的小鸟)就可以跳转过来
红色头绳的表示映射配置文件,蓝色头绳的表示mapper接口。在mapper接口点击红色头绳的小鸟图标会自动跳转 到对应的映射配置文件,在映射配置文件中点击蓝色头绳的小鸟图标会自动跳转到对应的mapper接口。也可以在 mapper接口中定义方法,自动生成映射配置文件中的 statement ,如图所示
比如你在mapper接口写上selectById()方法,看到报错,说这个sql语句selectById没有定义在配置文件中。它可以帮助我们定义按住enter+alt快捷键,然后就可以在配置文件写sql语句了。



第一就是我们就写好mapper接口方法,第二就是通过mybatisX插件生成对应的sql statement,它只能生成对应的sql标签,以及id和resultType,其他的sql语句要自己写,第三就是写对应的测试方法。
BrandMapper
public interface BrandMapper {/*** 查询所有*/List selectAll();}
BrandMapper.xml
public class MyBatisTest {@Testpublic void testSelectAll() throws IOException {//1. 获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2. 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//3. 获取Mapper接口的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);//4. 执行方法List brands = brandMapper.selectAll();System.out.println(brands);//5. 释放资源sqlSession.close();}}

BrandMapper.xml
注意:
1.mybatis数据库的列名,跟封装对象的各个属性名必须是完全相同的,不相同会出现取值为空。
2.因为jdbc是通过赋值吧数据库数据赋值到对象属性的,所以属性名可以不同,但是这里对象属性必须和数据库当中的名字一样,要不然为null。
3.定义sql片段(id去定义),然后再去引用它(通过include中的refid属性),有点类似css中的id选择器。
4.resultMap标签有2个属性,id是唯一标识,可以随便起个别名。type是当前的resultMap要和那个类型映射。id是主键映射,result是一般字段映射。
从上面结果可以看到 brandName 和 companyName 这两个属性的数据没有封装成功,查询 实体类 和 表中的字段 发现,在 实体类中属性名是 brandName 和 companyName ,而表中的字段名为 brand_name 和 company_name ,如下图所示 。那么 我们只需要保持这两部分的名称一致这个问题就迎刃而解。
我们可以在写sql语句时给这两个字段起别名,将别名定义成和属性名一致即可。
BrandMapper.xml

在每个数据后面都有一个查看详情按钮,你点击它他会把商品详细信息列表展示在这里。每一条记录都可以查看详情,查看详情就是查看某条数据的详细信息。你单击查看详情按钮他会把当前数据的id传到后台java代码,java代码根据id完成查询,查完之后会把这条记录的数据对象返回给页面,页面就会展示这条记录详细信息。


在 BrandMapper 接口中定义根据id查询数据的方法
/** * 查看详情:根据Id查询 */ Brand selectById(int id);在 test/java 下的 com.itheima.mapper 包下的 MybatisTest类中 定义测试方法
@Test public void testSelectById() throws IOException { //接收参数,该id以后需要传递过来 int id = 1; //1. 获取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //2. 获取SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //3. 获取Mapper接口的代理对象 BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); //4. 执行方法 Brand brand = brandMapper.selectById(id); System.out.println(brand); //5. 释放资源 sqlSession.close(); } 执行测试方法结果如下:
注意:从上面两个例子可以看出,以后开发我们使用 #{} 参数占位符。
可以看出报错了,因为映射配置文件是xml类型的问题,而 > < 等这些字符在xml中有特殊含义,所以此时我们需要将这些符 号进行转义,可以使用以下两种方式进行转义

简单的分析后,我们来看功能实现的步骤: 在 BrandMapper.xml 映射配置文件中编写 statement ,使用 resultMap 而不是使用 resultType
在 test/java 下的 com.itheima.mapper 包下的 MybatisTest类中 定义测试方法
@Test public void testSelectByCondition() throws IOException { //接收参数 int status = 1; String companyName = "华为"; String brandName = "华为"; // 处理参数 companyName = "%" + companyName + "%"; brandName = "%" + brandName + "%"; //1. 获取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //2. 获取SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //3. 获取Mapper接口的代理对象 BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); //4. 执行方法 //方式一 :接口方法参数使用 @Param 方式调用的方法 //List
但是它也存在问题,如果此时给的参数值是 Map map = new HashMap(); // map.put("status" , status); map.put("companyName", companyName); map.put("brandName" , brandName); 拼接的SQL语句就变成了 select * from tb_brand where and company_name like ? and brand_name like ? 而上面的语句中 where 关键后直接跟 and 关键字,这就是一条错误的SQL语句。这个就可以使用 where 标签解决 
在 BrandMapper 接口中定义单条件查询的方法。
/** * 单条件动态查询 * @param brand * @return */ List在 BrandMapper.xml 映射配置文件中编写 statement ,使用 resultMap 而不是使用 resultType
在 test/java 下的 com.itheima.mapper 包下的 MybatisTest类中 定义测试方法
@Test public void testSelectByConditionSingle() throws IOException { //接收参数 int status = 1; String companyName = "华为"; String brandName = "华为"; // 处理参数 companyName = "%" + companyName + "%"; brandName = "%" + brandName + "%"; //封装对象 Brand brand = new Brand(); //brand.setStatus(status); brand.setCompanyName(companyName); //brand.setBrandName(brandName); //1. 获取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //2. 获取SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //3. 获取Mapper接口的代理对象 BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); //4. 执行方法 List执行测试方法结果如下:


在 BrandMapper 接口中定义添加方法。
/** * 添加 */ void add(Brand brand);在 BrandMapper.xml 映射配置文件中编写添加数据的 statement
在 test/java 下的 com.itheima.mapper 包下的 MybatisTest类中 定义测试方法
@Test public void testAdd() throws IOException { //接收参数 int status = 1; String companyName = "波导手机"; String brandName = "波导"; String description = "手机中的战斗机"; int ordered = 100; //封装对象 Brand brand = new Brand(); brand.setStatus(status); brand.setCompanyName(companyName); brand.setBrandName(brandName); brand.setDescription(description); brand.setOrdered(ordered); //1. 获取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //2. 获取SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //SqlSession sqlSession = sqlSessionFactory.openSession(true); //设置自动提交事务,这种情况不需 要手动提交事务了 //3. 获取Mapper接口的代理对象 BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); //4. 执行方法 brandMapper.add(brand); //提交事务 sqlSession.commit(); //5. 释放资源 sqlSession.close(); } 执行结果如下:
订单数据存储在订单表中,订单项存储在订单项表中。
明白了什么时候 主键返回 。接下来我们简单模拟一下,在添加完数据后打印id属性值,能打印出来说明已经获取到了。 我们将上面添加品牌数据的案例中映射配置文件里 statement 进行修改,如下 
在 BrandMapper 接口中定义修改方法。
/** * 修改 */ void update(Brand brand);上述方法参数 Brand 就是封装了需要修改的数据,而id肯定是有数据的,这也是和添加方法的区别。
在 BrandMapper.xml 映射配置文件中编写修改数据的 statement 。
在 test/java 下的 com.itheima.mapper 包下的 MybatisTest类中 定义测试方法
@Test public void testUpdate() throws IOException { //接收参数 int status = 0; String companyName = "波导手机"; String brandName = "波导"; String description = "波导手机,手机中的战斗机"; int ordered = 200; int id = 6; //封装对象 Brand brand = new Brand(); brand.setStatus(status); // brand.setCompanyName(companyName); // brand.setBrandName(brandName); // brand.setDescription(description); // brand.setOrdered(ordered); brand.setId(id); //1. 获取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //2. 获取SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //SqlSession sqlSession = sqlSessionFactory.openSession(true); //3. 获取Mapper接口的代理对象 BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); //4. 执行方法 int count = brandMapper.update(brand); System.out.println(count); //提交事务 sqlSession.commit(); //5. 释放资源 sqlSession.close(); } 执行测试方法结果如下:
从结果中SQL语句可以看出,只修改了 status 字段值,因为我们给的数据中只给Brand实体对象的 status 属性设置值 了。这就是 set 标签的作用。 
在 BrandMapper 接口中定义根据id删除方法。
/** * 根据id删除 */ void deleteById(int id);在 BrandMapper.xml 映射配置文件中编写删除一行数据的 statement
在 test/java 下的 com.itheima.mapper 包下的 MybatisTest类中 定义测试方法
@Test public void testDeleteById() throws IOException { //接收参数 int id = 6; //1. 获取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //2. 获取SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //SqlSession sqlSession = sqlSessionFactory.openSession(true); //3. 获取Mapper接口的代理对象 BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); //4. 执行方法 brandMapper.deleteById(id); //提交事务 sqlSession.commit(); //5. 释放资源 sqlSession.close(); } 运行过程只要没报错,直接到数据库查询数据是否还存在。
在 test/java 下的 com.itheima.mapper 包下的 MybatisTest类中 定义测试方法
@Test public void testDeleteByIds() throws IOException { //接收参数 int[] ids = {5,7,8}; //1. 获取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //2. 获取SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //SqlSession sqlSession = sqlSessionFactory.openSession(true); //3. 获取Mapper接口的代理对象 BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); //4. 执行方法 brandMapper.deleteByIds(ids); //提交事务 sqlSession.commit(); //5. 释放资源 sqlSession.close(); }
在映射配合文件的SQL语句中使用用 arg 开头的和 param 书写,代码的可读性会变的特别差,此时可以使用 @Param 注解。
在接口方法参数上使用 @Param 注解,Mybatis 会将 arg 开头的键名替换为对应注解的属性值。
代码验证:
结论:以后接口参数是多个时,在每个参数上都使用 @Param 注解。这样代码的可读性更高。
所以,注解完成简单功能,配置文件完成复杂功能。
而我们之前写的动态 SQL 就是复杂的功能,如果用注解使用的话,就需要使用到 Mybatis 提供的SQL构建器来完成,而对应 的代码如下: