MyBatis学习记录

常用框架SSM:

Spring:它是整合其他框架的框架,核心是IOC和AOP,由20多个模块构成
SpringMVC:它是Spring家族的一个,专门优化控制器(Servlet),提供极简数据提交,数据携带,页面跳转功能
Mybatis:是持久化层的一个框架,用来进行数据库访问的优化,对数据访问层的优化,专注于sql语句,极简化JDBC的访问

三层架构,在项目开发中遵守的一种形式模式:

1.界面层:用来接受客户端的输入,调用业务逻辑层进行功能处理,返回结果给客户端,servlet就是界面层的功能
2.业务逻辑层:用来进行整个项目的业务逻辑处理,向上为界面层提供处理结果,向下问数据访问层要数据
3.数据访问层:用来进行数据库的增删改查操作,向上为业务逻辑层提供数据 界面层---->业务逻辑层---->数据访问层

添加Mybatis依赖和mysql驱动依赖

		<dependency>
	      <groupId>org.mybatis</groupId>
	      <artifactId>mybatis</artifactId>
	      <version>3.5.1</version>
	    </dependency>
	    <dependency>
	      <groupId>mysql</groupId>
	      <artifactId>mysql-connector-java</artifactId>
	      <version>8.0.21</version>
	    </dependency>

SqlMapConfig.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>
			<!-- 读取属性文件jdbc.properties
			   属性:resource:从resource目录下找指定名称的文件加载
					url:使用绝对路径找到文件
		   -->
			<properties resource="jdbc.properties"></properties>
			<!-- 配置数据库的环境变量(数据库连接配置)
			   default:使用下面的environment标签的id属性进行切换配置
			   id属性就是提供给environment的default属性使用
			   transactionManager:配置事务管理器
			   type:指定事务管理的方式
					JDBC:事务的控制交给程序员处理
					MANAGED:由容器Spring来管理事务
			   dataSource:配置数据源
					JNDI:java命名目录接口,在服务器端进行数据库连接池的管理
					POOLED:使用数据库连接池
					UNPOOLED:不使用数据库连接池
		   -->
			<environments default="development">
				<environment id="development">
					<transactionManager type="JDBC"></transactionManager>
					<dataSource type="POOLED">
						<property name="driver" value="${jdbc.driverClassName}"></property>
						<property name="url" value="${jdbc.url}"></property>
						<property name="username" value="${jdbc.username}"></property>
						<property name="password" value="${jdbc.password}"></property>
					</dataSource>
				</environment>
			</environments>
			<!-- 注册mapper.xml文件
				resource:从resource目录下找指定名称的文件注册
				url:使用绝对路径找到文件注册
				class:动态代理方式下的注册
				package:包名注册
			-->
			<mappers>
				<mapper resource="StudentMapper.xml"></mapper>
			</mappers>
		</configuration>

StudentMapper.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:是整个文件的大标签,用来开始和结束xml文件
			namepace:指定命名空间(相当于包名,用来区别不同mapper.xml文件中相同的id属性)
				resultType:指定查询返回的结果集的类型,如果是集合,必须是泛型的类型
				parameterType:如果有参数,则通过它来指定参数的类型
		-->
		<mapper namespace="lv">
			<select id="getAll" resultType="com.lv.pojo.Student">
				select id,name,email,age from student;
			</select>
		</mapper>

Mybatis对象分析

1.Resources类
解析SqlMapConfig.xml文件,创建出相应对象 InputStream in = Resources.getResourceAsStream(“SqlMapConfig.xml”);

2.SqlSessionFactory接口
DefaultSqlSessionFactory是实现类
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);

3.SqlSession接口
DefaultSqlSession实现类

为实体类注册别名

1.单个注册
 <typeAliases>
    <typeAlias type="com.lv.pojo.Student" alias="student"></typeAlias>
</typeAliases>
2.批量注册
<typeAliases>
        <package name="com.lv.pojo"/>
</typeAliases>

设置日志输出

	<settings>
	        <setting name="logImpl" value="STDOUT_LOGGING"/>
	</settings>

动态代理的实现规范

1.UsersMapper.xml文件与UsersMapper.java的接口必须同一个目录下
2.UsersMapper.xml文件与UsersMapper.java的接口文件名必须一致,后缀不管
3.UserMapper.xml文件中标签的id值与UserMapper.java的接口中方法名称完全一致
4.UserMapper.xml文件中标签的ParameterType值与UserMapper.java的接口中方法的参数类型完全一致
5.UserMapper.xml文件中标签的resultType值与UserMapper.java的接口中方法的返回值完全一致
6.UserMapper.xml文件中namespace属性必须是接口的完全限定名称
7.在SqlMapConfig.xml文件中注册mapper文件时,使用class = 接口的完全限定名称

