MyBatis高级
一,MyBatis注解开发
1,常用注解介绍
-
我们除了可以使用映射配置文件来操作以外,还可以使用注解形式来操作。
-
常用注解
- @Select(“查询的 SQL 语句”):执行查询操作注解
- @Insert(“新增的 SQL 语句”):执行新增操作注解
- @Update(“修改的 SQL 语句”):执行修改操作注解
- @Delete(“删除的 SQL 语句”):执行删除操作注解
2,注解实现查询操作
-
创建接口和查询方法,在方法上加上对应注解(就不需要映射文件了)
-
在核心配置文件中配置映射关系
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sE8MHGTn-1592649539343)(C:\Users\HUANGHAI\AppData\Roaming\Typora\typora-user-images\1592392624654.png)]
-
编写测试类
案例eg:核心配置文件
标准类
package com.itheima.bean;
public class Student {
private Integer id;
private String name;
private Integer age;
public Student() {
}
public Student(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
。。。。
接口
```java
import com.itheima.bean.Student;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
public interface StudentMapper {
//查询全部
@Select("SELECT * FROM student")
public abstract List<Student> selectAll();
//新增操作
@Insert("INSERT INTO student VALUES (#{id},#{name},#{age})")
public abstract Integer insert(Student stu);
//修改操作
@Update("UPDATE student SET name=#{name},age=#{age} WHERE id=#{id}")
public abstract Integer update(Student stu);
//删除操作
@Delete("DELETE FROM student WHERE id=#{id}")
public abstract Integer delete(Integer id);
}
测试类
package com.itheima.test;
import com.itheima.bean.Student;
import com.itheima.mapper.StudentMapper;
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 Test01 {
@Test
public void selectAll() throws Exception{
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
//2.获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//5.调用实现类对象中的方法,接收结果
List<Student> list = mapper.selectAll();
//6.处理结果
for (Student student : list) {
System.out.println(student);
}
//7.释放资源
sqlSession.close();
is.close();
}
3,注解实现新增操作
配置核心配置文件
<mappers>
<package name="com.itheima.mapper"/>
<mappers/>
标准类,同上
接口
import com.itheima.bean.Student;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
public interface StudentMapper {
//新增操作
@Insert("INSERT INTO student VALUES (#{id},#{name},#{age})")
public abstract Integer insert(Student stu);
}
测试类
@Test
public void insert() throws Exception{
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
//2.获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//5.调用实现类对象中的方法,接收结果
Student stu = new Student(4,"赵六",26);
Integer result = mapper.insert(stu);
//6.处理结果
System.out.println(result);
//7.释放资源
sqlSession.close();
is.close();
}
4,注解实现修改操作
配置核心配置文件
<mappers>
<package name="com.itheima.mapper"/>
<mappers/>
标准类,同上
接口
import com.itheima.bean.Student;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
public interface StudentMapper {
//修改操作
@Update("UPDATE student SET name=#{name},age=#{age} WHERE id=#{id}")
public abstract Integer update(Student stu);
}
测试类
@Test
public void update() throws Exception{
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
//2.获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//5.调用实现类对象中的方法,接收结果
Student stu = new Student(4,"赵六",36);
Integer result = mapper.update(stu);
//6.处理结果
System.out.println(result);
//7.释放资源
sqlSession.close();
is.close();
}
5,注解实现删除操作
核心配置文件
<mappers>
<package name="com.itheima.mapper"/>
<mappers/>
标准类,同上
接口
import com.itheima.bean.Student;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
public interface StudentMapper {
//删除操作
@Delete("DELETE FROM student WHERE id=#{id}")
public abstract Integer delete(Integer id);
}
测试类
@Test
public void delete() throws Exception{
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
//2.获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//5.调用实现类对象中的方法,接收结果
Integer result = mapper.delete(4);
//6.处理结果
System.out.println(result);
//7.释放资源
sqlSession.close();
is.close();
}
6,注解开发小结
-
注解可以简化开发操作,省略映射配置文件的编写。
-
常用注解
@Select(“查询的 SQL 语句”):执行查询操作注解
@Insert(“查询的 SQL 语句”):执行新增操作注解
@Update(“查询的 SQL 语句”):执行修改操作注解
@Delete(“查询的 SQL 语句”):执行删除操作注解
-
配置接口映射关系
-
<mappers> <package name="接口所在包"/> <mappers/>
二,MyBatis注解实现多表操作
1,一对一的环境介绍
-
环境准备
- @Results:封装映射关系的父注解。
Result[] value():定义了 Result 数组
- @Result:封装映射关系的子注解。
column 属性:查询出的表中字段名称
property 属性:实体对象中的属性名称
javaType 属性:被包含对象的数据类型
one 属性:一对一查询固定属性
- @One:一对一查询的注解。
select 属性:指定调用某个接口中的方法
2,一对一的实现
写一个父包,可以映射一对一,一对多,多对多包下的接口
<mappers>
<package name="com.itheima"/>
</mappers>
标准类(person,card表)
public class Person {
private Integer id; //主键id
private String name; //人的姓名
private Integer age; //人的年龄
public Person() {
}
public Person(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
。。。。
}
public class Card {
private Integer id; //主键id
private String number; //身份证号
private Person p; //所属人的对象
public Card() {
}
public Card(Integer id, String number, Person p) {
this.id = id;
this.number = number;
this.p = p;
};
。。。。。
}
接口
import com.itheima.bean.Card;
import com.itheima.bean.Person;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface CardMapper {
@Select("SELECT * FROM card")
@Results({
@Result(column = "id" ,property = "id"),
@Result(column = "number" ,property = "number"),
@Result(
property = "p",
javaType = Person.class,
column = "pid",//用card表中的pid字段来查询person表
//one、@One一对一固定写法,select属性:指定采用哪个接口中的哪个方法,从而得到person对象
// 相当于把pid作为PersonMapper接口条件传进来,然后得到封装了的person对象
one= @One(select = "com.itheima.one_to_one.PersonMapper.selectById")
)
})
List<Card> selectAll();
}
import com.itheima.bean.Person;
import org.apache.ibatis.annotations.Select;
public interface PersonMapper {
@Select("SELECT *FROM person WHERE id=#{id}")
Person selectById(Integer id);
}
测试类
import com.itheima.bean.Card;
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.IOException;
import java.io.InputStream;
import java.util.List;
public class Test01 {
@Test
public void selectAll() throws Exception {
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
CardMapper mapper = sqlSession.getMapper(CardMapper.class);
List<Card> cards = mapper.selectAll();
for (Card card : cards) {
System.out.println(card);
}
sqlSession.close();
is.close();
}
}
3,一对多的环境介绍
- @Results:封装映射关系的父注解。
Result[] value():定义了 Result 数组
- @Result:封装映射关系的子注解。
column 属性:查询出的表中字段名称
property 属性:实体对象中的属性名称
javaType 属性:被包含对象的数据类型
many 属性:一对多查询固定属性
- @Many:一对多查询的注解。
select 属性:指定调用某个接口中的方法
4,一对多的实现
<mappers>
<package name="com.itheima"/>
</mappers>
标准类(学生类,班级类)
import java.util.List;
public class Classes {
private Integer id; //主键id
private String name; //班级名称
private List<Student> students; //班级中所有学生对象
public Classes() {
}
public Classes(Integer id, String name, List<Student> students) {
this.id = id;
this.name = name;
this.students = students;
}
。。。。。
}
import java.util.List;
public class Student {
private Integer id; //主键id
private String name; //学生姓名
private Integer age; //学生年龄
private List<Course> courses; //学生所选择的课程对象
public Student() {
}
public Student(Integer id, String name, Integer age, List<Course> courses) {
this.id = id;
this.name = name;
this.age = age;
this.courses = courses;
}
。。。。。
}
接口(ClassesMapper和StudentMapper)
5,多对多的环境介绍
6,多对多的实现
标准类(student和课程表)
import java.util.List;
public class Student {
private Integer id; //主键id
private String name; //学生姓名
private Integer age; //学生年龄
private List<Course> courses; //学生所选择的课程对象
public Student() {
}
public Student(Integer id, String name, Integer age, List<Course> courses) {
this.id = id;
this.name = name;
this.age = age;
this.courses = courses;
}
。。。。。
}
public class Course {
private Integer id; //主键id
private String name; //课程名称
public Course() {
}
public Course(Integer id, String name) {
this.id = id;
this.name = name;
}
。。。。。
}
接口(CourseMapper和StudentMapper)
import com.itheima.bean.Course;
import com.itheima.bean.Student;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface StudentMapper {
//用这个语句来去除重复
@Select("SELECT * FROM student WHERE id IN(SELECT sid FROM stu_cr)")
@Results({
@Result(column = "id",property = "id"),
@Result(column = "name",property = "name"),
@Result(column = "age",property = "age"),
@Result(
property = "courses",
javaType = List.class,
//学生表中的主键id作为关联条件来找课程表和中间表的数据
column = "id",
//指定调用哪个接口中的哪个方法
many=@Many(select = "com.itheima.many_to_many.CourseMapper.selectBySid")
)
})
List<Student> selectAll();
}
import com.itheima.bean.Course;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface CourseMapper {
//因为查询的是id,name这种简单查询,所以可以自动封装,没有查引用数据,所以这样写可以
@Select("SELECT c.id ,c.name FROM stu_cr sc,course c WHERE sc.cid=c.id AND sc.sid=#{id}")
List<Course> selectBySid(Integer id);
}
测试类
import com.itheima.bean.Course;
import com.itheima.bean.Student;
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 Test01 {
@Test
public void selectAll() throws Exception{
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
//2.获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//5.调用实现类对象中的方法,接收结果
List<Student> list = mapper.selectAll();
//6.处理结果
for (Student student : list) {
System.out.println(student.getId() + "," + student.getName() + "," + student.getAge()+"\t" );
List<Course> courses = student.getCourses();
for (Course cours : courses) {
System.out.println( cours);
}
}
//7.释放资源
sqlSession.close();
is.close();
}
}
结果
1,张三,23
Course{id=1, name='语文'}
Course{id=2, name='数学'}
2,李四,24
Course{id=1, name='语文'}
Course{id=2, name='数学'}
7,注解多表操作的小结
-
@Results:封装映射关系的父注解。
-
Result[] value():定义了 Result 数组
-
@Result:封装映射关系的子注解。
-
column 属性:查询出的表中字段名称
-
property 属性:实体对象中的属性名称
-
javaType 属性:被包含对象的数据类型
-
one 属性:一对一查询固定属性
-
many 属性:一对多查询固定属性
-
@One:一对一查询的注解。
-
select 属性:指定调用某个接口中的方法
-
@Many:一对多查询的注解。
-
select 属性:指定调用某个接口中的方法
三,MyBatis构建SQL语句
1,SQL功能类的介绍
-
我们之前通过注解开发时,相关 SQL 语句都是自己直接拼写的。一些关键字写起来比较麻烦、而且容易出错。
-
MyBatis 给我们提供了 org.apache.ibatis.jdbc.SQL 功能类,专门用于构建 SQL 语句。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CTCX2eBS-1592649539348)(C:\Users\HUANGHAI\AppData\Roaming\Typora\typora-user-images\1592562308300.png)]
-
接口注解
@SelectProvider:生成查询用的 SQL 语句注解。
@InsertProvider:生成新增用的 SQL 语句注解。
@UpdateProvider:生成修改用的 SQL 语句注解。
@DeleteProvider:生成删除用的 SQL 语句注解。
type 属性:生成 SQL 语句功能类对象
method 属性:指定调用方法
2,查询功能的实现
3,新增能功能的实现
4,修改功能的实现
5,删除功能的实现
6,构建SQL的小结
-
定义功能类并提供获取查询的 SQL 语句的方法。
-
package com.itheima.sql; import com.itheima.bean.Student; import org.apache.ibatis.jdbc.SQL; public class ReturnSql { //定义方法,返回查询的sql语句 public String getSelectAll() { return new SQL() { { SELECT("*"); FROM("student"); } }.toString(); } //定义方法,返回新增的sql语句 public String getInsert(Student stu) { return new SQL() { { INSERT_INTO("student"); INTO_VALUES("#{id},#{name},#{age}"); } }.toString(); } //定义方法,返回修改的sql语句 public String getUpdate(Student stu) { return new SQL() { { UPDATE("student"); SET("name=#{name}","age=#{age}"); WHERE("id=#{id}"); } }.toString(); } //定义方法,返回删除的sql语句 public String getDelete(Integer id) { return new SQL() { { DELETE_FROM("student"); WHERE("id=#{id}"); } }.toString(); } }
接口注解
package com.itheima.mapper; import com.itheima.bean.Student; import com.itheima.sql.ReturnSql; import org.apache.ibatis.annotations.DeleteProvider; import org.apache.ibatis.annotations.InsertProvider; import org.apache.ibatis.annotations.SelectProvider; import org.apache.ibatis.annotations.UpdateProvider; import java.util.List; public interface StudentMapper { //查询全部 //@Select("SELECT * FROM student") @SelectProvider(type = ReturnSql.class , method = "getSelectAll") public abstract List<Student> selectAll(); //新增功能 //@Insert("INSERT INTO student VALUES (#{id},#{name},#{age})") @InsertProvider(type = ReturnSql.class , method = "getInsert") public abstract Integer insert(Student stu); //修改功能 //@Update("UPDATE student SET name=#{name},age=#{age} WHERE id=#{id}") @UpdateProvider(type = ReturnSql.class , method = "getUpdate") public abstract Integer update(Student stu); //删除功能 //@Delete("DELETE FROM student WHERE id=#{id}") @DeleteProvider(type = ReturnSql.class , method = "getDelete") public abstract Integer delete(Integer id); }
四,MyBatis学生管理系统
1,学生管理系统的介绍和环境搭建
2,学生管理系统的实现
vider(type = ReturnSql.class , method = “getSelectAll”)
public abstract List selectAll();
//新增功能
//@Insert("INSERT INTO student VALUES (#{id},#{name},#{age})")
@InsertProvider(type = ReturnSql.class , method = "getInsert")
public abstract Integer insert(Student stu);
//修改功能
//@Update("UPDATE student SET name=#{name},age=#{age} WHERE id=#{id}")
@UpdateProvider(type = ReturnSql.class , method = "getUpdate")
public abstract Integer update(Student stu);
//删除功能
//@Delete("DELETE FROM student WHERE id=#{id}")
@DeleteProvider(type = ReturnSql.class , method = "getDelete")
public abstract Integer delete(Integer id);
}
## 四,MyBatis学生管理系统
### 1,学生管理系统的介绍和环境搭建
### 2,学生管理系统的实现
##