框架笔记
1、环境搭建
-
创建dao包和domain
-
在resoure下创建sqlMapconfigxml文件,进行配置,xml用resource 而注解用class
<mappers>
<mapper resource="com/wei/dao/IUserDao.xml"/>
</mappers>
-
在resource创建与dao对应的映射文件
-
具体步骤
1. 读取配置文件
2. 获取工厂
3. 获取sqlsession对象
4. 获取dao对象
5. 调用dao中的方法
6. 释放资源
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapconfig.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory build = sqlSessionFactoryBuilder.build(resourceAsStream);
SqlSession session = build.openSession();
IUserDao mapper = session.getMapper(IUserDao.class);
List<User> all = mapper.getAll();
System.out.println(all);
resourceAsStream.close();
session.close();
2、进行CRUD
常用的注解
@before:初始化操作
@after: 销毁操作
InputStream inputStream = Resources.getResourceAsStream("SqlMapconfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);
SqlSession session = factory.openSession();
IUserDao iUserDao = session.getMapper(IUserDao.class);
User user = new User();
user.setId(47);
user.setUsername("lisi");
user.setBirthday(new Date());
user.setSex("男");
user.setAddress("广西");
iUserDao.saveUser(user);
session.commit();
inputStream.close();
session.close();
-
查询所有
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapconfig.xml"); SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); SqlSessionFactory build = sqlSessionFactoryBuilder.build(resourceAsStream); SqlSession session = build.openSession(); IUserDao mapper = session.getMapper(IUserDao.class); List<User> all = mapper.getAll(); System.out.println(all); resourceAsStream.close(); session.close();
-
根据id查找
//加载配置文件 InputStream inputStream = Resources.getResourceAsStream("SqlMapconfig.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(inputStream); SqlSession session = factory.openSession(); IUserDao mapper = session.getMapper(IUserDao.class); User user = mapper.findById(47); System.out.println(user); session.close(); inputStream.close();
-
模糊查询
like ${value} 这是固定写法
-
在一个对象中封装另一个对象,进行查询
例如 query对象中封装user class query{ private User user; } <select id = "" parameterType="query" resultType = "User"> select * from user where username = #{user.name}; </select>
3、返回值深入
-
当domain中的属性字段和数据库中的不一样时,有两种解决方法
1.从sql语句中修改,例如: select id as Id,userName as username from table 2.从mybatis角度,利用resultMap <resultMap id="userMap" type = "com.wei.domain.User"> //这是主键,用<id></id>标签 <id property = "userId" colume = "id"></id> //下面是非主键,用<result></result>标签 <result property = "userName" column = "username"></result> </resultMap>
properties标签细节
属性:
resource 常用
url 属性
typeAliases标签
只能在domain中定义别名
<typeAliases>
<typeAlias type = "com.wei.domain.user" alias = "user">
<package name = "com.wei.domain"></package> //直接导包,不用指定具体的类了
</typeAliases>
连接池介绍以及事务控制
-
连接池
-
mybatis中的事务
- 什么是事务
- 事务的四大特性
- 不考虑隔离会产生的三个问题
基于xml的动态sql
-
if 标签
<select id="findByCondition" resultType="com.wei.domain.User" parameterType="com.wei.domain.User"> select * from user where 1 = 1 <if test="username != null"> and username = #{username}; </if> //这里的与条件不能使用符号 “&&” 这是java中的,要使用 and <if test="author != null and author.name != null"> AND author_name like #{author.name} </if> </select>
-
where 标签
当使用where标签的时候,就不用再sql语句中加上 where 1 = 1 select * from user <where> <if test="username != null"> and username = #{username}; </if> //这里的与条件不能使用符号 “&&” 这是java中的,要使用 and <if test="author != null and author.name != null"> AND author_name like #{author.name} </where> </if>
-
foreach 标签
SELECT * FROM POST P WHERE ID in <foreach item="item" index="index" collection="list" open="(" separator="," close=")"> #{item} </foreach> foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能! 提示 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。
-
sql标签 (了解)
抽取重复的sql语句
mybatis中的多表查询
-
一对一
其实就是要想方设法的构造出能够匹配的实体类,并且利用mybatis中的一些标签来实现这个结构,例如一个需求是这样的:有两张表,一张是账户表account,有id,uid(用户的id),money,另一张是 用户表user有id,name,password.现在想要查询账户中的信息和用户中的信息,这就是要同时显示 id uid,money,name,password. 通过sql语句来返回这些数据,所以要构造出一个实体类accountuser来接受这些返回值,用这个实体类来做返回类型.
- 第一种方法
<select id = "method" resultType= "accountuser"> select a.*,u.name,u.password from account as a,user u where a.uid = u.id </select>
-
第二种方法 (不爱用这个),就是这个类包含其他类的引用或者是类引用
利用resultMap来封装。想法就是再accoun表中加入user的引用,然后,利用resultMap进行封装
<resultMap type= "account" id = "accountMap"> //这是主键的配置,用id标签 <id column="aid" property="id"></id> //这是非主键的配置,用result标签 <result column = "uid" property = "uid"> </result> //配置相关的引用,用association标签 <association property = "user" javaType="user"> <id></id> <result></result> </association> </resultMap>
-
多对一
“多”中有“一”的类引用
-
一对多
“一”中有“多”的集合引用作为属性
-
多对多
各自包含各自的一个集合引用,在sql中的体现就是,用两次左外连接,或者是两次右外连接,既然在类中加入了引用,那么就要使用resultMap来做
<resultMap> <id></id> <result></result> //引用的配置用collection标签,而类引用用association <collection> <id></id> <result></result> </collection> </resultMap>
延迟加载
1、概念
延迟加载:在真正使用数据时,才查询出来,也叫按需查询,一对多和多对多都是使用这种加载。
立即加载:多对一,和一对一,都是采用立即加载,不管用不用,都查询出来
操作
-
在SqlMapConfig.xml中添加延迟加载的配置
- aggressiveLazyLoading:开启时,任一方法的调用都会加载该对象的所有延迟加载属性。 否则,每个延迟加载属性会按需加载
- lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置
fetchType
属性来覆盖该项的开关状态
<settings> <setting name = "lazyLoadingEnabled" value= "true"></setting> <setting name = "aggressiveLazyLoading" value "false"></setting> </settings>
-
可以在collection标签中,使用 select 属性来标识要延迟加载的方法,
- select 属性:填写的值是映射的sql语句的id
- column:参数的来源,例如来源于user中的属性id,就写这个字段名
<collection property = "com..domain.account" ofType = "account" select ="com..dao.IAccountDao.findByUid" column="id"> </collection>
缓存
1、什么是缓存
存在于内存中的临时数据
2、为什么使用缓存
减少和数据库交互的次数,提高效率
3、什么样的数据能使用缓存,什么样的不能
适用:经常查询但是不经常改变,数据的正确与否对最终结果影响不大
4、一级缓存和二级缓存
一级:指的是mybatis中的SqlSession级别的缓存,只有SqlSession没有flush或者是close,它就存在
二级:指的是mapper映射级别的缓存,多个SqlSession去操作同一个Mapper映射的sql语句,多个sqlsession可以公用二级缓存,二级缓存是跨sqlsession的。
使用步骤:
-
在SqlMapconfig.xml中开启设计
<settings> <setting name = "cacheEnabled" value = "true"></setting> </settings>
-
配置相关的Mapper映射文件
<mapper namespace = "com.wei.dao.IUserDao"> <cache> </cache> </mapper>
- 配置语句上面的useCache属性
- 注意点:使用二级缓存时,必须要实现Serializable接口,可以使用序列化方式来保存对象
<select id = "" resultType = "" parameterType= "" useCache = "true"> select * from user where id = #{id}; </select>
注解开发
-
环境搭建
-
CRUD
注意点: 如果使用了注解,那就用注解,不要一个用注解,一个用xml
@Select
@Insert
@Update
@Delete
-
多表查询
一对一:一个类中包含另一个类的引用,使用注解配置
@Results注解代替的是标签
@Select("select * from user") @Results(id ="userMap" value = { @Result(id = true,property = "userid"), @Result(column = "username" ,property = "username") }) List<User> findAll();
而在注解中,如何使用一对一呢,可以使用@one注解
在Result中有
id标签:是否是主键字段
column:数据库的列名
property: 需要配置的属性名
one: 需要使用的@one注解
many:需要使用的@Many注解
@Select("select * from user") @Results(id ="userMap" value = { @Result(id = true,property = "userid"), @Result(column = "username" ,property = "username"), //一对一的配置 @Result(column ="uid" property = "user",one =@One(select = "com.wei.dao.IUserDAo.findById"),fetchType=FetchType.LATY) }) List<User> findAll();
-
缓存配置
一级缓存默认都是开始的
开启二级缓存的步骤
-
在SqlMapConfig中开启缓存支持
<settings> <setting name = "cacheEnabled" value ="true"></setting> </settings>
-
在dao层中使用注解配置二级缓存
@CacheNamespace(blocking= true)
-