Mybatis第二天
一、回顾
1. 自定义框架 -- 架构师
2. mybatis 的入门
1) 添加依赖 mybatis-3.4.5.jar
2) 核心配置文件:SqlMapConfig.xml -- 四个属性, 引入映射文件
3) XXXXMapper.xml -- sql ,mapperId , resultType , parameterType
4) javaBean -- 所有的java类都是bean对象
pojo :简单java对象, 一般只有属性,属性的set和get方法
5) 测试
SqlSessionFactoryBuilder -- SqlSessionFactory -- SqlSession(增删改查)
二、教学目标
1、mybatis实现CRUD
2、两种Dao开发
3、核心配置文件详解
4、输入参数和输出参数
三、mybatis实现CRUD
- mybatis 的中文文档网址:http://www.mybatis.org/mybatis-3/zh/getting-started.html
- selectList 查询多个对象,返回一个list集合(也能查询一个)
selectOne: 查询单个对象,返回一个对象 - 日志记录日常操作
引入依赖:
引入日志的配置文件:log4j.properties<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
【注意】这里面rootCategory 后面的 debug是指显示debug信息,console指控制台打印、logfile日志文件可以输出、info指初始化信息显示
log4j.appender.LOGFILE.File=d:\axis.log ——日志文件
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE, info
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
- 增删改查
id=“findById”:唯一的标识
resultType=“com.itheima.domain.User” :返回值类型
parameterType:参数类型
<!--UserMapper删除操作-->
<delete id="del" parameterType="java.lang.Integer">
delete from user where id = #{id}
</delete>
<!--测试类-->
@Test
public void testDel(){
//获取输入流对象
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("SqlMapConfig.xml");
//获取SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象
//获取的sqlsession不能自动提交
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行sql语句
sqlSession.delete("userMapper.del",3);
//提交:只要修改了数据库必须提交
sqlSession.commit();
sqlSession.close();
}
- 模糊查询
参数: %a%
配置文件: username like #{username}
参数: a
配置文件1: username like “%”#{username}"%"
配置文件2: username like "% v a l u e 如 果 传 的 是 简 单 类 型 必 须 使 用 v a l u e 如 果 是 p o j o , 属 性 名 引 用 d 、 参 数 简 单 类 型 : 基 本 数 据 类 型 , S t r i n g 如 果 {value}%" 如果传的是简单类型必须使用value 如果是pojo,属性名引用 d、参数 简单类型: 基本数据类型,String 如果 value如果传的是简单类型必须使用value如果是pojo,属性名引用d、参数简单类型:基本数据类型,String如果{} 必须用value引用
如果#{} 随便写
pojo类型:属性名引用
e、${} 与 #{}区别
${}:直接拼接,不会转换类型, 不能防注入
#{}:转换类型后拼接, 相当于占位符?,可以防注入
1.2 Mybatis解决原生jdbc编程的问题
1、频繁创建、释放数据库连接造成系统资源浪费,影响系统性能。使用数据库连接池技术可以解决此问题。
解决:在SqlMapConfig.xml中配置数据连接池,使用连接池管理数据库连接。
2、Sql语句写在代码中造成代码不易维护,实际应用中Sql变化的可能较大,Sql变动需要改变java代码。
解决:将Sql语句配置在XXXXmapper.xml文件中与Java代码分离。
3、向Sql语句传参数麻烦,因为Sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应(硬编码)。
解决:Mybatis自动将Java对象映射至Sql语句,通过statement中的parameterType定义输入参数的类型。
4、对结果集解析麻烦(查询列硬编码),Sql变化会导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成Pojo对象解析比较方便。
解决:Mybatis自动将Sql执行结果映射至Java对象,通过statement中的resultType定义输出结果的类型。
2.2SqlSession使用分析
SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等。
通过SqlSessionFactory创建SqlSession,而SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建。
SqlSessionFactoryBuilder用于创建SqlSessionFacoty,SqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder了,因为SqlSession是通过SqlSessionFactory生产,所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是方法范围即方法体内局部变量。
SqlSessionFactory是一个接口,接口中定义了openSession的不同重载方法,SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory。
SqlSession是一个面向用户的接口, sqlSession中定义了数据库操作方法。
每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的(因为SqlSession底层对应的是Connection连接)。因此最佳的范围是请求或方法范围。
四、两种Dao开发
1、传统dao开发
2、动态代理模式开发
【注意】
动态代理模式:规范必须遵守
namespace:必须是对应接口的全限类名
select|update|insert|delete: 四个标签 id必须对应dao接口的方法名
!--
动态代理模式:规范必须遵守
namespace:必须是对应接口的全限类名
select|update|insert|delete: 四个标签 id必须对应dao接口的方法名
-->
<mapper namespace="com.itheima.dao.UserDao">
<select id="findAll" resultType="com.itheima.domain.User">
select * from user
</select>
@Test
public void testFindAll(){
SqlSession sqlSession = sessionFactory.openSession();
//获取Dao接口的动态代理对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> userList = userDao.findAll();
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
五、核心配置文件详解
1. 配置文件中的标签和顺序
properties?, 配置属性(学习)
settings?, 全局配置:缓存,延迟加载
typeAliases?, 类型别名(学习)
typeHandlers?, 类型转换(操作)(了解)
objectFactory?, objectWrapperFactory?, reflectorFactory?, 类型工厂,一般不用
plugins?, 插件:分页插件
environments?, 环境配置(数据源)
databaseIdProvider?,
mappers? 引入映射配置文件(学习)
? : 一个或者零个
| : 任选其一
+ : 最少一个
* : 零个或多个
, : 必须按照此顺序编写
properties(可以给环境配置调用)
可以在外部单独新建一个配置文件,方便使用者修改;
也可以在xml文件里添加
${jdbc.driver}:ognl表达式
在xml中没有el表达式
<!--属性配置-->
<!--<properties>-->
<!--<property name="jdbc.driver" value="com.mysql.jdbc.Driver"></property>-->
<!--<property name="jdbc.url" value="jdbc:mysql://localhost:3306/mybatisdb_331"></property>-->
<!--<property name="jdbc.username" value="root"></property>-->
<!--<property name="jdbc.password" value="root"></property>-->
<!--</properties>-->
<!--引入外部属性文件-->
<properties resource="jdbc.properties"></properties>
typeAliases 别名(mapper里就可以简写)
可以直接引入一个包,然后该包内的所有类都可以用简单类名来表示
<!--类型别名映射-->
<typeAliases>
<!--单个类型映射-->
<!--<typeAlias type="com.itheima.domain.User" alias="user"></typeAlias>-->
<!--包的映射:引入该包中所有的pojo类型,配置别名: 简单类名(不区分大小写)-->
<package name="com.itheima.domain"></package>
</typeAliases>
从而下面的mapper可以简化
<mapper namespace="com.itheima.dao.UserDao">
<select id="findAll" resultType="USer">
select * from user
</select>
<insert id="save" parameterType="com.itheima.domain.User">
insert into user values(null ,"${username}",#{password},#{sex},#{address},#{birthday})
</insert>
</mapper>
mappers引入映射配置文件
<mappers>
1. <!--引入UserMapper.xml配置文件-->
<!--<dao resource="com/itheima/dao/UserDao.xml"/>-->
2. <!--引入UserMapper的配置文件:url:绝对路径-->
<!--<mapper url="file:///F:\ideaworkspace\……\UserDao.xml"></mapper>-->
3. <!--引入UserDao接口
通过接口引入配置:
前提:必须在同一个包中
文件名称必须一致
-->
<!--<mapper class="com.itheima.dao.UserDao"></mapper>-->
4. <!--
通过接口引入配置:
前提:必须在同一个包中
文件名称必须一致
-->
<!--引用一个包中的所有dao接口-->
<package name="com.itheima.dao"></package>
</mappers>
nfiguration>
六、输入参数类型和输出参数类型
VO——value object 值对象:用来存储参数值
1. 输入参数
简单类型: 基本数据类型+ String类型
#{} :名称随便
${} :${value}
pojo 类型
#{} :${} : 属性名引用
包装对象类型 (这里就是项目里的VO)
引用 #{属性.属性名}
Map集合
引用: #{key}
多个参数
引用时:#{param1},#{param2}.....#{paramN}
2. 返回值类型(也在mapper里)
如果列与属性名不一致,对应的属性为null, 必须写映射配置
如数据库里是uid,而domain里的User里是id
<!--resultMap:结果映射:一般用户列名与属性名不一致的情况-->
<!--
id="":唯一的标识
type="":返回值的类型
-->
<resultMap id="userList" type="user">
<!--
id:一般写主键的映射
property: 属性名
column: 列名
-->
<id property="id" column="uid"></id>
<!--映射其他属性和列-->
<result property="username" column="uname"></result>
</resultMap>
---
<select id="findAll" resultMap="userList">
select * from user
</select>
七、总结