在上一篇博客 Mybatis框架之创建第一个项目(IDEA),演示了如何使用Mybatis操作数据库,在此篇博客,将介绍一下相关使用细节,帮助大家更好掌握Mybatis的使用。请阅读上一篇博客,对Mybatis框架使用有基本了解。
MyBatis
是持久层框架(即对数据库操作(增、删、改、查)的封装)!
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_day_01?useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
dataSource>
environment>
environments>
<mappers >
<mapper resource="cn/hestyle/mapper/UserMapper.xml"/>
mappers>
configuration>
注 意 : \color{red}注意: 注意:实际开发中一般不会出现单独使用Mybatis框架,一般都是表现层、业务层、持久层都各有一个框架,所以这个可能不会有单独的Mybatis主配置文件,但是这些配置项还是会进行配置,只是放到了其它配置文件。(比如项目还使用了Spring框架,那么数据源(数据库)的配置将会配置在spring的配置中。)
所谓映射文件
有两层意思,
第一层是将Dao层访问数据库的方法映射为访问数据库的sql语句,效果是我们不用写Dao层实现类,只需要写Dao层接口、映射文件,比如接口UserMapper.class文件中的public User findById(Integer id)
方法,映射为
<select id="findById" parameterType="java.lang.Integer" resultType="cn.hestyle.entity.User">
SELECT id id, username username, sex sex, address address
birthday birthday, modify_time modifyTime
FROM user
WHERE id = #{id}
select>
第二层是将数据库中的表(user表)的字段与实体类(比如User类)属性进行映射,效果是我们不用处理sql执行的结果集,它会按照映射规则封装成我们需要的类型(实体类对象)。比如user.id
字段映射到User.id
属性,user.username
字段映射到User.username
属性,user.modify_time
字段映射到User.modifyTime
属性。
由于表user(id, username, sex, address, birthday, modify_time)
和实体类User(id, username, sex, address, birthday, modifyTime)
只有modify_time
字段名、modifyTime
属性名不同,所以sql可以进行简化:
<select id="findById" parameterType="java.lang.Integer" resultType="cn.hestyle.entity.User">
SELECT id, username, sex, address
birthday, modify_time modifyTime
FROM user
WHERE id = #{id}
select>
也就是说当属性名和字段名不一致时,此时需要手动指定映射规则
。
可能有些道友会有些疑问,难道我把User实体类属性名、user表的字段名弄成一一对应不行吗?规范的类属性命名是小驼峰命名法
,比如modifyTime
,而MySQL数据库不区分大小写,常见的命名风格是使用下划线隔开单词,比如modify_time
,这下懂了没!
关于这个映射
是Mybatis
框架的重中之重,如果没有理解,请结合之前的博客 Mybatis框架之创建第一个项目(IDEA),多阅读几遍。
此配置文件放在src目录下,或者Resources目录下,常见配置的内容有别名、数据库相关的环境、映射文件的路径。
<configuration>
<typeAliases>
<typeAlias type="cn.hestyle.entity.User" alias="User"/>
typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_day_01?useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
dataSource>
environment>
environments>
<mappers >
<mapper resource="cn/hestyle/mapper/UserMapper.xml"/>
mappers>
configuration>
方式一:使用typeAlias
标签,可指定别名
<typeAliases>
<typeAlias type="cn.hestyle.entity.User" alias="User"/>
typeAliases>
方式二:使用package
标签,别名默认
<typeAliases>
<package name="cn.hestyle.entity"/>
typeAliases>
配置类型别名后,在映射文件中即可简化parameterType、resultType参数。
<!--
parameterType设置入口参数类型Integer,对于Java基本数据库类型int、Integer、doule、Double等可以不用写包路径
resultType返回结果类型User(假设我已经使用了方式二在主配置文件中进行了别名设置) -->
<select id="findById" parameterType="int" resultType="user">
SELECT id, username, sex, address
birthday, modify_time modifyTime
FROM user
WHERE id = #{id}
</select>
方式一:使用mapper
标签resource
属性,每个mapper都需要设置相对路径(包路径)
<mappers >
<mapper resource="cn/hestyle/mapper/UserMapper.xml"/>
<mapper resource="cn/hestyle/mapper/StudentMapper.xml"/>
mappers>
方式二:使用mapper
标签class
属性,每个class都需要设置相对路径(包路径)
<mappers >
<mapper class="cn/hestyle/mapper/UserMapper.class"/>
<mapper class="cn/hestyle/mapper/StudentMapper.class"/>
mappers>
要求UserMapper.class
、UserMapper.xml
同名
方式三:使用mapper
标签url
属性,每个mapper都需要设置绝对路径(文件在硬盘中的路径) 不 推 荐 使 用 ! \color{red}不推荐使用! 不推荐使用!
<mappers >
<mapper url="/Users/hestyle/IdeaProjects/mybatis_day_01/src/cn/hestyle/mapper/UserMapper.xml"/>
<mapper url="/Users/hestyle/IdeaProjects/mybatis_day_01/src/cn/hestyle/mapper/StudentMapper.xml"/>
mappers>
方式四:使用package
标签name
属性,批量设置映射文件路径。 使 用 较 多 \color{red}使用较多 使用较多
<mappers >
<package name="cn.hestyle.mapper"/>
mappers>
关于映射文件的作用,在前面Mybatis相关概述
已经进行了介绍,此处不再赘述。
常见的SQL语句有INSERT
、SELECT
、UPDATE
、DELETE
四种,也就是所谓的增、删、改、查。UserMapper.xml文件中演示了四种SQL的基本写法。
<mapper namespace="cn.hestyle.mapper.UserMapper">
<insert id="save" keyProperty="id" useGeneratedKeys="true" parameterType="cn.hestyle.entity.User">
INSERT INTO user(
username, birthday, sex, address
) VALUES (
#{username},#{birthday},#{sex},#{address}
)
insert>
<delete id="deleteById" parameterType="java.lang.Integer">
DELETE FROM user
WHERE id = #{id}
delete>
<update id="update" parameterType="cn.hestyle.entity.User">
UPDATE user
SET username = #{username},
birthday = #{birthday},
sex = #{sex},
address = #{address}
WHERE id = #{id}
update>
<select id="findById" parameterType="java.lang.Integer" resultType="cn.hestyle.entity.User">
SELECT *
FROM user
WHERE id = #{id}
select>
mapper>
除了四种基本写法外,还一些特别一点但是可能比较常用的写法。
查找username
字段中包含usernameKey
关键字的所有记录。
<select id="findUsersByUsernameKey" parameterType="java.lang.String" resultType="cn.hestyle.entity.User">
SELECT *
FROM user
WHERE username LIKE CONCAT('%', #{usernameKey}, '%')
select>
<select id="findUsersByUsernameKey" parameterType="java.lang.String" resultType="cn.hestyle.entity.User">
SELECT *
FROM user
WHERE username LIKE '%${usernameKey}%'
select>
查询name包含nameKey关键字,place包含placeKey关键字,价格在[30.5,40.5]区间,且库存数量大于10的产品。
/**
* Product实体类
*/
public class Product {
private Integer id;
private String name;
private String place;
private Double price;
private Integer number;
//getter、setter
}
<select id="findProductsWithConditions" parameterType="hashmap" resultType="cn.hestyle.entity.Product">
SELECT *
FROM product
WHERE name LIKE CONCAT('%', #{nameKey}, '%')
AND place LIKE CONCAT('%', #{placeKey}, '%')
AND price between #{minPrice} AND #{maxPrice}
AND number >= #{number}
select>
比如用户只修改了用户名,前面的Update方法需要将User类的所有字段都更新一遍,然而我们只需要更新用户名。
<update id="update" parameterType="cn.hestyle.entity.User">
UPDATE user
<trim prefix="set" suffixOverrides=",">
<if test="username!=null">
username=#{username},
if>
<if test="birthday!=null">
birthday=#{birthday},
if>
<if test="sex!=null">
sex=#{sex},
if>
<if test="address!=null">
address=#{address},
if>
trim>
WHERE id = #{id}
update>
<insert id="saveUsers" useGeneratedKeys="true" keyProperty="id" parameterType="cn.hestyle.entity.User">
INSERT INTO user(
username, birthday, sex, address
) VALUES
<foreach collection="list" item="insertItem" separator=",">
(#{insertItem.username}, #{insertItem.birthday}, #{insertItem.sex}, #{insertItem.address})
foreach>
insert>
Mybatis框架的关键就是接口中的方法与SQL的映射,一定要理解好两层映射关系
。上面介绍的4中基本映射编写语法以及四种高级语法的表达能力已经足够解决大多数问题了,希望可以帮助到大家。写了好几个小时。。。点个赞呗~