动态代理访问的步骤

1.建表User
2.新建maven工程,刷新可视化
3.修改目录
4.修改pom.xml,添加依赖
5.添加jdbc.propertis文件
6.添加SqlMapConfig.xml文件
7.添加实体类
8.添加mapper文件夹,新建UsersMapper接口
9.在mapper文件夹下,新建UsersMapper.xml文件,完成增删改查
10.添加测试类,测试功能

SqlMapConfig.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>
        <!--读取属性文件jdbc.properties-->
        <properties resource="jdbc.properties"></properties>
        <!--设置日志输出-->
        <settings>
            <setting name="logImpl" value="STDOUT_LOGGING"/>
        </settings>
        <!--实体类注册别名-->
        <typeAliases>
            <package name="com.lv.pojo"/>
        </typeAliases>
        <!--配置数据库的环境变量(数据库连接配置)-->
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"></transactionManager>
                <dataSource type="POOLED">
                    <property name="driver" value="${jdbc.driverClassName}"></property>
                    <property name="url" value="${jdbc.url}"></property>
                    <property name="username" value="${jdbc.username}"></property>
                    <property name="password" value="${jdbc.password}"></property>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <!--<mapper class="com.lv.mapper.UsersMapper"></mapper>-->
            <!--批量注册-->
            <package name="com.lv.mapper"/>
        </mappers>
    </configuration>

UsersMapper接口写法:

   public interface UsersMapper {
        //查询所有的信息的方法
        List<User> getAll();
        //根据id查询信息的方法
        User getId(Integer num);
        //模糊查询方法
        List<User> getByName(String name);
        //更新用户方法
        int update(User user);
        //增加用户
        int insert(User user);
        //根据主键删除用户
        int delete(Integer id);
        //模糊用户名和地址查询
        List<User> getByNameorAddress(@Param("columnName") String columnName, @Param("columnValue") String columnValue);
    }

