1. 注解开发(理解)
对于简单的SQL
,建议使用注解;对于复杂SQL
,建议使用xml
配置映射配置文件。
1.1 常用注解
-
@Insert:实现新增 相当于标签
@Update:实现更新 相当于标签
@Delete:实现删除 相当于标签
@Select:实现查询 相当于标签
1.3查询-单表
interface StudentMapper{
// 标注在方法是,可以通过注解获取到方法的返回值类型、参数类型、该方法属于哪个类
@Select("select * from student")
List<Student> findAll();
}
测试代码
@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);
for(Student stu : list){
System.out.println(stu);
}
//7.释放资源
sqlSession.close();
is.close();
}
1.4 新增-单表
StudentMapper
接口
interface StudentMapper{
//新增操作
@Insert("INSERT INTO student VALUES (#{id},#{name},#{age})")
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();
}
1.4.1 新增并返回自增的主键
StudentMapper
接口
interface StudentMapper{
//新增操作
@Insert("INSERT INTO student VALUES (#{id},#{name},#{age})")
@Option(useGeneratedKeys=true, keyColumns="id",keyProperty="id")
Integer insert(Student stu);
}
新增之前,封装了一个Student对象,该对象的id没有赋值;当调用完新增方法之后,会把当前学生的信息保存进数据库并返回主键id,而且会把该id设置进之前是Student对象。
1.5 修改-单表
StudentMapper
接口
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();
}
1.6 删除-单表
StudentMapper
接口
interface StudentMapper{
//删除操作
@Delete("DELETE FROM student WHERE id=#{idx}")
public abstract Integer delete(@Param("idx")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();
}
1.7 一对一查询
CardMapper.java
public interface CardMapper {
//查询全部
@Select("SELECT * FROM card") //@Select 相当于Select标签
@Results({ //@Results 相当于 ResultMap标签
@Result(column = "id",property = "id",id = true), // @Result + id=true相当于id标签
@Result(column = "number",property = "number"), @Result + id=fasle相当于result标签
@Result( //@Result 相当于association
property = "p", // 被关联对象的变量名
javaType = Person.class, // 被关联对象的实际数据类型
column = "pid", // 根据查询出的card表中的pid字段来查询person表
/*
one = @One(select="") 一对一分步查询,延迟加载的固定写法
select属性:指定查询关联对象时,调用哪个接口中的哪个方法
*/
one = @One(select = "com.itheima.one_to_one.PersonMapper.selectById")
)
})
public abstract List<Card> selectAll();
}
PersonMapper.java
public interface PersonMapper {
//根据id查询
@Select("SELECT * FROM person WHERE id=#{id}")
public abstract Person selectById(Integer id);
}
1.8 一对多查询
ClassesMapper.java
public interface ClassesMapper {
//查询全部
@Select("SELECT * FROM classes")
@Results({
@Result(column = "id",property = "id",id=true),
@Result(column = "name",property = "name"),
@Result(
property = "students", // 被包含对象的变量名
javaType = List.class, // 被包含对象的实际数据类型
column = "id", // 根据查询出的classes表的id字段来查询student表
/*
many = @Many(select="") 一对多分步查询,延迟加载的固定写法
select属性:指定查询关联对象时,调用哪个接口中的哪个方法
*/
many = @Many(select = "com.itheima.one_to_many.StudentMapper.selectByCid")
)
})
public abstract List<Classes> selectAll();
}
StudentMapper.java
public interface StudentMapper {
//根据cid查询student表
@Select("SELECT * FROM student WHERE cid=#{cid}")
public abstract List<Student> selectByCid(Integer cid);
}
1.9 多对多
多对多的本质就是多个一对多,可以使用一对多映射多对多。
public interface StudentMapper {
// 查询有选课信息的全部学生,加上中间表联查目的是为了去除没有选课的学生
@Select("SELECT DISTINCT s.id,s.name,s.age FROM student s,stu_cr sc WHERE sc.sid=s.id")
// 查询所有学生
// @Select("SELECT * FROM student ")
@Results({
@Result(column = "id",property = "id"),
@Result(column = "name",property = "name"),
@Result(column = "age",property = "age"),
@Result(
property = "courses", // 被包含对象的变量名
javaType = List.class, // 被包含对象的实际数据类型
column = "id", // 根据查询出student表的id来作为关联条件,去查询中间表和课程表
/*
many = @Many(select="") 一对多分步查询,延迟加载的固定写法
select属性:指定查询关联对象时,调用哪个接口中的哪个方法
*/
many = @Many(select = "com.itheima.many_to_many.CourseMapper.selectCourseByStudentid")
)
})
public abstract List<Student> selectAll();
}
CourseMapper.java
public interface CourseMapper {
//根据学生id查询所选课程
@Select("SELECT c.id,c.name FROM stu_cr sc,course c WHERE sc.cid=c.id AND sc.sid=#{id}")
public abstract List<Course> selectCourseByStudentid(Integer studentId);
}
3. SQL
构建(了解)
将SQL
写在注解中不美观且手动写SQL
容易出错,可以通过mybatis
提供的构建自动生成SQL
语句
作用:
- 不用手写SQL
- 可以实现动态SQL拼接
select * from student
SQL.select("**").from(“student”) .toString = select * from student
3.1 注解
@SelectProvider
@InsertProvider
@UpdateProvider
@DeleteProvider
3.2 使用
标注在dao
层接口的方法上,获取用户构建好的SQL
语句
-
type
属性:指定构建SQL
语句的类的类型Xxx.class
-
method
属性:指定构建SQL
语句的类中的方法名(字符串形式,无括号),"getAll"
如果说
SQL
语句需要传递参数,在构造SQL
的方法形参位置定义与dao
层接口对应方法相同类型的参数即可。
3.3 代码
构建SQL
语句的ReturnSql.java
public class ReturnSql {
//定义方法,返回查询的sql语句
public String getSelectAll() {
/*return new SQL() {
{
SELECT("*");
FROM("student");
}
}.toString();*/
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();*/
return "INSERT INTO student VALUES (#{id},#{name},#{age})";
}
//定义方法,返回修改的sql语句
public String getUpdate(Student stu) {
return new SQL() {
{
/*UPDATE("student");
SET("name=#{name}", "age=#{age}");
WHERE("id=#{id}");*/
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();
}
}
数据持久层接口类StudentMapper.java
public interface StudentMapper {
//查询全部
//@Select("SELECT * FROM student")
/*
type:生成SQL语句的类
method:生成SQL语句的类的方法名称
* */
@SelectProvider(type = ReturnSql.class , method = "getSelectAll")
public abstract List<Student> selectAll();
//新增功能
//@Insert("INSERT INTO student VALUES (#{id},#{name},#{age})")
/*
type:生成SQL语句的类
method:生成SQL语句的类的方法名称
* */
@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);
}
3. 学生管理系统
整合
-
导包
mybatis
log4j
-
编写配置文件核心配置使用
xml
-
在接口中为每个方法编写
SQL
语句(映射配置使用注解) -
在
Service
中要要修改获取dao
层接口实现类对象的方式从原来自己new一个,改成找
Mybatis
的SQLSession
获取
MybatisUtils.java
public class MybatisUtils<T> {
private static SqlSession sqlSession = null;
private static InputStream is = null;
private MybatisUtils() {
}
// 提供获取Dao层接口代理对象的方法
public static SqlSession getSqlSession() {
try {
//1.加载核心配置文件
is = Resources.getResourceAsStream("MyBatisConfig.xml");
//2.获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取SqlSession对象
sqlSession = sqlSessionFactory.openSession(true);
} catch (Exception e) {
e.printStackTrace();
}
return sqlSession;
}
// 释放资源
public static void realse(){
sqlSession.close();
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
逆向工程
逆向工程:
原来步骤:自己domain、dao、dao.xml,对应数据库中的表
逆向工程:根据数据库库中的表,自动生成domain、dao接口、daoxml
Mybatis官方提供了逆向工程实现的基础jar包:mybatis-generator-core-1.3.6.jar