Mybatis基础知识

MyBatis

MyBatis的简介:

MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。

MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。

MyBatis使用简单的XML或注解用于配置和原始映射,将接口和JavaPOJOsPlan Old Java Objects,普通的Java对象)映射成数据库中的记录

MyBatis作为持久层框架,其主要思想是将程序中的大量sql语句剥离出来,配置在配置文件中,实现sql的灵活配置。这样做的好处是sql与程序代码分离,可以在不修改程序代码的情况下,直接在配置文件中修改sql

MyBatis的工作原理:

Reader reader =null;

//读取配置信息,生成Reader对象

reader=Resources.getResourceAsReader("Configuration.xml");

//创建SqlSessionFactoryBuilder对象

SqlSessionFactoryBuilder sfb=new SqlSessionFactoryBuilder();

//根据SqlSessionFactoryBuilder对象创建SessionFactory

SqlSessionFactory factory =sfb.build(reader);

//创建session对象

SqlSession session = factory.openSession();

session.close();

MyBatishibernate

都从配置文件中得到sessionFactory

从sessionFactory中产生session

通过session完成对数据的增删改

Mybatis的session不安全,用完就要关闭。

不需要管理开启事务,但是要提交事务

也有映射文件

MyBatis的优点:

好学,灵活性好

HibernateMyBatis:

Hibernate的移植性好,Dao层开发简单

MyBatis的开发流程:

1、       搭建环境,导入jar 包,配置主配置文件(指定实体类别名,配置数据库信息,配置映射文件)

2、       建立对象模型(对象的实体类以及对象之间的关系:关联属性)

3、       根据对象模型建立数据库中关系模型:使用mybatis需要手动创建数据库,创建表以及主外键设置

4、       定义功能规范:接口

5、       针对接口中不同的方法中在不同的xml文件中编写与方法对应的sql语句

6、       拿到SqlSession对象(手动拿到的是不安全的)

7、       通过session创建实现接口的类的对象

UserMapper userMapper=session.getMapper(User.class);

搭建测试环境:

  • Ø MyEclipse 8.5
  • Ø mysql 5.1 
  • Ø jdk 1.6
  • Ø apache-tomcat-6.0.14
  • Ø mybatis-3.2.2.jar

创建Java项目

导入jar包:

mybatis_HOME/mybatis-3.2.2.jar

