Java的单例模式与延时加载

Java的单例模式与延时加载,讲解的非常好

java单例模式与延时加载


附上代码:

public class Singleton {

	private Singleton() {
	}

	private static class SingletonHolder{
		static Singleton instance =  new Singleton();
	}
	
	public Singleton getInstance(){
		return SingletonHolder.instance;
	}
	
}


### Java MyBatis 延迟加载的实现用法 #### 配置延迟加载 MyBatis 提供了全局配置选项来启用或禁用延迟加载。通过在 `Configuration` 类中设置 `lazyLoadingEnabled` 属性为 `true`,可以开启全局的延迟加载功能[^4]。此外,还可以通过设置 `aggressiveLazyLoading` 属性来控制是否在方法调用时加载所有属性,或者仅按需加载特定属性。 ```xml <settings> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings> ``` 上述配置启用了延迟加载,并且设置了非激进模式,即每个属性将按需加载而不是一次性加载所有关联数据[^4]。 #### 实现机制 MyBatis 的延迟加载是基于动态代理和反射机制实现的。当一个对象被标记为延迟加载时,MyBatis 会创建一个代理对象。这个代理对象会在实际访问关联属性时触发 SQL 查询以加载数据[^3]。具体来说,当用户尝试访问某个延迟加载的属性时,代理对象会拦截该访问并执行相应的查询操作。 #### 使用方法 在使用 MyBatis 的延迟加载时,可以通过 XML 映射文件或注解的方式来定义关联关系。以下是一个基于 XML 的示: ```xml <resultMap id="userResultMap" type="User"> <id property="id" column="user_id"/> <result property="name" column="user_name"/> <association property="profile" javaType="Profile" select="selectProfile" column="user_id" fetchType="LAZY"/> </resultMap> <select id="selectUser" resultMap="userResultMap"> SELECT * FROM users WHERE id = #{id} </select> <select id="selectProfile" resultType="Profile"> SELECT * FROM profiles WHERE user_id = #{userId} </select> ``` 在这个子中,`profile` 属性被配置为延迟加载。只有当代码显式访问 `user.getProfile()` 时,才会触发对 `selectProfile` 查询的调用[^2]。 如果使用注解方式,则可以通过 `@One` 或 `@Many` 注解来定义延迟加载的关联关系: ```java public class User { private Integer id; private String name; @One(select = "com.example.mapper.ProfileMapper.selectProfile", fetchType = FetchType.LAZY) private Profile profile; // getters and setters } ``` 上述代码片段展示了如何通过注解的方式定义一个延迟加载的一对一关系[^5]。 #### 注意事项 - 延迟加载可能会导致 N+1 查询问题。因此,在设计查询时需要权衡是否使用延迟加载。 - 确保数据库连接在延迟加载发生时仍然可用,否则可能会引发异常。 - 如果某些属性总是需要一起加载,考虑使用预加载(eager loading)以避免多次查询带来的性能开销。 #### 示代码 以下是一个完整的示,展示了如何在 MyBatis 中配置和使用延迟加载: ```java @Mapper public interface UserMapper { @Select("SELECT * FROM users WHERE id = #{id}") @Results({ @Result(id = true, property = "id", column = "user_id"), @Result(property = "name", column = "user_name"), @Result(property = "profile", column = "user_id", one = @One(select = "selectProfile", fetchType = FetchType.LAZY)) }) User selectUserById(int id); @Select("SELECT * FROM profiles WHERE user_id = #{userId}") Profile selectProfile(int userId); } ``` ```java public class UserService { @Autowired private UserMapper userMapper; public void getUserWithProfile(int id) { User user = userMapper.selectUserById(id); System.out.println(user.getName()); // 不会触发 profile 加载 System.out.println(user.getProfile().getDetail()); // 触发 profile 加载 } } ``` ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值