UsersMapper.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="com.lv.mapper.UsersMapper">
    <select id="getAll" resultType="user">
        select id,username,birthday,sex,address from users
    </select>
    <select id="getId" resultType="user" parameterType="int">
        select id,username,birthday,sex,address from users where id = #{id}
    </select>
    <select id="getByName" resultType="user" parameterType="string">
        select id,username,birthday,sex,address from users where username like concat('%',#{name},'%')
    </select>
    <update id="update" parameterType="user">
        update users set username=#{userName},birthday=#{birthday},sex=#{sex},address=#{address}
         where id =#{id}
    </update>
    <insert id="insert" parameterType="user">
        <selectKey keyProperty="id" resultType="int" order="AFTER">
            select last_insert_id()
        </selectKey>
        insert into users (username,birthday,sex,address) value (#{userName},#{birthday},#{sex},#{address})
    </insert>
    <delete id="delete" parameterType="int" >
        delete from users where id = #{id}
    </delete>
    <select id="getByNameorAddress" resultType="user">
        select id,username,birthday,sex,address from users where ${columnName} like concat('%',#{columnValue},'%')
    </select>
</mapper>

测试类写法:

  public class MyTest {
        //SqlSession对象
        SqlSession sqlSession;
        //动态代理对象
        UsersMapper uMapper;
        //日期的格式化刷子
        SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd");
        @Before
        public void open() throws IOException {
            //使用文件流读取核心配置文件SqlMapConfig.xml
            InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
            //创建SqlSessionFactory工厂
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
            //取出sqlSession的对象
            sqlSession = factory.openSession();
            //取出动态代理对象,完成接口中方法的调用,实则是调用xml文件中相同的标签的功能
            uMapper = sqlSession.getMapper(UsersMapper.class);
        }
        @After
        public void close(){
            //关闭SqlSession对象
            sqlSession.close();
        }
        @Test
        //查询所有的信息
        public void testGetAll(){

            List<User> list = uMapper.getAll();
            list.forEach(user -> System.out.println(user));
        }
        @Test
        //按id查询信息
        public void testGetId(){
            User u = uMapper.getId(7);
            System.out.println(u);
        }
        @Test
        //模糊查询
        public void testGetByName(){
            List<User> list = uMapper.getByName("小");
            list.forEach(users -> System.out.println(users));
        }
        @Test
        //更新数据
        public void testUpdate() throws ParseException {
           User u = new User(7,"老七",date.parse("1999-07-10"),"2","湖南");
           int num = uMapper.update(u);
            System.out.println(num);
           sqlSession.commit();
        }
        @Test
        //插入数据
        public void testInsert() throws ParseException{
            User u = new User("老八",date.parse("1999-07-10"),"2","湖南省");
            int num = uMapper.insert(u);
            System.out.println(num);
            sqlSession.commit();
            System.out.println(u);
        }
        @Test
        //根据id删除数据
        public void testDelete(){
            int num = uMapper.delete(32);
            System.out.println(num);
            sqlSession.commit();
        }
        @Test
        //根据名字和地址模糊查询
        public void testgetByNameorAddress(){
            List<User> list = uMapper.getByNameorAddress("username","小");
            List<User> list2 = uMapper.getByNameorAddress("address","湖");
            list.forEach(users -> System.out.println(users));
            list2.forEach(users -> System.out.println(users));
        }
        @Test
        //生成uid
        public void testUUID(){
            UUID uid = UUID.randomUUID();
            //replace替换-为空,substring截取16位
            System.out.println(uid.toString().replace("-","").substring(16));
        }
    }

#{}占位符

传参大部分使用#{}传参,底层使用的事preparedStatement对象,是安全的数据访问,防止sql注入
1.如果parameterType的类型是8种基本封装类型+String,则#{}里随便写
2.如果parameterType的类型是实体类的类型,则#{}只能是类中成员变量的名称,而且区分大小写

${}字符串拼接或字符串替换(很少用)
字符串拼接,一般用于模糊查询,少用,有sql注入的风险
1.如果parameterType的类型是8种基本封装类型+String,则${}里随便写,如果是3.5.1以下版本只能写value
2.如果parameterType的类型是实体类的类型,${}只能是类中成员变量的名称.
3.concat('%',#{name},'%')  以后用这种做模糊查询

字符串替换:
需求:模糊地址或模糊用户名查询
 <select id="getByNameorAddress" resultType="user">
        select id,username,birthday,sex,address from users where ${columnName} like concat('%',#{columnValue},'%')
 </select>

返回主键值:

在插入语句结束后,返回自增的主键值到入参的id属性中
keyProperty:user对象的哪个属性来传入返回值
resultType:返回主键的类型
order:在插入语句执行前还是后返回主键的值

<insert id="insert" parameterType="user">
         <selectKey keyProperty="id" resultType="int" order="AFTER">
             select last_insert_id()
         </selectKey>
         insert into users (username,birthday,sex,address) value (#{userName},#{birthday},#{sex},#{address})
 </insert>

UUID:

全球唯一字符串,由36个字母数字中划线组成
UUID uid = UUID.randomUUID();
//replace替换-为空,substring截取16位
System.out.println(uid.toString().replace("-","").substring(16));

动态sql:

 可以定义代码片段,可以进行逻辑判断,可以进行循环处理,(批量处理),使条件判断更为简单
 <sql>:用来定义代码片段,可以将所有的列名,或复杂的条件定义为代码片段,供使用时调用
 <include>:用来引用<sql>定义的代码片段
 <if>:进行条件判断
 <where>:进行多条件拼接,在查询,删除,更新中使用
 <set>:有选择的进行更新处理,至少更新一列
 <foreach>:用来进行循环遍历,完成循环条件查询,批量删除,批量增加,批量更新
            collection:用来指定入参的类型,list,map,array
            item:每次循环遍历出来的值或对象
            separator:多个值之间的分隔符
            open:循环外的前括号
            close:循环外的后括号

 用动态sql代码简化的UsersMapper.xml:
 <select id="getByCondition" parameterType="user" resultType="user">
         select <include refid="allColumns"></include>
         from users
         <where>
             <if test="userName != null and userName != ''">
                 and username like concat('%',#{userName},'%')
             </if>
             <if test="birthday != null">
                 and birthday = #{birthday}
             </if>
             <if test="sex != null and sex != ''">
                 and sex = #{sex}
             </if>
             <if test="address != null and address != ''">
                 and address like concat('%',#{address},'%')
             </if>
         </where>
     </select>
      <update id="updateset" parameterType="user">
             update users
             <set>
                 <if test="userName != null and userName !=''">
                     username = #{userName},
                 </if>
                 <if test="birthday != null">
                     birthday = #{birthday},
                 </if>
                 <if test="sex != null and sex != ''">
                     sex = #{sex},
                 </if>
                 <if test="address != null and address != ''">
                     address = #{address}
                 </if>
             </set>
             where id = #{id}
         </update>
      <select id="getByIds" resultType="user">
                 select <include refid="allColumns"></include>
                 from users
                 where id in
                 <foreach collection="array" item="id" separator="," open="(" close=")">
                     #{id}
                 </foreach>
      </select>
      <delete id="deleteBatch">
              delete from users where id in
              <foreach collection="array" item="id" separator="," open="(" close=")">
                  #{id}
              </foreach>
          </delete>
          <insert id="insertmore">
              insert into users (username,birthday,sex,address) values
              <foreach collection="list" item="user" separator=",">
                  (#{user.userName},#{user.birthday},#{user.sex},#{user.address})
              </foreach>
          </insert>
      //多个update操作JDBCurl要加这段&allowMultiQueries=true
      <update id="updatemore" parameterType="user">
              <foreach collection="list" item="u" separator=";">
                  update users
                  <set>
                      <if test="u.userName != null and u.userName !=''">
                          username = #{u.userName},
                      </if>
                      <if test="u.birthday != null">
                          birthday = #{u.birthday},
                      </if>
                      <if test="u.sex != null and u.sex != ''">
                          sex = #{u.sex},
                      </if>
                      <if test="u.address != null and u.address != ''">
                          address = #{u.address}
                      </if>
                  </set>
                  where id = #{u.id}
              </foreach>
          </update>

指定参数位置:

 如果入参是多个,可以通过指定参数位置进行传参,是实体包含不住的条件,实体类只能封装成员变量的条件
 如果某个成员变量要有区间范围的判断,或者有两个值进行处理,则实体类包不住
      <select id="getByBirthday" resultType="user">
             select <include refid="allColumns"></include> from users
             where birthday between #{arg0} and #{arg1}
      </select>

入参是map:(重点)

 如果入参超过一个以上,使用map封装查询条件,查询条件更明确
 <select id="getByMap" resultType="user">
         select <include refid="allColumns"></include> from users
         where birthday between #{Begin} and #{End}
 </select>

 返回值是map:
 <select id="getMap" resultType="map" parameterType="int">
         select username,address from users where id = #{id}
 </select>

resultMap简单用法:

	<resultMap id="bookmap" type="book">
         //主键绑定
         <id property="id" column="bookid"></id>
         //非主键绑定
         <result property="name" column="bookname"></result>
     </resultMap>

表之间的关联关系:

无论是什么关联关系,如果某方持有另一方集合,使用<collection>,如果是对象,使用<association>
    1.一对多:客户和订单就是典型的一对多关联关系,一个客户可以有多个订单
    使用一对多的关联关系,可以满足查询客户的同时查询该客户名下的订单
    <select id="getById" parameterType="int" resultMap="customermap">
            select c.id cid,name,age,o.id oid,orderNumber,orderPrice,customer_id
            from customer c left join orders o on c.id = o.customer_id
            where c.id=#{id}
    </select>

    2.多对一:订单和客户就是多对一关联,站在订单的方向查询订单的同时将客户信息查出
    <select id="getById" parameterType="int" resultMap="ordersmap">
            select o.id oid,orderNumber,orderPrice,customer_id,c.id cid,name,age
            from orders o inner join customer c on o.customer_id = c.id
            where o.id=#{id}
    </select>
    3.一对一
    4.多对多

事务:

多个操作同时完成,或同时失败称为事务处理
 四个特性:一致性,持久性,原子性,隔离性
 Mybatis框架中设置事务
 <transactionManager type="JDBC"></transactionManager>
 设置自动提交
 sqlSession = factory.openSession(true);

缓存:

Mybatis框架提供两级缓存,一级缓存和二级缓存,默认开启一级缓存
缓存为了提交查询效率
一级缓存用的是sqlSession的作用域,同一个sqlSession共享一级缓存的数据
二级缓存用的事mapper的作用域,不同的sqlsession只要访问的同一个mapper.xml文件,则共享二级缓存

ORM:

ORM(Object Relational Mapping):对象关系映射
Mybatis框架是ORM非常优秀的框架
java语言中以对象的方式操作数据,存到数据库中以表的方式进行存储,对象中的成员变量与表中
的列之间的数据互换成为映射

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值