mybatis_HOME/lib/*.jar

MySql jdbc驱动:

mysql-connector-java-5.0.4-bin.jar

Junit-3.8.1.jar

定义接口:

MyBatis根据接口自动创建持久层代码

MyBatis的主配置文件:Configuration.xml

<typeAliases >配置别名

配置开发环境

配置数据源(JDBC)

连接池是dbcp连接池

映射文件和实体类的关系不是很密切

Sql语句和接口中的方法对应

<select id=”接口中的名字的方法” parameterType=”接口中的方法参数类型” resultMap=”接口中的方法的返回值类型”>

<?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>

//定义别名

     <typeAliases>

        <typeAlias alias="IdCard" type="com.mybatis.IdCard"/>

        <typeAlias alias="Person" type="com.mybatis.Person"/>

     </typeAliases>

  

//环境配置

    <environments default="development">

        <environment id="development">

        <transactionManager type="JDBC"/>

            <dataSource type="POOLED">

            <property name="driver" value="com.mysql.jdbc.Driver"/>

            <property name="url" value="jdbc:mysql://127.0.0.1:3306/hibernate_one2one_pk_1" />

            <property name="username" value="root"/>

            <property name="password" value="root"/>

            </dataSource>

        </environment>

</environments>

//写了接口中方法对应的sql语句的xml文件,一个接口多个方法,可以有多个xml文件

      <mappers>

        <mapper resource="com/mybatis/IdCard.xml"/>

        <mapper resource="com/mybatis/Person.xml"/>

    </mappers>

</configuration>

MyBatis不能自己创建表,必须手工创建表。

工具类:

1、       读取配置文件reader=Resources.getResourceAsReader(“Configuration.xml”)

2、       创建SqlSessionFactoryBuilder对象

3、       通过SqlSessionFactoryBuilder对象读取reader创建工厂

SqlSessioFactory factory=ssfb.build(reader);

factory.openSession();//拿到session,线程不安全,用完就要关闭

//创建实现了UserMapper接口的持久类对象(持久层对象)UserMapper是一个定义了方法的接口。

UserMapper userImpl=session.getMapper(UserMapper.class);

1、       session得到相应的User.xml配置文件(因为session是由SqlSessionFactory创建的,读取流主配置信息)

2、       session能找到接口,并且能找到接口中的方法

3、       session能找到与接口中的方法对应的sql语句,按照sql语句自动的实现方法

User user=userImpl.selectUserById(1);//调用接口实现类的方法

#{id}:取出参数名为id对应的参数值

在主配置文件中定义别名,后面的配置中 都可以在别名的基础上写路径。

MyBatis体现了面向接口编程

 

MyBatis做增删改查

1、       找到对象模型以及对象模型的关系

2、       确定如何操纵数据库

3、       配置xml,是的接口中的每个方法都有对应的sql语句,使用sql语句实现接口中的方法

4、       通过session的getMapper创建实现接口的类的对象

5、       调用对象的相应方法,完成增删改查操作

6、       关闭session

 

一个接口中定义的方法,可以散布在多个xml配置中

创建sql语句执行

查询所有用户:返回的是List集合

resultMap:自定义返回值类型的集合

<resultMap type="User" id="resultListUser">

<id column="id" property="id" />

<result column="userName" property="userName" />

<result column="userAge" property="userAge" />

<result column="userAddress" property="userAddress" />

</resultMap>

查询出来的记录生成resultListUser所标识的user对象,然后将记录的字段设到User对象中,然后把User对象放入list集合中,继续查下一条,依次生成对象放入list集合。

<!-- 返回list 的select 语句,注意 resultMap 的值是指向前面定义好的 -->

    <select id="selectUsers"   resultMap="resultListUser">

        select * from user 

</select>

查询表中的指定字段,设到Map中,再将Map设到list 集合中:

resultSet:指定生成集合

<!-- 把用户的id,userName封装到map集合 -->

<select id="selectMaps"   resultType="java.util.HashMap">

select id,userName from user

</select> 

从user表中找到相应的字段,生成Map,字段名作为key,字段值作为value,然后将Map设到list集合中。

一条记录创建一个Map,一个Map中有两个Entry(键值对)。

有多少条记录就有多少个Map,查询多少个字段Map中就会有几个Entry键值对。

MyBatis的分页技术:

RowBounds:分页器对象

rowBounds =new RowBounds(”起点:从第几条记录查”,”查几条记录”)

session.selectList(“selectUsers”,null,rowBounds);

缺点:内存使用不当

Mybatis使用内存分页

原理:先查询出所有的记录,然后再查询指定分页查询的记录

插入:(两种插入方式)数据库自动生成主键id

<insert id="addUser" parameterType="User"

useGeneratedKeys="true" keyProperty="id">

insert into user(userName,userAge,userAddress) 

values(#{userName},#{userAge},#{userAddress}) 

</insert>

#{userName}从user对象中拿到username属性设定user表中对应的字段上。

useGeneratedKeys="true"Mybatis可以从数据库中取得这个记录的id 设给这个对象的id属性。

keyProperty="id"指定id属性为主键

MyBatis的方法中有多个参数需要传递的时候,需要把对象封装成一个对象,再传递。

resultMap:(手动设定返回值类型的对象)

主键给主键设值的时候 使用id标签

普通属性设值使用result标签

<resultMap type="User" id="resultListUser">

   <id column="id" property="id" />

   <result column="userName" property="userName" />

   <result column="userAge" property="userAge" />

   <result column="userAddress" property="userAddress" />

</resultMap>

MyBatis的注重点:

接口怎么定义

接口对应的sql语句怎么写

MyBatis的增删改查的特点:

主键不使用数据库自增:设置主键为手动设定,必须手动添加主键,手动提交数据。

更新数据:先查询再update(和jdbc更新几乎一样)

删除数据:一定要commit

删除后的数据:数据库中没有记录,对象还在:对象状态从持久态变为瞬时态。

多个条件查询:将多个条件封装到一个对象中(Condition对象)

Sql语句:

<select id=”find” parameterType=”Condition” resultType=”Article”>

     select * from acticle

     <where>

<if test="title != null">

and title = #{title}

</if>

<if test="userid != null">

and userid = #{userid}

</if>

</where>

</select>

增删改查:

<?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.mybatis.UserMapper">

<!-- 为了返回list 类型而定义的returnMap -->

    <resultMap type="User" id="resultListUser">

        <id column="id" property="id" />

        <result column="userName" property="userName" />

        <result column="userAge" property="userAge" />

        <result column="userAddress" property="userAddress" />

    </resultMap>

   

<!-- 返回list 的select 语句,注意 resultMap 的值是指向前面定义好的 -->

    <select id="selectUsers"   resultMap="resultListUser">

        select * from user 

    </select>

   

  <!-- 把用户的id,userName封装到map集合 -->

    <select id="selectMaps"   resultType="java.util.HashMap">

        select id,userName from user 

    </select> 

 <!--执行增加操作的SQL语句。id和parameterType 

       分别与IUserOperation接口中的addUser方法的名字和 

       参数类型一致。以#{name}的形式引用Student参数 

       的name属性,MyBatis将使用反射读取Student参数 

       的此属性。#{name}中name大小写敏感。引用其他 

       的gender等属性与此一致。seGeneratedKeys设置 

       为"true"表明要MyBatis获取由数据库自动生成的主 

       键;keyProperty="id"指定把获取到的主键值注入 

       到Student的id属性-->

 <insert id="addUser" parameterType="User"

        useGeneratedKeys="true" keyProperty="id">

        insert into user(userName,userAge,userAddress) 

             values(#{userName},#{userAge},#{userAddress}) 

 </insert>

 <!--执行查询数据的SQL语句-->

 <select id="selectUserByID" parameterType="int" resultType="User">

        select * from `user` where id = #{id}

 </select>

 <!--执行更新数据的SQL语句-->

 <update id="updateUser" parameterType="User" >

update user set userName=#{userName},userAge=#{userAge},

userAddress=#{userAddress} where id=#{id}

 </update>

<!--执行删除数据的SQL语句-->

<delete id="deleteUser" parameterType="int">

        delete from user where id=#{id}

</delete>

</mapper>

 

PPT:个人介绍,项目介绍,基本技术,基本功能,预期结果

各个版本的源代码

项目评审成绩表

 

 

Many-to-one:

对象模型:

User :id ,name,group

Group:id ,name

关系模型:

手动建表:

t_user: id是主键,groupid为外键,外键参照t_group表的主键

t_group:id是主键,没有外键

insert into user(name,groupid) values(#{name},#{group.id})

#{group.id}group:是User对象的一个属性,group属性所指的Group对象中有id属性。这就是将group属性所指的Group对象的id属性设到groupid字段上。

所以在存储之前,必须先存储group对象,使得Group对象有id。

many-to-one的查询:手动创建sql语句

select  t_user.id uid,t_user.name uname ,t_user.groupid

,t_group.name from t_user ,t_group where t_user.groupid=t_group.id and t_groupid=#{id}

#{id}标识的是对象的属性

查询出来的数据接收:resultMap自定义接收数据类型

<association property=”group” javaType=”Group” resultMap=”resultGroup”/>

association标识外键

通过结果集生成user对象:三个属性 (id ,name,group)

group为关联属性:Group类型的对象,使用resultMap所标识的标签给group属性设值,相同字段名的值使用别名。

主要步骤:

1、       联合查询找到相应的数据

2、       先生成 User对象(里面有个group属性)

3、       生成Group对象,再设到User对象的group属性上

One-to-one:

对象模型:

Person: id,name,idCard

IdCard: id ,idcardNum

关系模型:

主键就是外键,外键参照idcard属性对应的类所映射的表

Hibernate的唯一主键关联(ont-to-one自动级联)

<id name=”id”>

<generator class=”foreign”>

<param name=”property”>idCard</param>

</generator>

</id>

<one-to-one name=”idCard” constrained=”true”/>

Person对象的ididcard属性对应的IdCard对象的id中取得

IdCard对象的主键自动生成,IdCard对象一定要拿到id属性,需要标识useGeneratedKeys=”true”,keyProeprty=”id”,因为需要拿到id属性给Person对象的id属性赋值作为主键。

这里不会自动级联,需要手动先存储IdCard 对象然后再存储Person ,Person对象的id赋值 #{idCard.id},通过关联属性所对应的对象的id属性。

insert into t_person(id ,name) values(#{idCard.id},#{name})

session.commit();记得提交事务

然后也要记得关闭session.

 

加载关系:查找id1 的记录,生成person对象

id从记录中查到的id赋值,name从记录中查到的name赋值

association: 外键 关联属性的赋值(idCard)

resultMap:

<id property =”id”/>

<result property =”name”/>

<association property=”idCard” javaTpye=” IdCard” resultMap=”resultIdcard” />

property:指定给哪个属性赋值

javaType:指定属性类型

resultMap:指定属性在标识所标识的对象中生成

假若查询语句中使用了别名字段,那么结果集也需要使用别名

select  t_person.id pid t_person.name pname  from t_person;

<id property =”id” column=”pid”/>

<result property =”name” column =”pname”/>

property:指定对象中的属性名

column:指定数据库中查询出来的字段名

Many-to-many:

对象模型:

Role:id,name

User:id,name,roles(Set)

关系模型:

创建第三张表:至少两个字段userid,roleid,分别参照t_user,t_role

创建三张表:

t_user:id name(id:auto_increment)

t_role:id,name(id:auto_increment)

t_user_role:id,userid,roleid(id:auto_increment,

userid:foreign key,roleid:foreign key)

设置外键:(使用命令行生成)

create table hcheck(

id int (20) primary key,

fkey char(20) not null,           //外键设置为学号

constraint fkey foreign key(fkey) references student(ID)

)ENGINE=InnoDB auto_increment=1 Default charset=utf8;

存储关系:

创建对象:

先创建(多个)Role对象,id自动生成

创建User对象user1,id自动生成

创建Set集合,把Role对象设到set集合中

把set集合设到User对象的roles属性中

再创建User对象user2,id自动生成

创建Set集合,把Role对象设到set集合中

把set集合设到User对象的roles属性中

调用方法存储:

调用接口中的方法存储对象

先存储Role对象,再存储User对象

将多个参数封装成一个对象存储:

最后存储UserRole对象

将两个参数封装成一个对象(因为mybatis一次只能存储一个参数)

分别迭代set集合,将存储的对象id迭代取出来,存到UserRole对象中

new UserRole(u1.getId(),role.getId());

在调用接口实现类的方法时传递UserRole对象,将两个参数以一个对象的方式传递过去。

insert into t_user_role(userid,roleid) values(#{userid},#{roleid})

加载关系:先主找外,再外找主(one-to-many,many-to-one)

创建集合进行关联:

查找id为1的User对象

先把三张表建立关系

连接查询: select * form t_user,t_role,t_user_role where t_user.id=t_user_role.userid and t_role.id=t_user_role.roleid;

<id property=”对象中的属性名” column=”数据库中的字段名:如果设置了别名就写别名”>

<result  property=”对象中的属性名” column=”数据库中的字段名:如果设置了别名就写别名”>

roles属性设值,用的是collection标签

ofType指定集合中存放的数据类型

<collection property=”roles” ofType=”Role”>

<id property=” id” column=”bid(查询的时候设置的别名)”/>

<result  property=”name” column=”username(别名)”/>

</collection>

查到一条数据,就存到roles属性上,依次执行

配置示例:

<?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语句和接口中的方法一一对应

     方法名对应sql语句的id标识

     方法参数对应sql语句中的parameterType

     方法的返回值对应sql语句中的resultMap/resultType

     resultMap:自定义返回值类(主要用于集合,多条语句的查询)

     resultType:已存在的返回值类型的对象

-->

<mapper namespace="com.mybatis.Mapper">

 <insert id="addRole" parameterType="Role"

        useGeneratedKeys="true" keyProperty="id">

        insert into t_role(rolename) 

             values(#{name}) 

 </insert>

  <resultMap id="resultRole" type="Role">

        <id property="id" column="t_role.id" />

        <result property="name" column="rolename" />

       

    </resultMap>

 <select id="getRoleByID" parameterType="int" resultMap="resultRole">

        select * from `t_role` where id = #{id}

 </select>

</mapper>

继承映射:

如何从表中取出相关的记录生成相关的对象

多态查询:父类 Animal ,子类:Bird,Pig

手动建立表,鉴别器字段手动指定

存储:

创建Bird对象,手动设定除主键以外的字段的值

创建Pig对象,手动设定除主键以外的各个字段的值

调用接口实现类对象对应的方法 将对象存储到数据库的表中

insert into t_animal(type,name,sex,weight) values(#{type},#{name},#{sex},#{weight})

加载关系:

完成多态查询:

鉴别器字段的设置:

column:指定字段为鉴别器字段

<discriminator javaType=”string” column=”type”>

<case value=”P” resultType=”Pig”>

<result property=”weight” column=”weight”>

</case>

<case value=”B” resultType=”Bird”>

<result property=”height” column=”height”>

</case>

</discriminator>

最终版本银行项目:

SpringMVC+Spring+MyBatis

AOP完成添加日志,并且添加权限验证(权限表)

管理员可以冻结账户()

SpringMVC+Spring+Mybatis的集成

1、创建web项目

2、导入mybatis的jar包(mybatis的主jar:,mybatis-3.2.2.jar,mybatis-spring-1.2.1.jar,数据库的驱动:mysql-connector-java-3.1-1.bin.jar)

3、配置MyBatis的主配置文件

Web.xml的配置:

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4"

     xmlns="http://java.sun.com/xml/ns/j2ee"

     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

     http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

//SpringMVC的配置信息

<servlet>

<servlet-name>spring</servlet-name>

<servlet-class>

org.springframework.web.servlet.DispatcherServlet

</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>spring</servlet-name>

<url-pattern>*.do</url-pattern>

</servlet-mapping>

//Spring的配置

 <listener>

<listener-class>

org.springframework.web.context.ContextLoaderListener

</listener-class>

</listener>

<!--指定Spring 的主配置文件所在目录。默认配置在WEB-INF目录下 -->

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/applicationContext.xml</param-value>

</context-param>

</web-app>

启动tomcat:

读取web.xml文件,先创建ContextLoaderListener监听器对象,对application内置对象的创建和销毁做监听

全局初始化参数里面封装spring的主配置文件信息

全局初始化参数封装到application内置对象中

Application内置对象一创建,会调用contextInitialized方法,通过事件对象拿到application内置对象,拿到全局初始化参数Spring的配置文件信息,在该方法中创建BeanFactory,然后封装到application内置对象中

BeanFactory一创建:

1、       Spring创建数据源对象dataSource,在数据源中注入数据库的连接信息(url,驱动,用户名,密码)

<!--配数据源本示例采用DBCP连接池-->

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">

<property name="driverClassName">

<value>com.mysql.jdbc.Driver</value>

</property>

<property name="username">

<value>root</value>

</property>

<property name="password">

<value>mysql</value>

</property>

<property name="url">

<value>jdbc:mysql://localhost:3306/ssm</value>

</property>

</bean>

 

2、通过数据源和MyBatis的配置信息创建SqlSessionFactory对象,注入数据源对象,注入所有的sql语句的配置信息

<property name=”dataSource” ref=”dataSource”/>

<propertyname=”mapperLocation” value=”classpath:cn/ssm/bean/.*xml”/>

<!--配置sqlSessionFactory-->

  <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

<!--dataSource属性指定要用到的连接池-->

<property name="dataSource" ref="dataSource"/>

<!--所有实体类的映射文件-->

<property name="mapperLocations" value="classpath:com/tmall/bean/*.xml"/>

</bean>

在myBatis中生成SqlSessionFactory,拿到session对象,用来通过getMapper根据接口生成接口实现类对象

3、配置映射器:生成接口实现类对象(持久对象)

通过sqlSessionFactory和注入接口来创建持久对象

<bean id=”Mapper” class=”Spring的类”>

</bean>

<!--配置映射器-->

<bean id="Mapper" class="org.mybatis.spring.mapper.MapperFactoryBean">

<!--sqlSessionFactory属性指定要用到的SqlSessionFactory实例-->

<property name="sqlSessionFactory" ref="sqlSessionFactory" />

<!--mapperInterface属性指定映射器接口,用于实现此接口并生成映射器对象-->

<property name="mapperInterface" value="com.tmall.inter.OperationMapper" />

</bean>

4、创建业务层对象

<bean id=”loginService” class=”cn.ssm.service.LoginService”/>

 

5、通过数据源创建配置事务管理器(存储,更新,删除不用提交)

使用spring的类创建事务管理器对象,注入数据源就可以了

<!-- 事务管理器 -->   

<bean id="transactionManager"   

class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource" />   

</bean>  

创建springMVC的中央控制器对象DispatcherServlet,执行init方法,读取主配置文件springmvc-servlet.xml,创建webFactory。

创建视图定位器对象

创建请求分派器对象

配置启用注解,配置扫描的包

请求分派器到指定的包下找后端处理器类(@Controller标识的类),创建后端处理器对象,再继续找@Resource标识的属性,注入相应业务层对象

Spring和Mybatis不需要使用代理,也没有织入方法。和Hibernate不一样。

发送请求:

执行项目以前,手动创建数据库,创建表以及表之间的关系

请求交给Tomcat,Tomcat创建request内置对象接收请求

发现是*.do交给SpringMVC处理,截取请求路径/login.do

到webFacotry找到请求分派器

请求分派器找后端处理器,并且根据请求找到@RequestMapping标识的方法

在对应的方法中调用业务对象的方法处理请求。

将需要存储的对象存入request内置对象中

读取主配置:别名,数据库信息,映射文件信息

今日任务:

1、       把银行项目5.0 ,mystruts1.0,学生管理系统看一遍

2、       把java基础,spring springmvc,struts1,hibernate, mybatis, javaweb基础的文档都看一遍

3、       把用友公司的相关信息了解,然后看相关面试题

4、       数据库相关知识,了解公司产品

原文地址:https://www.cnblogs.com/DFX339/p/8535169.html