MyBatis 框架
数据持久层框架(DAO将数据持久化到数据库),实现DAO层的代码。对JDBC代码的封装。
特点:
①封装通用功能,简化代码,提高开发效率(获得conn,绑定参数,发送sql,处理异常,处理结果集)
②sql放在配置文件中,提高sql可维护性。
③自带连接池功能
④自带缓存(提高查询效率) [重点]
1).第一个MyBatis程序
核心编程思想
①书写DAO接口
②开发Mapper文件
SQL+绑定的参数===实现接口中的方法。
环境搭建
1. 导入jar。
1. 导入mybatis的jar
2. 导入oracle的驱动jar
3. 导入mybatis依赖lib的jar。
2. 引入配置文件:
mybatis-config.xml(连接数据库相关的参数)
driverClassName oracle.jdbc.OracleDriver
url jdbc:oracle:thin:@localhost:1521:xe
username hr
password hr
transactionManager 连接池(POOLED/UNPOOLED)
XxxMapper.xml(相当于dao的实现类)
3. 初始化配置
2).MyBatis实现DAO、以及重要的API
(1)实现DAO编程
① 写DAO接口
public interface PersonDAO{
void insert(Person person);
}
② 书写Mapper文件(DAO的实现类)[sql+参数]
<insert id="实现接口的方法名" parameterType="参数中实体类型全类名">
insert into t_person values(seq_person.nextval,#{属性名},#{sex},#{age},#{mobile},#{address})
</insert>
属性: id: 实现的接口的方法名
parameterType: 参数类型(实体的全类名)
sql语中绑定参数: #{属性名}
③ 注册管理mapper文件[在mybatis-config中配置]
<mappers>
<!-- 注册管理所有的mapper文件 -->
<mapper resource="com/baizhi/demo1/PersonDAOImpl.xml"></mapper>
</mappers>
resource: mapper文件相对于src的路径。
(2)重要API
目的:
使用DAO获得PersonDAO的对象、调用personDAO的方法。
常用的类:
sqlSession:
①获得dao接口的实现类的对象。
XxxDAO dao = sqlSession.getMapper(接口.class);
②相当于connection.[提交事务 关闭close,回滚事务]
SqlSessionFactory
①获得sqlSession
SqlSession session = sqlSessionFactory.openSession();
②保存封装mybatis-config.xml配置文件。
SqlSessionFactoryBuilder: 读取配置文件
Resources: 获得读取配置文件的输入流。
步骤:
①获得mybatis-config的输入流
②读取mybatis-config的文件,构造成SqlSessionFactory
③通过SqlSEssionFactory获得SqlSession
④通过SqlSession获得DAO接口的对象
⑥调用方法测试。
3).MyBatis-DAO接口的修改、删除、(模糊)查询、多参方法调用
(1)操作
①修改
a. 书写PersonDAO接口,声明修改的方法
public interfafce PersonDAO{
public void update(Person person);
}
b. 在Mapper通过标签实现方法
<update id="update" parameterType="Person的全类名">
update t_person set name = #{name},sex =#{sex},age=#{age},mobile=#{mobile},address=#{address} where id = #{id}
</update>
c. 注册mapper文件 [一个接口,对应一个mapper文件,注册一次]
②删除
a. 定义dao接口的方法
b. 书写mapper文件标签
c. 注册mapper文件。
限定参数绑定的名字
a.定义接口方法
public interface PersonDAO{ public void delete(@Param("指定参数绑定使用的名字")Integer id); }
b Mapper文件
<delete>delete from t_person where id = #{指定参数绑定使用的名字} </delete>
③查询
查询单个:
a. 书写DAO接口方法
public interface PersonDAO{ Person selectById(Integer id); }
b. mapper文件实现该方法(sql 参数 对查询结果映射实体对象)
<select id="selectById" parameterType="java.lang.Integer" resultType="一行数据映射实体对象类型
select id,name,sex,age,mobile,address from t_person where id = #{id}
</select>
c. 注册mapper文件
ResultType的作用:
作用: 映射查询结果的列封装成实体的属性
要求: 查询结果的列名必须和实体的属性名一致
注意:表列名和实体属性名不一致时,通过sql 的as起别名方式,使查询结果的列名和实体的属性名一致。
查询多个:
只需要明确单行数据映射的实体类型,MyBatis会自动讲每个数据封装的每个实体放入list集合中。
a. 书写DAO接口方法
public interface PersonDAO {List<Person> selectAll(); }
b. 书写mapper文件中的标签
<select id="selectAll" resultType="rs的一行数据映射实体类型">
select id,name,sex,age,mobile,address from t_person
</select>
c. 注册mapper文件
模糊查询:
<select id="selectByName" resultType="rs的一行数据映射实体类型" paramType=”java.lang.String”>
select * from t_person where name = ‘%’ || #{name} ||‘%’
或 select * from t_person where name = ‘%${name}%’
</select>
④多个参数(基本,包装,String):
方案一:
@Param给接口方法的参数起别名
public interface UserDAO {
User selectByUsernameAndPassword(@Param("username")String username,@Param("password")String password);
}
//可以不用写类型
select id,username,password from t_user where username = #{username} and password = #{password}
方案二:
绑定参数通过#{参数的序号从0开始}
注意:MyBatis的Mapper文件的sql书写 >或者 <
问题: 会发生转义
解决: 替换成转义字符
MyBatis注意事项总结:
①增删改必须要提交事务。(事务自动开启,手动提交模式)
②参数绑定情况
实体类型 #{属性名}
(单个参数)基本数据类型+包装类型+String #{随便}
没有参数 parameterType不用写
多个参数 可以起别名,可以按序号绑定
③mapper文件转义字符
sql的筛选条件: < ---> <
> ---> >
& ---> &
“ ---> "
© ---> '
eg: select * from t_user where id <= 1000; //选择id值不超过1000的用户信息
4).MyBatisUtil类的封装、MyBatis的使用技巧、以及日志
(1)MyBatisUtil类的封装
MyBatis核心API
SqlSession:
①相当于connection
sqlSession.commit();//提交事务
sqlSession.rollback();//回滚事务
sqlSession.close();//将连接还回连接池。
②获得XXxDAO接口的对象。
轻量级对象,每次操作创建一个新的。
比如: Action SqlSession Connection
③SqlSessionFactory
作用: 封装mybatis-config配置文件的信息。
重量级对象,web应用只创建一个。对象的创建消耗资源。
java代码:
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUtil2 {
private static SqlSessionFactory factory = null;
private static ThreadLocal<SqlSession> tdl = new ThreadLocal<SqlSession>();
static{
InputStream is = null;
try {
is = Resources.getResourceAsStream("mybatis-config.xml");
factory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {throw new RuntimeException("mybatis配置文件加载异常",e);
}finally{
if(is != null){
try { is.close();
} catch (IOException e) { e.printStackTrace(); }
}
}
}
/** 获得SqlSession */
public static SqlSession getSqlSession(){
SqlSession session = null; //1. 获得DAO对象 sqlSession
try {
session = tdl.get();
if(session == null){ //当前线程如果没有sqlSEssion
session = factory.openSession();
tdl.set(session); //将session存入当前线程
}
} catch (Exception e) {throw new RuntimeException("获得SqlSession的异常",e);}
return session;
}
/** 根据接口的类对象,获得dao的对象*/
public static <T> T getMapper(Class<T> clazz){
SqlSession session = getSqlSession(); //获得sqlSession
T t = session.getMapper(clazz); //调用session.getMapper(clazz);
return t;
}
/** 提交事务+释放资源*/
public static void commit(){
//sqlSession.commit();
try{
SqlSession session = getSqlSession();
session.commit();
}catch(RuntimeException e){throw e;
}finally{close();}
}
/** 回滚事务+释放资源 */
public static void rollback(){
try{
SqlSession session = getSqlSession();
session.rollback();
}catch(RuntimeException e){ throw e;
}finally{close();}
}
/** 释放session资源 */
public static void close(){
//session.close();
SqlSession session = getSqlSession();
if(session != null){
session.close();
//从当前线程中移除该session
tdl.remove();
}
}
}
(2)MyBatis使用技巧、日志
①配置文件提示
②日志
MyBatis集成日志功能:mybatis运行期间的痕迹,通过控制台打印。
目的: 查看mybatis运行的痕迹,调试,验证。
使用: 导入日志的jar log4j.jar; 导入配置文件. log4j.properties [必须放在src根目录]
补救工作:在创建项目时java version可以选择高版本、Target Runtime可以选择自己安装的TomCat
5).MyBatis实体起别名(简化)、参数绑定底层原理、对象插入后绑定随机的id(可返回)
(1)实体简化
①给实体类的权限定名取别名。(mybatis-config配置文件)
com.baizhi.demo1.Person 别名="Person"
<typeAliases>
<typeAlias type="实体的全类名" alias="别名"></typeAlias>
<typeAlias></typeAlias>
</typeAliases>
②Mapper使用实体类名
resultType="Person" 或 parameterType=”Person”
(2)参数绑定的底层原理
①默认mapper文件绑定参数 #{xxx}
说明:底层使用的PreparedStatement对象,使用的是SQL预编译执行、参数绑定。
优点: 防止sql注入、相对效率高(一点)
缺点: 只能绑定数据值. sql关键字,列 非数据无法绑定。
②使用sql字符串拼接绑定参数 ${xx}
优点: 可以绑定任何内容。(关键词,列)
缺点: sql注入。
mybatis使用字符串拼接绑定参数: ${xx}
(3)插入操作后的实体对象绑定id
传统的插入:提前查出要随机的id:select 序列名.nextval from dual;然后调用对象的set方法进行绑定。
MyBatis方式:
<insert id='insert' parameterType="实体类型">
<!--在insert语句之前,执行select序列的sql,为了给参数的id属性绑定值。-->
<selectKey order="BEFORE" resultType="类型" keyProperty="sql执行结果绑定参数的实体的属性名,例如id">
select seq_user.nextval from dual
</selectKey>
insert into t_user values(#{id},…)
</insert>
注:order(在插入语句之前绑定),keyProperty(要绑定的属性名)