什么是Mybatis?
mybatis是一个基于java的ORM的数据库持久化框架。
那么,orm又是什么呢?什么又是框架呢?什么是持久化呢?
orm,全称是Object Relational Mapping,中文名是对象关系映射。
常见的ORM框架有:Hibernate、TopLink、Castor JDO、Apache OJB等。
框架的产生,就是为了解决某一领域的问题而产生,就是对一些公共的代码进行了封装,使得我们不需要再去写那些复杂的底层逻辑。它本身只是一个半成品,我们只需要在上面根据我们的实际需要进行进一步开发,提高了我们的开发效率。同时,也使得我们大家都遵照一定的规则来写代码,提高了代码的可读性和维护性。
持久化,把内存中的数据保存到数据库的过程就叫做持久化。
Mybatis有什么特点?
(1)MyBatis 是一个支持普通 SQL查询,存储过程(数据库mysql/oracle)和高级映射的优秀持久层框架。
(2)MyBatis ****消除了几乎所有的JDBC代码和手工设置参数以及结果集的检索****。
(3)MyBatis 使用简单的 ****XML*或 注解 用于配置和原始映射,将接口和 Java 的*POJOs****(Plain Old Java Objects,普通的 Java对象 Employee/User/Entity/Domain)映射成数据库中的记录。
Mybatis的使用
一、导入jar包
二、在mysql数据库中准备一张表,我这里的表名叫做product,还有一张表productdir,留待后面使用
三、做相应的配置文件
1.配置mybatis的xml文件,文件名可以随便命名,我这里是mybatis-config.xml
```java
<?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>
<!--引入jdbc.propeties文件-->
<properties resource="jdbc.properties" />
<!-- 环境们 (很多环境的意思)default:默认使用哪一个环境(必需对应一个环境的id)-->
<environments default="development">
<!--一个环境 id:为这个环境取唯一一个id名称-->
<environment id="development">
<!--事务管理 type:JDBC(支持事务)/MANAGED(什么都不做)-->
<transactionManager type="JDBC" />
<!-- 数据源, 连接池 type(POOLED):MyBatis自带的连接池 -->
<dataSource type="POOLED">
<!-- 连接数据库的参数 -->
<property name="driver" value="${driverClassName}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<!-- 这个mappers代表的是相应的ORM映射文件 -->
<mappers>
<mapper resource="cn/itcast/mybatis/domain/ProductMapper.xml" />
</mappers>
</configuration>
2.配置jdbc.properties文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///mybatis
username=root
password=123456
3.配置与sql相关的文件,一般命名为xxxMapper.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的主要功能就是写sql
mapper:根
namespace:命令空间 (用来确定唯一) 以前这个是可以不加的,现在必需加
namespace的值,规则的:映射文件XxxMapper.xml所在的包+domain类名+Mapper
-->
<mapper namespace="cn.itcast.mybatis.domain.ProductMapper">
<!--
select : 这里面写查询语句
id:用来确定这条sql语句的唯一
以后我们确定唯一,也就是找sql语句 : namespace +.+ id
例: cn.itsource.mybatis.day1._1_hello.ProductMapper.get
parameterType : 传入的参数类型 long:大Long _long:小long (具体的对应请参见文档)
resultType : 结果类型(第一条数据返回的对象类型) 自己的对象一定是全限定类名
-->
<select id="get" resultType="cn.itcast.mybatis.domain.Product">
select * from product
</select>
<!--
useGeneratedKeys:要得到主键
keyColumn:数据库主键的列
keyProperty:对应实体类的属性
-->
<insert id="save" parameterType="cn.itcast.mybatis.domain.Product"
useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into product(productName,salePrice,supplier,brand,cutoff,costPrice)
values (#{productName},#{salePrice},#{supplier},#{brand},#{cutoff},#{costPrice})
</insert>
<!--long是java.util.Long的别名-->
<delete id="remove" parameterType="long">
delete from product where id=#{id}
</delete>
<select id="findOne" parameterType="long" resultType="cn.itcast.mybatis.domain.Product">
select * from product where id=#{id}
</select>
<update id="update" parameterType="cn.itcast.mybatis.domain.Product">
update product set productName=#{productName},
salePrice=#{salePrice},
supplier=#{supplier},
brand=#{brand},
cutoff=#{cutoff},
costPrice=#{costPrice}
where id=#{id}
</update>
<sql id="whereSql">
<where>
<if test="id!=null">
and id=#{id}
</if>
<if test="productName!=null">
and productName=#{productName}
</if>
</where>
</sql>
<!--按条件查询-->
<select id="findByQuery" parameterType="cn.itcast.mybatis.query.ProductQuery"
resultType="cn.itcast.mybatis.domain.Product">
select * from product
<include refid="whereSql"></include>
</select>
<!--批量删除-->
<delete id="removeBatch" parameterType="java.util.List">
delete from product where id in
<foreach collection="list" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</delete>
<!--批量添加-->
<insert id="saveBatch" parameterType="java.util.List">
insert into product(productName,salePrice,supplier,brand,cutoff,costPrice)
values
<foreach collection="list" item="product" separator=",">
(#{product.productName},#{product.salePrice},#{product.supplier},#{product.brand},#{product.cutoff},#{product.costPrice})
</foreach>
</insert>
<!--批量修改-->
<insert id="updateBatch" parameterType="map">
update product set productName=#{productName} where id in
<foreach collection="list" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</insert>
</mapper>
4.测试
## 四、完成crud
```java
<!--
这个Mapper的主要功能就是写sql
mapper:根
namespace:命令空间 (用来确定唯一) 以前这个是可以不加的,现在必需加
namespace的值,规则的:映射文件XxxMapper.xml所在的包+domain类名+Mapper
-->
<mapper namespace="cn.itcast.mybatis.domain.ProductMapper">
<!--
select : 这里面写查询语句
id:用来确定这条sql语句的唯一
以后我们确定唯一,也就是找sql语句 : namespace +.+ id
例: cn.itsource.mybatis.day1._1_hello.ProductMapper.get
parameterType : 传入的参数类型 long:大Long _long:小long (具体的对应请参见文档)
resultType : 结果类型(第一条数据返回的对象类型) 自己的对象一定是全限定类名
-->
<select id="get" resultType="cn.itcast.mybatis.domain.Product">
select * from product
</select>
<!--
useGeneratedKeys:要得到主键
keyColumn:数据库主键的列
keyProperty:对应实体类的属性
-->
<insert id="save" parameterType="cn.itcast.mybatis.domain.Product"
useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into product(productName,salePrice,supplier,brand,cutoff,costPrice)
values (#{productName},#{salePrice},#{supplier},#{brand},#{cutoff},#{costPrice})
</insert>
<!--long是java.util.Long的别名-->
<delete id="remove" parameterType="long">
delete from product where id=#{id}
</delete>
<select id="findOne" parameterType="long" resultType="cn.itcast.mybatis.domain.Product">
select * from product where id=#{id}
</select>
<update id="update" parameterType="cn.itcast.mybatis.domain.Product">
update product set productName=#{productName},
salePrice=#{salePrice},
supplier=#{supplier},
brand=#{brand},
cutoff=#{cutoff},
costPrice=#{costPrice}
where id=#{id}
</update>
<sql id="whereSql">
<where>
<if test="id!=null">
and id=#{id}
</if>
<if test="productName!=null">
and productName=#{productName}
</if>
</where>
</sql>
<!--按条件查询-->
<select id="findByQuery" parameterType="cn.itcast.mybatis.query.ProductQuery"
resultType="cn.itcast.mybatis.domain.Product">
select * from product
<include refid="whereSql"></include>
</select>
<!--批量删除-->
<delete id="removeBatch" parameterType="java.util.List">
delete from product where id in
<foreach collection="list" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</delete>
<!--批量添加-->
<insert id="saveBatch" parameterType="java.util.List">
insert into product(productName,salePrice,supplier,brand,cutoff,costPrice)
values
<foreach collection="list" item="product" separator=",">
(#{product.productName},#{product.salePrice},#{product.supplier},#{product.brand},#{product.cutoff},#{product.costPrice})
</foreach>
</insert>
<!--批量修改-->
<insert id="updateBatch" parameterType="map">
update product set productName=#{productName} where id in
<foreach collection="list" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</insert>
</mapper>
五、提取工具类
这里使用枚举
public enum MybatisUtil {
INSTANCE;
private static SqlSessionFactory sqlSessionFactory;
static {
Reader reader = null;
try {
reader = Resources.getResourceAsReader(“mybatis-config.xml”);
sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
}
}
public SqlSession getSession(){
return sqlSessionFactory.openSession();
}
}
六、使用细节问题
1.主键问题
有时候 保存一条数据之后,需要拿到这条数据的主键,拿到之后可以做后续事情
场景:
角色的保存
useGeneratedKeys=“true” keyColumn=“id” keyProperty=“id”
2.日志问题
使用日志的好处:使用日志框架可以帮助我们进行分析与排错
这里使用log4j日志框架
第一步,导入jar包
第二步,写log4j.properties文件
#log4j.rootLogger=ERROR, stdout
#(了解)日志等级: OFF level > FATAL(致命) > ERROR(错误) > WARN (警告)>
INFO (提示)> DEBUG (调试)> trace > ALL level(所有配置)
#输出效果 如果你设置日志级别是trace,则大于等于这个级别的日志都会输出
关闭日志输出
#log4j.rootLogger=NONE
#log4j.rootLogger=NONE ERROR 为严重错误 主要是程序的错误、
WARN为一般警告,比如session丢失、 # INFO为一般要显示的信息,比如登录登出、 # DEBUG为程序的调试信息 # TRACE 堆栈信息 # 扫描包 配置自己包
log4j.rootLogger=ERROR, stdout
#log4j.rootLogger=NONE
log4j.logger.cn.itcast=TRACE
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
七、动态sql
<sql id="whereSql">
<where>
<if test="id!=null">
and id=#{id}
</if>
<if test="productName!=null">
and productName=#{productName}
</if>
</where>
</sql>
<!--按条件查询-->
<select id="findByQuery" parameterType="cn.itcast.mybatis.query.ProductQuery"
resultType="cn.itcast.mybatis.domain.Product">
select * from product
<include refid="whereSql"></include>
</select>