8.1 面向接口编程
解耦
接口从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离
接口的本身反映了系统设计人员对系统的抽象理解。
接口应有两类:第一类是对一个个体的抽象,它可对应为一个抽象体(abstract class);
第二类是对一个个体某一方面的抽象,即形成一个抽象面(interface);
8.2 使用接口开发
使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让你本就复杂的 SQL 语句更加混乱不堪。 因此,如果你需要做一些很复杂的操作,最好用 XML 来映射语句。
注解在接口上实现【核心:使用了反射】
@Select("select * from user")
List<User> getUsers();
需要在核心配置文件中绑定接口
<!-- 绑定接口-->
<mappers>
<mapper class="com.ex.dao.UserMapper"/>
</mappers>
测试使用
public void test(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
//底层主要应用反射
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.getUsers();
for (User user : users) {
System.out.println(user);
}
sqlSession.close();
本质:反射机制实现
底层:动态代理
Mybatis 详细的执行流程!
8.3 CRUD
我们可以在工具类创建的时候实现自动提交事务
public static SqlSession getSqlSession(){
//这样就可以自动commit
return sqlSessionFactory.openSession(true);
}
编写接口,增加注解
public interface UserMapper {
@Select("select * from user")
List<User> getUsers();
//根据id查询用户
@Select("select * from user where id=#{id} ")
User getUserById(@Param("id") int id2);//注解的这个‘id'优先级更高
// 方法存在多个参数,所有参数前面必须加上@Param注解
@Insert("insert into user(id,name,pwd) values (#{id},#{name},#{password})")
int addUser(User user);
@Update("update user set id=#{id},name=#{name},pwd=#{password} where id=#{id}")
int UpdateUser(User user);
@Delete("delete from user where id=#{id}")
int deleteUser(@Param("id") int id);
}
测试类
【注意:我们必须要把接口注册绑定到我们的核心配置文件中】
关于@Param()注解
基本类型的参数或者String类型需要加上
引用类型不需要加
如果只有一个基本类型的话,可以忽略,但是建议大家都加上
我们在SQL中引用的就是我们这里的@Param()中设定的属性
#{} 和${} 的区别:
#{}是预编译处理,${}是字符串替换
使用#{}可以有效的防止SQL注入,提高系统安全性。
错误集锦
错误现象
org.apache.ibatis.binding.BindingException: Type interface com.ex.dao.UserMapper is not known to the MapperRegistry.
在mapper.xml配置签名时,写错了,配成了pojo下面去了,应该配置mapper.在mybatis-config里面也是这个路径。
错误:在测试的时候老是报错,说找不到某个实体类。
原因:在mapper.xml里面使用resultType=“” 的时候,应该是这个实体类的全名,包括包名,如果没有这么写,那么就需要取别名才行!