MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除 了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plan Old Java Objects,普通的 Java 对象)映射成数据库中的记录。
MyBatis的前身是iBatis,MyBatis在iBatis的基础上面,对代码结构进行了大量的重构和简化;大量的参考了Hibernate的设计
MyBatis没有hibernate方便,功能没有hibernate强大;易学,性能更好的被程序猿控制
1.导jar包:
MyBatis的核心包:mybatis-3.1.1.jar
MyBatis依赖的jar包:lib/*.jar
MySQL的驱动包:mysql-connector-java-5.1.7-bin.jar
2.在数据库(mybatis)中创建一张表(user)
3.根据表创建实体类:User
4.MyBatis的主配置文件:mybatis-config.xml
配置事务管理器/连接池/映射器
mybatis-config.xml
<?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>
<!-- 声明一些属性Properites
<properties>
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</properties>
-->
<properties resource="db.properties" />
<!-- 为类型配置别名 -->
<typeAliases>
<typeAlias type="com.jd.pss.query.User" alias="User"/>
<typeAlias type="com.jd.pss.query.UserQueryObject" alias="UserQueryObject"/>
</typeAliases>
<!-- 配置环境
default代表mybatis默认使用哪个环境
问题,mybatis可以配置多个数据库环境,目的是什么?
1,容易在不同数据库之间切换(default)
2,mybatis是天生支持多数据库,多数据库类型的持久化框架;
-->
<environments default="default">
<!-- 配置一个环境,每个环境有自己的id-->
<environment id="default">
<!-- transactionManager:事务管理器,在定义这个环境中应该怎么使用事务
JDBC:注意大小写,JDBC一定是一种Mybatis里面定义的TranscationManager的类型的别名;代表使用JDBC的事务管理
-->
<transactionManager type="JDBC" />
<!-- datasource:数据库连接池,定义在这个环境中连接数据库相关信息
POOLED:注意大小写,POOLED也一定是一种mybatis里面定义的DataSource的别名,是代表需要缓存的连接池
-->
<dataSource type="POOLED">
<!-- 使用property元素对数据库连接信息进行配置 -->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- 在完成映射文件之后,需要告诉mybatis -->
<mappers>
<mapper resource="com/jd/pss/query/UserMapper.xml"/>
</mappers>
</configuration>
** 5.MyBatis的映射文件**UserMapper.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">
<!-- mapper节点上的namespace属性
namespace:命名空间,默认情况下,这个namespace可以随意写,只是要求不同mapper文件之间的namespace不要重复;
-->
<mapper namespace="com.jd.pss.UserMapper">
<!-- 声明一个resultMap来对结果集到对象的映射规范
type属性:这个resultMap要返回的对象类型
id属性:为这一个resultMap起一个名字
-->
<resultMap type="User" id="base_mapping">
<!-- 设置一个id属性,
column:对应的列名;
property:对应对象中的属性名
javaType:对应的java类型;
jdbcType:对应的数据库中的类型;javaType+jdbcType=====hibernate的<property元素中的type
默认情况下一般不需要设置jdbcType和javaType,mybatis会自动识别
-->
<id column="id" property="id"/>
<!-- 使用result来映射普通属性 -->
<!-- 普通的属性映射 -->
<result column="name" property="name"/>
<result column="salary" property="salary"/>
<result column="hiredate" property="hiredate"/>
</resultMap>
<resultMap type="User" id="select_list_mapping">
<id column="id" property="id"/>
<result column="name" property="name"/>
</resultMap>
<!-- 元素上都有一个id属性,这个id属性唯一的在这个mapper文件中定义了这个元素的名字
这个元素的全名:namespace.id
mybatis的CRUD操作元素中,写的是SQL
keyColumn:代表主键的列名;
keyProperty:代表在对象中表示OID的属性名字
useGeneratedKeys:采用JDBC的获取自动生成主键的方式获取主键
-->
<insert id="add" parameterType="User" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
<!-- 在SQL中使用#{}来对应 parameterType中的对应属性的值-->
INSERT INTO user(name,hiredate,salary)
VALUES (#{name},#{hiredate},#{salary})
</insert>
<!-- 添加一个update节点 -->
<update id="update" parameterType="User">
update user set name=#{name},salary=#{salary},hiredate=#{hiredate} where
id=#{id}
</update>
<!-- 添加一个删除节点
<delete id="delete" parameterType="com.jd.mybatis.User">
注意,这个时候,#{id}中id指的是传入的User实例中的id属性值
DELETE FROM user WHERE id = #{id}
</delete>
-->
<delete id="delete" parameterType="long">
<!-- 注意,如果传入的参数值是一个普通类型,那么在SQL中,就随便写名字 -->
DELETE FROM user WHERE id = #{id}
</delete>
<!-- 在mybatis里面是不区分get和select的,get仅仅就是一个select
1,resultType:查询出来的结果集中每一行结果集要包装成的对象
2,这里面会有一个问题,列和对象的属性是怎么对应的呢?
可以使用resultMap来自定义列和对象属性的映射关系;
[注意]:一个select只能有一个resultType或者一个resultMap
-->
<!-- 编写查询语句 -->
<select id="get" parameterType="Long"
resultMap="base_map">
select *from user where id=#{id}
</select>
<select id="list" resultMap="base_map">
select *from user
</select>
</mapper>
测试类
查询测试类
监控MyBatis的运行
Domain的修改|删除|查询操作
mybatis找参数的方式:
1.首先使用属性名的方式去找
必须:保存操作传入的是一个User对象,所以在SQL中的#{name},的name使用的是User对象中的属性名
2.如果在传入的类型中找不到对应的属性,必如删除操作,传入的是一个long类型,在long中找不到一个叫做id的属性,此时就直接使用传进来的值作为参数
MyBatis的运行流程:
1.加载配置文件:mybatis-config.xml
得到事务管理器,使用JDBC的事务管理器来管理事务
得到连接池对象,然后设置相关的属性,创建出对应的连接池:POOLED,mybatis自身提供的连接池
创建一个SqlSessionFactory对象(相当与一个连接池)
2.打开一个会话(和数据库的会话) SqlSession,相当于一个连接对象:Connection
3.使用SqlSession中的方法获取到映射文件中的SQL语句,并且执行SQL,获取到执行的结果
namespace+sqlid
insert into user(name, salary, hiredate) values(#{name},#{salary},#{hiredate})
将SQL中的占位符翻译成符合预编译语句对象的SQL :带有占位符
insert into user(name, salary, hiredate) values(?,?,?)
创建一个预编译语句对象
Connection对象.prepredStatement(sql);
设置参数
使用#{}指定的参数来作为SQL的参数,#{}取的是指定类型对象的属性值
执行SQL
4.结果如果是一个结果集:查询操作
此时需要将结果集数据封装成指定类型(使用resultType来指定)的对象
注意:此时要求Java中的对象的属性的类型(名称)必须和数据库中列的类型(名称)的要一致
获取自动生成的主键:
当用户执行保存操作之后,立即将保存到数据库中自动生成的主键返回回来
在JDBC中可以手动设置返回自动生成的主键:
在MyBatis中如何获取?
2.在项目中,为自定义的类型设置别名
在主配置文件中做如下的配置:
3.在项目上线之后,需要管理人员来维护项目,所以,管理人员有可能去修改相关的配置:如连接数据库的密码等
为管理人员少犯低级错误(将配置文件修改错),需要将这些需要修改的配置抽取到一个单独的文件中:db.properties
**4.问题:在执行查询操作(增删改没有)的时候,如果属性名和列名不一致,将造成数据封装失败的问题
**
解决方案:使用resultMap来对属性和列做映射
此时,在查询的SQL中,使用resultMap来指定结果集的封装方式
注意:resultType和resultMap不能同时用
使用Mapper接口:
问题:1.在执行CRUD操作的时候,需要去获取到对应的SQL语句(通过namespace+sqlid),如果将字符串写错,在编译时期发现不了...
2.参数的类型接受的是Object类型的,所以,如果将参数类型设置错了,在编译时期发现不了...
解决方案: 使用Mapper接口来解决上面的问题
观察获取语句的字符串
com.jd.pss.domain.UserMapper.save
com.jd.pss.domain.UserMapper.delete
com.jd.pss.domain.UserMapper.update
com.jd.pss.domain.UserMapper.get
com.jd.pss.domain.UserMapper.list
上面的字符串很像在指定一个类的全限定名+类中的方法
接口的定义的要求:
public interface UserMapper {
void save(User u);
void delete(Long id);
void update(User u);
User get(Long id);
List<User> list();
}