01_MyBatis注解开发
这几年来注解开发越来越流行,MyBatis也可以使用注解开发方式,这样就可以减少编写
Mapper映射文件了。MyBatis常用注解
@Insert:实现新增
@Update:实现更新@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
02_MyBatis注解操作CRUD
@Insert、@Update、@Delete、@Select
DAO接口
public interface IEmployeeDao {
@Select("select * from tb_employee")
List < Employee > selectEmployeeList();
@Insert("insert into tb_employee(ename,salary,dno) values(#{ename},#{salary},#
{dno})")
int insertEmployee(Employee employee);
@Delete("delete from tb_employee where eid = #{eid}")
int deleteEmployeeById(Long id);
@Update("update tb_employee set ename = #{ename} where eid = #{eid}")
int updateEmployee(Employee employee);
}
代码测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:/spring.xml"}
)
public class IEmployeeDaoTest {
@Resource
private IEmployeeDao employeeDao;
@Test
public void selectEmployeeList() {
List<Employee> employeeList = employeeDao.selectEmployeeList();
System.out.println(employeeList);
}
@Test
public void insertEmployee() {
Employee employee = new Employee();
employee.setEname("邱邱");
employee.setSalary(10000.0);
employee.setDno(1L);
int i = employeeDao.insertEmployee(employee);
System.out.println(i);
}
@Test
public void deleteEmployeeById() {
int i = employeeDao.deleteEmployeeById(0L);
System.out.println(i);
}
@Test
public void updateEmployee() {
Employee employee = new Employee();
employee.setEid(2L);
employee.setEname("qzw");
int i = employeeDao.updateEmployee(employee);
System.out.println(i);
}
}
03_复杂关系映射注解说明
实现复杂关系映射之前我们可以在映射文件中通过配置
复杂关系映射的注解说明
@Results 注解
代替的是标签
该注解中可以使用单个@Result 注解,也可以使用@Result 集合@Results({@Result(), @Result() })或@Results(@Result())
@Result 注解
代替了
@Result 中 属性介绍:
id 是否是主键字段
column 数据库的列名
property 需要装配的属性名
one 需要使用的@One 注解(@Result(one=@One)()))<br /> many 需要使用的@Many 注解(@Result(many=@many)()))<br />@One 注解(一对一)<br /> 代替了<assocation>标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。<br /> @One 注解属性介绍:<br /> select 指定用来多表查询的 sqlmapper<br /> fetchType 会覆盖全局的配置参数 lazyLoadingEnabled。<br />。使用格式:<br /> @Result(column=" ",property="",one=@One(select=""))<br />@Many 注解(多对一)<br /> 代替了<Collection>标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合。<br /> 注意:聚集元素用来处理“一对多”的关系。需要指定映射的 Java 实体类的属性,属性的javaType (一般为 ArrayList)但是注解中可以不定义;<br /> 使用格式:<br /> @Result(property="",column="",many=@Many(select=""))
04_注解实现一对一延迟加载
一个订单属于一个用户
IOrderDao代码
@Select("select * from tb_orders")
@Results(id = "resultMap",value = {
@Result(id = true , property = "customerId" ,column = "customerId",javaType = Long.class),
@Result(property = "name" , column = "name" ,javaType = String.class ),
@Result(property = "address" ,column = "address",javaType = String.class),
@Result(property = "customer", javaType = Customer.class,
one = @One(select = "com.qzw.dao.ICustomerDao.selectCustomerById",
fetchType = FetchType.EAGER), column = "customerNo")
})
List<Order> selectOrderList();
ICustomerDao代码
@Select(value = "select * from tb_customer where customerId = #{customerId}")
Customer selectCustomerById(Long customerId);
05_注解实现一对多延迟加载
一个用户有多个订单
ICustomerDao代码
@Select(value = "select * from tb_customer") @Results(id = "resultMap",
value = {
@Result(id = true,property = "orderId",column = "orderId",javaType = Long.class),
@Result(property = "state",column = "state",javaType = String.class),
@Result(property = "orderList",column = "customerId", many = @Many(select="com.qzw.dao.IOrderDao.selectOrderListByCustomerId",fetchType = FetchType.LAZY))
}
)
List<Customer> selectCustomerList();
IOrderDao代码
@Select("select * from tb_orders where customerNo = #{customerNo}")
List<Order> selectOrderListByCustomerId(Long customerId);
06_ @lazy注解
1、@Lazy注解是什么
@Lazy注解用于标识bean是否需要延迟加载,源码如下:
@Target({
ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.FIELD
})@ Retention(RetentionPolicy.RUNTIME)@ Documented
public@ interface Lazy {
/**
* Whether lazy initialization should occur.
*/
boolean value() default true;
}
只有一个参数,默认是true,也就是说只要加了这个注解就会延迟加载
2、@Lazy注解怎么使用
没加注解之前主要容器启动就会实例化bean,如下:AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(MainConfig.class);
而加上@Lazy注解则必须在第一次调用的时候才会加载如下:
/**
* 定义一个bean对象
* @return
*/
@Scope@ Lazy@ Bean(value = "user0", name = "user0", initMethod = "initUser", destroyMethod = "destroyUser")
public User getUser() {
System.out.println("创建user实例");
return new User("张三", 26);
}
@Lazy注解注解的作用主要是减少springIOC容器启动的加载时间
解决循环依赖冲突
07_@dependsOn注解
指定在注入一个bean之后再注入此bean
注解在@Bean
定义方法上
该例子使用方法方式定义了一个bean entityManager
,并指出它依赖于bean transactionManager
。虽然bean entityManager
实例化过程中没有通过属性或者构造函数参数方式依赖于bean transactionManager
,但是其过程中会牵涉到对transactionManager
的使用,如果此时transactionManager
没有被实例化,entityManager
的实例化过程会失败。这就是一种典型的不通过属性或者构造方法参数方式依赖,但是实际上存在依赖的情况,这种情况正是注解@DependsOn
的用武之地。
@Bean(name = "entityManager")@ DependsOn("transactionManager")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws Throwable {
LocalContainerEntityManagerFactoryBean entityManager =
new LocalContainerEntityManagerFactoryBean();
// 省略无关的实现部分
// ...
return entityManager;
}