本帖最后由 大蓝鲸小蟀锅 于 2017-12-22 19:21 编辑
【南京校区】非诚勿扰《mybatis》之初体验 德艺双馨杨老师
用了那么长时间的jdbc是不是感觉操作非常繁琐,接下来介绍一种会让你感到很愉快的代替jdbc的开源框架,从此让你的编程速度
飞起来。还等什么速度围观吧!
一、以前学习的和数据库交换的JDBC有很多的缺陷
1.Jdbc查询代码繁琐,需要手工完成
2.sql命令定义在程序里,它的改变会导致程序的重新编译
3.没有完善的缓存机制,每次查询都需要做数据库操作。
4.Jdbc描述关系数据比较繁琐
二、MyBatic的基本情况
百度百科:MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,
并且改名为MyBatis 。2013年11月迁移到Github。
MyBatis 是持久层的框架 是一个工具,通过xml文件(配置文件)的形式完成O-R mapping的数据库操作。
持久化:数据永久保存的过程
框架(半成品):程序中的半成品,它完成了公共功能的开发。
ORMapping:Object Releasional Mapping
MyBatis 能做什么 -->替代JDBC
三、让我们来学习下mybatis的创建过程吧
1、导包
导mybatis-3.1.1.jar,
ojdbc5.jar,
log4j.jar(打印日志信息)// log4j.properties文件放到src下面 mybatis默认使用log4j作为输出日志信息
2、写mybatis的配置文件 Mybatis-config.xml :一个项目有一个
1)首先是数据库配置文件
db.properties :
driver=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:xe
username=heige1
password=heige1
2)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 引入外部数据库配置文件 配置属性
先加载内部属性,再加载外部属性,如果有同名属性会覆盖。
-->
<properties resource="db.properties">
<property name="driver" value="com.mysql.jdbc.Driver"/>
</properties>
<!-- 驼峰映射 -->
<settings>
<!-- 开启驼峰,开启后,只要数据库字段和对象属性名字母相同,无论中间加多少下划线都可以识别-->
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
<!-- 配置pojo别名 -->
<typeAliases>
<!-- 可以为一个实体类起别名 -->
<typeAlias type="cn.itheima.mybatis.po.User" alias="user"/>
<!-- 也可以以扫描整个包的形式创建别名,别名就是类名,不区分大小写 -->
<package name="cn.itheima.mybatis.po"/>
</typeAliases>
<!--
environments 集中配置mybatis运行环境的,可以在该标签里配置多个环境,用来连接不同
的数据库。其中default属性指定在默认环境下使用哪一个环境(environment)
和spring整合后 environments配置将废除 由spring去配置
-->
<environments default="development">
<!-- enviornment 配置一个mybatis的运行环境(主要就是连接那个数据库),id属性是这个
环境的唯一标识。
-->
<environment id="development">
<!--
transactionManager 设置mybatis完成数据库操作时事务的提交策略,type属性值为
"JDBC",表示用Jdbc事务提交方式提交
-->
<transactionManager type="JDBC"></transactionManager>
<!-- dataSource 配置数据库连接,type属性值为“POOLED”,表示使用mybatis内置连接池 -->
<dataSource type="POOLED">
<!-- 配置一个连接需要的参数,name属性值有driver、url、username、password -->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- 注册配置文件 resource="映射文件的路径,注意不以/开头的ClassPath(从src下开始写)-->
<mappers>
<!--resource 是基于classpath查找的 -->
<mapper resource="sqlmap/user.xml"/>
<!-- 根据接口名称加载mapper文件
要求:1、mapper映射文件和接口在同一个目录下
2、mapper映射文件的名称和接口名称一致。
3、class就是接口的权限定名
-->
<mapper class="cn.itheima.mybatis.mapper.UserMapper"/>
<!-- 使用扫描包的形式加载mapper文件 -->
<package name="cn.itheima.mybatis.mapper"/>
</mappers>
</configuration>
3)配置 mapper.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace是命名空间,实现接口的全类名 作用:sql语句的隔离
mapper代理的开发规则:
1、namespace必须时候接口的全限定名
2、增删改查标签的id必须和接口的方法名称一致
3、接口方法的参数类型要和parameterType要一致
4、接口方法的返回值类型要和resultType一致
-->
<mapper namespace="cn.itheima.mybatis.mapper.UserMapper">
<!-- 执行select命令的方法用select标签声明
id = 指定实现的方法名
parameterType = 参数类型,如果为对象类型则需要全类名,如果配置了别名可以用别名
resultType = 返回值类型,如果为对象则需要全类名,如果配置了别名可以用别名
#{}作用就是占位符,相当于jdbc的“?”
-->
<select id="getUserById" parameterType="java.lang.Integer" resultType="cn.itheima.entity.User">
select * from user where id=#{id};
</select>
<!-- 如果查询结果返回list, resultType设置为list中一个元素的数据类型
${}字符串拼接指令 注意:如果是取简单数据类型的参数,括号中的值必须为value
-->
<select id="getUserByName" parameterType="string" resultType="cn.itheima.mybatis.po.User">
SELECT * FROM `user` WHERE username LIKE '%${value}%'
</select>
<!-- 参数时候pojo时,#{}中的名称就是pojo的属性 -->
<insert id="insertUser" parameterType="cn.itheima.mybatis.po.User">
<!-- keyProperty:对于pojo的主键属性
resultType:对应主键的数据类型
order:是在insert语句执行之前或者之后。
如果使用uuid做主键,应该先生成主键然后插入数据,此时应该使用Before
-->
<selectKey keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT into user (username,birthday,sex,address)
values (#{username}, #{birthday}, #{sex}, #{address})
</insert>
</mapper>
四、我们如何使用mybatis呢
加载mybatis-config.xml配置文件 获得sqlsession
mybatis的核心类:
a.SqlSession -- 一个”会话“,相当于原来jdbc里service层的一个函数的生命周期,处于一个
connection的范围。在一个SqlSession生命周期里可能包含多次数据库访问操作。
b.SqlSessionFactory -- 创建SqlSession的工厂类
c.SqlSessionFactoryBuilder -- 负责加载mybatis-config.xml文件信息。
创建SqlSessionFactoryBuilder对象 --> builder对象读取配置文件,生成SqlSessionFactory对象
--> 运行时通过factory对象获取SqlSession对象
方法一:
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("配置文件的位置"));
SqlSession sqlSession = sqlSessionFactory.openSession();
方法二: 本质上是一直的只不过一个是用字符流 一个用字节流。
SqlSessionFactoryBuilder sfb=new SqlSessionFactoryBuilder();
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = sfb.build(is);
SqlSession session = factory.openSession();
五、我们用到最多的查询
1.如果属性名和字段名相同
<select id="queryPeopleById" parameterType="" resultType="实体的全限定名">
2.如果属性名和字段名不相同
1) <select id="" parameterType="" resultType="">
select 字段名 as 属性名,。。。。。 from 表名
</select>
查询过程中为查询到的字段起别名,让别名和属性名保持一致
2) 通过定义一个resultMap来指定字段和属性的对应关系
<resultMap type="实体的全限定名" id="该resultMap的唯一标识">
<id property="属性名" column="数据库字段名"></id>
<result property="属性名" column="数据库字段名"></result>
</resultMap>
<select id="" parameterType="" resultMap="resultMap的id">
3.查询结果是一个List集合
<select id="" paramterType="" resultType="集合里的一个元素的全限定名">
4.查询函数有多个参数
public List<People> queryPeople(String username,String password)
1)在映射文件里,省略parameterType
<select id="queryPeople" resultType="entity的全限定名">
select * from people where username=#{0} and password=#{1}
</select>
通过参数在参数表里的下标指定参数顺序
2)在函数定义上通过“注解”为参数指定固定的名字
public List<People> queryPeople(@Param(value="a1")String username,@Param(value="a2")String password);
<select id="queryPeople" resultType="entity的全限定名">
select * from people where username=#{a1} and password=#{a2}
</select>
5.分页查询 (oracle)
在使用mybatis 时我们sql是写在xml 映射文件中,如果写的sql中有一些特殊的字符的话,在解析xml文件的时候会被转义
如果在sql中包含 > <,sql解析时,特殊符号会发生转义。
解决方案1:使用<![CDATA[….]]> 块
<select id="page" resultType="account"">
<![CDATA[
select card_id as cardId,username,password,age from
(select card_id,usename,password,age,rownum rn from
(select card_id,username,password,age from t_account order by card_id)) e
where e.rn>=#{start} and e.rn<=#{end}
]]>
</select>
解决方案2 :使用转义字符 > 代替> < 代替 <
<select id="page" resultType="account"">
select card_id as cardId,username,password,age from
(select card_id,usename,password,age,rownum rn from
(select card_id,username,password,age from t_account order by card_id)) e
where e.rn >=#{start} and e.rn <=#{end}
</select>
六、除了查询以外呢我们还有其他三种操作
函数定义 -- public void insertPeople(People p); --> p对象的id为null,插入前先获取id值
<insert id="insertPeople" parameterType="实体的全限定名">
<!-- 在执行insert命令前,先获取一个唯一值,给id属性赋值 返回值类型是序列的类型 -->
<selectKey resultType="int" keyProperty="需要被赋值的属性名"
order="BEFORE(本次查询优先于insert命令执行)">
select people_seq.nextval from dual
</selectKey>
insert into people values(#{id},#{参数对象对应的属性名},#{属性名},.....)
</insert>
更新<update>
<update id="update" parameterType="实体全限定名">
update employee set name=#{name}, age=#{age}, salary=#{salary} where id=#{id}
</update>
删除<delete>
<delete id="delete" parameterType="java.lang.Integer">
delete from employee where id = #{id}
</delete>
mybatis的基本用法基本上介绍完了。你学会了吗,敬请期待下一篇的非诚勿扰《mybatis》之在判断
|
|