8.使用注解开发
8.1面向接口编程
8.1.1大部分开发用接口的原因就是:
- 解耦,可拓展,提高复用,分层开发,上层不用管具体的实现,大家都遵守共同的标准,使得开发变得更容易,规范性更好。
- 接口更深的理解就是定义(规范和约束)和实现的分离。
- 架构师只写一个接口,而你只管实现,这就是接口与实现的分离。
- 接口本身反映了系统设计人员对系统的抽象理解。
- 接口有两类:
- 一是对一个个体的抽象,它可成为一个抽象体。abstract class
- 二是对一个个体某一方面的抽象,形成一个抽象面。interface。
- 一个个体可能有多个抽象面,抽象体和抽象面是有区别的。
8.1.2三个面向对象
面向对象:我们考虑的问题,是以对象为单位,考虑它的属性和方法。
面向过程:我们考虑问题,以一个具体的流程为单位,考虑它的实现。
接口和非接口的设计:和面向对象和面向过程不是一个问题,更多是考虑整体的架构。
8.2mybatis注解—简化开发
1.接口上定义注解开发的sql
//使用注解开发
public interface UserMapper {
@Select("select * from user")
List<User> getUsers();
}
2.在mybatis配置文件mybatis-config.xml中的mappers,获取定义注解的接口
<!--之前使用xml开发,需要绑定mapper.xml
现在使用注解开发需要绑定接口(我们在接口上面写的注解)
-->
<mappers>
<mapper class="com.kuang.dao.UserMapper"></mapper>
</mappers>
3.测试
@Test
public void getUsers(){
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();
}
小结:
本质,使用了反射机制
底层,使用动态代理
使用注解开发,虽然不用在配置UserMapper.xml文件,简化了开发,但是对于复杂的sql语句的执行,注解并不能做到。
所以,在UserMapper.xml是万能的。但是配置相对麻烦。
在mybatis-05中,由于字段名和属性名不一致,注解开发就没有读取到数据库中pwd的字段信息。
log日志
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 1320677379.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4eb7f003]
==> Preparing: select * from user
==> Parameters:
<== Columns: id, name, pwd
<== Row: 1, 李一, 123456
<== Row: 2, 李二, 222
<== Row: 3, 李三, 12345
<== Row: 4, 李四, 123456
<== Row: 5, 李五, 123456
<== Row: 6, 李六, 123456
<== Total: 6
User{id=1, name='李一', pwd='null'}
User{id=2, name='李二', pwd='null'}
User{id=3, name='李三', pwd='null'}
User{id=4, name='李四', pwd='null'}
User{id=5, name='李五', pwd='null'}
User{id=6, name='李六', pwd='null'}
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4eb7f003]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4eb7f003]
Returned connection 1320677379 to pool.
8.3mybatis执行流程详解
Resources获取加载全局配置文件---->实例化SqlSessionFactoryBuilder构造器------>解析文件流XMLConfigBuilder——->configuration所以的配置信息------>SqlSessionFactory实例化——>-transactional事务管理器----->创建exector执行器----->创建SqlSession—–>实现增删改查
如果增删改查失败,就回滚到事务管理器,如果成功就提交事务。
8.4注解实现增删改查
注解来简化开发,只能用于简单的SQL语句,对于复杂的,它没办法解决,还是得用xml配置sql。
自动提交事务
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession(true);
//当这里为true时,自动提交事务
}
1.接口的增删改查
//方法有多个参数时,所有的而参数必须在前面加入@Param("")注解,这里才是把参数传递给数据库的参数
@Select("select * from user where id=#{id}")
User getUserById(@Param("id") int id);
//这里是对象类型不用param,
@Insert("insert into user(id,name,pwd) values(#{id},#{name},#{password})")
int addUsers(User user);
//修改
@Update("update user set pwd=#{password} where id=#{id}")
int updateUser(@Param("id") int id,@Param("password") String password);
//删除,这里是把@param这个参数传给SQL的
@Delete("delete from user where id=#{deleteId}")
int deleteUser(@Param("deleteId") int id);
方法有多个参数时,所有的而参数必须在前面加入@Param("")注解,这里才是把参数传递给数据库的参数
测试
@Test
public void getUsers(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//查询
// List<User> users = mapper.getUsers();
// for (User user:users
// ) {
// System.out.println(user);
// }
//更具账号查询
// User userById = mapper.getUserById(1);
// System.out.println(userById);
//添加
// mapper.addUsers(new User(7, "李六", "123456"));
//修改
// mapper.updateUser(7,"777777");
//删除
mapper.deleteUser(7);
sqlSession.close();
}
@param注解
- 在使用@Param时,参数类型或者String,需要加上
2.引用类型不用加,对象不用加
3.如果只有一个基本类型的话,可以忽略,建议加上
4.我们在SQL中引用的就是我们这里的Param的属性值。
**#{}和${}**的区别
1.建议#{},可以防止SQL注入,更加安全。