一、连接池
1.1
连接池是面向数据库连接的
连接池是为了优化数据库的连接资源
1.2 mybatis中的连接池
在Mybatis中我们将它的数据源DataSource分为
①、UNPOOLED 不使用连接池的数据源
会为每一个数据库操作创建一个新的连接,并关闭它。该方式使用于只有小规模数量并发用
户的简单应用程序上。
②、POOLED 使用连接池的数据源
会创建一个数据库连接池,连接池中的一个连接会被用做数据库操作。一旦数据库操作完
成,Mybatis会将此连接返回给连接池。在开发或测试环境中,常用此方式。
③、JNDI 使用 JNDI 实现的数据源
Mybatis从在应用服务器向配置好的JNDI数据源dataSource获取数据库连接。在生产环境
中优先考虑这种方式
源码分析:
①UNPOOLED 不用连接池
第一次进行加载驱动的初始化
获取连接
事物级别的设置、自动提交的配置
返回coon对象
②POOLED 使用连接池
获取coon对象时的步骤:
第一步:判断空闲的集合是否为空,如果不为空就返回最早创建的coon对象
第二步:判断活跃集合中的conn对象数量是否最大,如果小于最大值就创建coon
第三步:获取最早的那个活跃的coon对象的时间看是否超时,若超时就移除, 移除后创建一个coon对象
第四步:线程等待
使用完后coon对象的走向:
每次我们使用的coon对象不是真正的coon,而是代理的一个coon,当我们调 用close方法时,其实不会关闭资源,而是将使用完后的coon放到了连接池 中
二、PageHeiper插件的使用
1、导入jar包
2、在mybatis-config.xml中配置插卡
<plugins>
<plugin interceptor ="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
3、在查询的结果集前,传入我们要分页的参数
PageHeiper.offsetPage(起始值,分页单位);
4、在查询结果集合之后创建PageInfo对象并传入查询出的集合
PageInfo pageInfo = new PageInfo(plist);
5、使用pageinfo对象直接getTotal()获取总条数
四、 事务的自动提交
//这是事务的提交方式为自动提交
SqlSession session = sessionFactory.openSession(true);
//默认是flase 不自动提交需要手动的commit,将所有的更新动作当做是一个事务处理;
//如果其中某个操作有异常那么所有的事务都会回滚
// true 自动提交 每个操作视为一个事务 ,只要有事务可以顺利提交那么不影响其他的事
五、事务的隔离级别设置
脏读:一个事物读取一条数据,这条数据被另一条事物回滚
重复读:一个事物读取一条数据,再次读取发现数据被更改
幻读:一个事物查询一条数据,再次查询发现多了一条
read uncommited 读取未提交
read commited 读取提交的数据
repeatable 可以重复读
serialize 序列化 串联操作
SqlSession session =
sessionFactory..openSession(TransactionlsolationLevel.READ_COMMITED);
六、懒加载
1、配置懒加载
<settings>
<setting name="lazyLoadingEnaled" value="true"/>
<setting name="aggresslazyLoading" value="false"/>
</settings>
2、mapper.xml
<resultMap type="Category" id="categoryBean2" autoMapping="true">
<id column="id" property="id"/>
<result column="name" property="name"/>
<collection property="products" ofType="Product" column="id" select="query" autoMapping="true"/>
<select id="lazyLoadingEnaled" resulyMap="categoryBean2" parameterType="int">
select * from t_category where id =#{id}
</select>
<select id="query" reslutMap="Product" parameterType="int">
select * from t_product where cid =#{id}
</select>
七、注解关联查询
一对多
public interface CategoryMapper{
@Select("select * from t_category where id =#{id}")
@Result({
@Result(id = true,column = "id",property = "id"),
@Result(column = "name",property = "name"),
@Result(property = "products" , javaType = List.class ,column="id",
many = @Many(select="tledu.dao.ProductMapper.getListById")
)
})
public Category getCategoryById(int id);
}
public interface ProductMapper{
@Select("select * from t_product where cid =#{id}")
public List<Product>getListByld(int id);
}
多对一
public interface ProductMapper{
@Select("select * from t_product where id =#{id}")
@Result({
@Result(proprty = "category",javaTypr = Categroy.class,column = "id",
one=@One(select="com.tledu.dao.CategoryMapper.getCategoryById")
)
})
public Category geProuductByIdById(int id);
}
public interface CategoryMapper{
@Select("select * from t_category where cid =#{id}")
@Results({
@Result(id=true,column="id",property="id"),
@Result(column="name",property="name"),
@Result(property = "products" , javaType = List.class ,column="id",
many = @Many(select="tledu.dao.ProductMapper.getListById")
})
public Category getCategory Byld(int id);
s八、缓存策略
一级缓存
在sqlSession中
默认开启,只要在同一个sqlSession中那么同样的查询条件就会从缓存中取出
销毁、刷新、close commit ,一级缓存一直存在
sqilSession。clearCache()清除一级缓存
二级缓存
SQLSessionDactory
1、在配置文件中配置缓存
<setting name="cacheEnabled" value="true"/>
2、实体类实现序列化接口
Public class Category implements Seriallizable{
3、在要缓存的mapper.xml中添加<cache/>标签,表示当前mapper使用缓存
<mapper namespace="com.tledu.pojo">
<cacahe/>
<resultMap id="categoryBean" type="Category">....
4、测试
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder.build(inputStream);
SqlSession session = sessionFactory.openSession();
session.selectOne("getProductById",2);
session.commit();
session.close();
SqlSession session2 = sessionFactory.openSession();
session2.selectOne("getProductById",2);
session2.commit();
session2.close();
sessionFactory.getConfiguration().getCache("缓存所在的mapper.xml的namespace").clear();//二级缓存清除