Mybatis是一个持久层框架,主要和你的数据库连接,执行增删改查操作。下面是自己的学习笔记,如果有理解不对的地方,希望指正。
废话不多说,直接上干货了。
项目目录结构:
mapper:主要写sql语句
pojo:实体类,与数据库表对应
test:用来测试的
utiils:连接数据库的工具类
jdbc.properties:连接mysql数据库配置文件
log4j.properties: 日志配置文件
sqlMapConfig.xml :mybatis核心配置文件
需要导入的包和mysql数据表就不解释了,后面上传项目源代码
订单表和用户表
我主要讲解一下mybatis的知识,其他的类还需要阅读源代码。
mybatis为什么可以连接数据并操作呢?
看它的核心配置文件SqlMapConfig,里面有详细的注释,它主要包含了连接池配置和mapper.xml的配置,sql语句就写在了mapper.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>
<!-- 先找property,再找jdbc.properties,如果发现name一样的,替换掉,
也就是说,你的property写错了,只要jdbc.properties写的是对的,就可以
-->
<properties resource="jdbc.properties">
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="root"/>
</properties>
<typeAliases>
<!-- 单个别名定义 -->
<!-- <typeAlias type="com.itheima.mybatis.pojo.User" alias="user"/> -->
<!-- 别名包扫描器(推荐使用此方式),整个包下的类都被定义别名,别名为类名,不区分大小写-->
<package name="com.itheima.mybatis.pojo"/>
</typeAliases>
<!-- 和spring整合后 environments配置将废除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!-- 加载映射文件 -->
<mappers>
<!-- 第三种方式,包扫描器要求(推荐使用此方式):
1、映射文件与接口同一目录下
2、映射文件名必需与接口文件名称一致
-->
<package name="com.itheima.mybatis.mapper"/>
</mappers>
</configuration>
mybatis规范:
<!-- 动态代理开发规则:
1.namespace必须是接口的全路径名
2.接口的方法名必须和sql的id一致
3.接口的入参必须和parameterType一致
4.接口的返回值必须和resultType一致
-->
UserMapper接口和UserMapper.xml放到同一目录
这样我们就可以利用接口来调用UserMapper.xml中的sql语句了
@Test
public void testGetUserById() {
SqlSession sqlSession=SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
//获取接口的代理实现类,实现类的创建sqlSession帮我们做了
UserMapper userMapper= sqlSession.getMapper(UserMapper.class);
User user= userMapper.getUserById(30);
System.out.println(user);
//关闭资源,等到时候和spring整合到一起的时候,就不需要这些
sqlSession.close();
}
大家需要仔细看看mapper.xml中sql语句是怎么写的,里面都有非常详细的注释 ,包括单表的增删改查,多表的一对一关系,一对多关系。
<?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语句 -->
<!-- 动态代理开发规则:
1.namespace必须是接口的全路径名
2.接口的方法名必须和sql的id一致
3.接口的入参必须和parameterType一致
4.接口的返回值必须和resultType一致
-->
<mapper namespace="com.itheima.mybatis.mapper.UserMapper">
<sql id="user_sql">
id,username,birthday,sex,address
</sql>
<!-- id:sql语句得唯一标识 parameterType:入参的数据类型 resultType:返回结果的数据类型-->
<!-- #{}:占位符,相当于jdbc中的? -->
<select id="getUserById" parameterType="int" resultType="User">
select u.id,u.username,u.birthday,u.sex,u.address from user u where u.id=#{id}
</select>
<!-- 返回结果为集合,只需设置每一个元素的类型即可 -->
<select id="getUserByUserName" parameterType="string" resultType="com.itheima.mybatis.pojo.User">
<!-- '%${value}%' 字符串拼接指令,入参类型为普通类型的时候,只能用value-->
select u.id,u.username,u.birthday,u.sex,u.address from user u where u.username like #{username}
</select>
<insert id="insertUser" parameterType="com.itheima.mybatis.pojo.User" useGeneratedKeys="true" keyProperty="id">
<!-- selectKey:自增主键返回,keyProperty:要绑定的pojo的属性,resultType:返回类型,order:在执行插入语句之后 -->
<!-- <selectKey keyProperty="id" resultType="int" order="AFTER">
mysql,查询最后一行更新的id
SELECT LAST_INSERT_ID()
</selectKey> -->
INSERT INTO `user`(`username`, `birthday`, `sex`, `address`) VALUES (#{username}, #{birthday}, #{sex}, #{address});
</insert>
<update id="updateUser" parameterType="com.itheima.mybatis.pojo.User">
UPDATE `user` SET `username` = #{username}, `sex` = #{sex}, `address` = #{address} WHERE `id` = #{id}
</update>
<delete id="deleteUser" parameterType="int">
DELETE FROM `user` WHERE `id` = #{id}
</delete>
<!-- 第二天 -->
<!-- 返回结果为集合,只需设置每一个元素的类型即可 -->
<select id="getUserByQueryVo" parameterType="QueryVo" resultType="User">
<!-- '%${value}%' 字符串拼接指令,入参类型为普通类型的时候,只能用value-->
select u.id,u.username,u.birthday,u.sex,u.address from user u where u.username like #{user.username}
</select>
<!-- 返回User表的个数 -->
<select id="getUserCount" resultType="int">
SELECT count(1) from user
</select>
<!-- 演示动态sql-if标签的使用情景 -->
<select id="getUserByWhere" parameterType="user" resultType="user">
<!-- SELECT * FROM USER WHERE username LIKE '%${username}%' and id = #{id} -->
SELECT * FROM USER where 1 = 1
<!-- if标签的使用 -->
<if test="id != null and id!=''">
and id = #{id}
</if>
<if test="username != null and username != ''">
and username LIKE '%${username}%'
</if>
<if test="sex != null and sex != ''">
and sex =${sex}
</if>
</select>
<!-- 演示动态sql-where标签的使用情景 -->
<select id="getUserByWhere2" parameterType="user"
resultType="com.itheima.mybatis.pojo.User">
<!-- include:引入sql片段,refid引入片段id -->
SELECT
<include refid="user_sql"></include>
FROM USER
<!-- where会自动加上where同处理多余的and,where标签相当于where 1=1 -->
<where>
<!-- if标签的使用 -->
<if test="id != null">
and id = #{id}
</if>
<if test="username != null and username != ''">
and username LIKE '%${username}%'
</if>
</where>
</select>
<!-- 演示动态sql-foreach标签的使用情景 -->
<select id="getUserByIds" parameterType="queryvo"
resultType="com.itheima.mybatis.pojo.User">
SELECT
<include refid="user_sql"></include>
FROM USER
<!-- where会自动加上where同处理多余的and -->
<where>
<!-- id IN(1,10,25,30,34) -->
<!-- foreach循环标签
collection:要遍历的集合,来源入参
item:集合中的变量,随便起名字
open:循环开始前的sql
separator:分隔符
close:循环结束拼接的sql
-->
<foreach item="uid" collection="ids" open="id IN(" separator=","
close=")">
#{uid}
</foreach>
</where>
</select>
<!-- 一对多关联查询 -->
<resultMap type="user" id="user_order_map">
<id property="id" column="id" />
<result property="username" column="username" />
<result property="birthday" column="birthday" />
<result property="address" column="address" />
<result property="sex" column="sex" />
<!-- collection:配置一对多关系
property:用户下的order属性
ofType:property的数据类型,支持别名
-->
<collection property="orders" ofType="order">
<!-- id标签用于绑定主键
column其实是sql语句查出来之后的字段实际值
-->
<id property="id" column="oid"/>
<!-- 使用result绑定普通字段 -->
<result property="userId" column="id"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
</collection>
</resultMap>
<!-- 一对多关联查询 -->
<select id="getUserOrder" resultMap="user_order_map">
SELECT
u.`id`,
u.`username`,
u.`birthday`,
u.`sex`,
u.`address`,
o.`id` oid,
o.`number`,
o.`createtime`
FROM `user` u
LEFT JOIN `order` o
ON o.`user_id` = u.`id`
</select>
</mapper>
最后还是要通过阅读源码有一个更加清晰的认识。
https://download.csdn.net/download/lxqq965467723/11834062
https://download.csdn.net/download/lxqq965467723/11834061