Mybatis

1.Mybatis简述

1.概述:MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。

JDBC连接:

//加载驱动
class.forname("com.mysql.cj.jdbc.Driver");
//获取连接对象并获取连接
String url = "";
String user ="root";
String password ="";
Connection connecton = DriverManager.getconnection("url","user","password");
//定义sql语句
String sql = "select * from user";
//获取执行sql对象
PreparedStatement statement=connection.prepareStatement(sql);
 //给占位符赋值
 prepareStatement.setString(1,name);
  prepareStatement.setString(2,password);
 //执行命令
 ResultSet  resultSet = PreparedStatement.executeQuery()
 //处理
 return resultSet.next()

Mybatis与hibernate的区别

  • hibernate:全自动映射 ORM框架,不需要自己手动去写SQL语句

  • mybatis:半自动ORM框架,需要自己手动去写SQL语句

  • 开发速度不同

    • 工作量对比: 针对高级查询,Mybatis需要手动编写SQL语句,以及ResultMap。

    • Hibernate有良好的映射机制,开发者无需关心SQL的生成与结果映射,可以更专注于业务流程。

  • 优化程度

    • MyBatis可以进行更为细致的SQL优化,可以减少查询字段。

  • 掌握程度

    • MyBatis容易掌握,而Hibernate门槛较高。

2.Mybatis 环境搭载

        导入maven依赖包

 <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.9</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.2</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.1</version>
      <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/jstl/jstl -->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>



    <!-- https://mvnrepository.com/artifact/taglibs/standard -->
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>

  </dependencies>
  •         创建jdbc.properties文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/manage?
jdbc.username=root
jdbc.password=""
  •         配置mybatis核心文件

                mybaties-config.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>
<!--    MyBatis核心配置文件中的标签必须按照指定顺序配置
(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,
objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)-->


<!--&lt;!&ndash;    引入properties 此后在当前文件中使用${key}的方式访问value &#45;&#45; >-->
    <properties resource="jdbc.properties"/>
<!--    typeAliases 设置类型别名,即为某个具体的类型设置一个别名-->
    <typeAliases>
<!--        <typeAlias type="entity.dao1.Message" alias="abc"></typeAlias>-->
<!--        若不设置alias,当前类型拥有默认别名Message,不区分大小写-->
<!--        <typeAlias type="entity.dao1.Message"></typeAlias>-->
<!--        指定包设置类型别名,指定包下所有的类型将全部拥有,默认别名-->
        <package name="entity.dao1"/>
    </typeAliases>
    <!--environments:配置连接数据库环境
        属性:
        default:设置默认使用的环境的id
    -->
    <environments default="development">
        <!--
            <environment>:设置一个具体的连接数据库的环境
             属性:
             id:是指环境的唯一标识,不能重复
        -->
        <environment id="development">
        <!--  transactionManager:设置事务管理器
             属性:
             type:设置事务管理方式
             type=“JDBC|MANAGED
             JDBC:表示使用JDBC中原生的事务管理方式
             MANAGED:被管理,例如spring
        -->
            <transactionManager type="JDBC"/>
                <!--
                dataSource:设置数据源的类型
                属性:
                type="POOLED|UNPOOLED|JNDI"
                POOLED:表示使用数据库连接池
                UNPOOLED:表示不使用数据库连接池
                JNDI:表示使用上下文中的数据源
                -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
<!--引入mybaties的映射文件-->
    <mappers>
<!--        以包的方式引入映射文件
        1.mapper接口和映射文件所在的包必须一致
        2.mapper接口的名字和映射文件的文字必须一致
-->
        <package name="dao"/>
<!--        <mapper resource="mappers/UserMapper.xml"/>-->
    </mappers>
</configuration>

        映射文件UserMapper.xml

                映射文件对应了mysql中的sql语句

                注意Mybatis中可以面向接口操作数据,但要保证俩个一致:

                        a>mapper接口的全类名和映射文件的命名空间(namespace)保持一致

                        b>mapper接口中的方法名和映射文件中编写Sql的标签的id属性保持一致

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

</mapper>

        dao包下UserMapper接口

        这个Mapper接口跟以前dao包下的接口一样,但是我们不需要创建它的实现类,可以通过mybatis的一些功能来具体实现这个接口,调用这个接口中的方法就可以对应sql语句,实现功能

package dao;

import entity.dao1.Message;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

/**
 * mybaties获取参数值的俩种方式:#{} 和${}
 * 1.若mapper接口方法的参数为单个的字面量类型
     *此时可以通过#{} 和${}以任意内容获取参数值,一定要注意${}的单引号问题
     * #{}的本质是占位符赋值,${}的本质是字符串拼接
 * 2.若mapper接口方法的参数为多个的字面量类型
     * 此时MyBatis会将参数放在map集合中,以俩种方式存储数据
     * 以arg0,arg1 ... 为键,以参数为值
     * 以param1,param2 ...为键,以参数为值
     * 因此,只需要通过#{}和${}访问,一定要注意${}的单引号问题
 * 3.若mapper接口方法的参数为map集合类型的参数
     * 只需要通过#{}和${}访问,一定要注意${}的单引号问题
 * 4.若mapper方法中的接口方法的参数为实体类类型的参数
    * 只需要通过#{}和${}访问实体类中的属性名,就可以获取相对应的属性值,一定要注意${}的单引号问题
 * 5.可以在mapper接口方法的参数上设置@Param注解
     * 此时MyBatis会将参数放在map中,以俩种方式进行存储
     * a>以@Param注解的value属性值为键,以参数为值
     * b>以param1,param2 ...为键,以参数为值
 */
public interface UserMapper {
    /**
     * 查询
     * @return
     */
    List<Message> select();


    /**
     * 修改用户信息
     * @return
     */
    int updateUser();

    /**
     * 删除
     * @return
     */
    int delete();

    /**
     * 新增数据
     * @return
     */
    int insert();


    /**
     * 根据用户名查询用户信息
     * @param name
     * @return
     */
    Message getUserByUsername(String name);

    /**
     * 查询用户名密码   验证登录
     * @param name
     * @param password
     * @return
     */
    Message checkLogin(String name ,String password);

    /**
     * 验证登录
     * @param map
     * @return
     */
    Message checklogin1(Map<String,Object> map);


    /**
     * 添加用户信息
     * @param message
     * @return
     */
    int add(Message message);

    /**
     * 模糊查询表
     * @param username
     * @param password
     * @return
     */
    Message checkLoginByParam(@Param("username") String username, @Param("password")String password);

    /**
     * 动态设置表名
     */
    List<Message> getMessageList(@Param("tableName") String tableName);

    /**
     * 批量删除
     * @param ids
     * @return
     */
    int delete_table (@Param("ids") String ids);


    /**
     * 添加用户信息
     * 获取自增主键
     */
    void insertKey(Message message);
}

        entity包下的实体类,数据库中一个表对应一个实体类/

package entity.dao1;

public class Message {
    private int id;
    private String username;
    private String password;

    public int getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }


}

创建SqlSession工具类

public  static SqlSession getsqlSession(){
        SqlSession sqlSession =null;
        try {
            //获取核心配置文件的输入流
            InputStream is = Resources.getResourceAsStream("mybaties-config.xml");
            //获取SqlSessionFactoryBuilder对象(Mybatis封装的是jdbc,所以我们需要找到一个执行sql语句的入口,来帮我们执行sql语句的一个对象)
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new 
            SqlSessionFactoryBuilder();
            //SqlSssionFactory是一个工厂对象,帮助我们提供SqlSession,根据核心配置文件输入流获取                        SqlSession对象 
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
             //获取Sql的会话对象SqlSession,是mybatis提供的操作数据库的对象
            sqlSession = sqlSessionFactory.openSession(true);

        } catch (IOException e) {
            e.printStackTrace();
        }
        return sqlSession;
    }

创建测试类

 SqlSession sqlSession = SqlSessionUntil.getsqlSession();
//创建mapper对象,但是mapper是接口,不能实例,获取UserMapper的代理实现类对象
 UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//底层使用代理模式,帮助我们创建实体类对象,让我们来实现接口中的方法
  • 静态sql的增删改查
  •  <insert id="add">
        insert into message(username,password) values ("yangwenjie","123456")
    </insert>
        <update id="update">
            update message set username ="qige" where username="yangwenjie"
        </update>
        <delete id="delete">
            delete from message where username="qige"
        </delete>
       <!--resultType 具体的类型  map,double,int,实体类-->
        <select id="select_all" resultType="entity.abc.User">
            select  * from message;
        </select>

    静态sql占位符有参

  • 1.若mapper接口方法的参数为单个的字面量类型
        *此时可以通过#{} 和${}以任意内容获取参数值,一定要注意${}的单引号问题
        * #{}的本质是占位符赋值,${}的本质是字符串拼接
    * 2.若mapper接口方法的参数为多个的字面量类型
        * 此时MyBatis会将参数放在map集合中,以俩种方式存储数据
        * 以arg0,arg1 ... 为键,以参数为值
        * 以param1,param2 ...为键,以参数为值
        * 因此,只需要通过#{}和${}访问,一定要注意${}的单引号问题
    * 3.若mapper接口方法的参数为map集合类型的参数
        * 只需要通过#{}和${}访问,一定要注意${}的单引号问题
    * 4.若mapper方法中的接口方法的参数为实体类类型的参数
       * 只需要通过#{}和${}访问实体类中的属性名,就可以获取相对应的属性值,一定要注意${}的单引号问题
    * 5.可以在mapper接口方法的参数上设置@Param注解
        * 此时MyBatis会将参数放在map中,以俩种方式进行存储
        * a>以@Param注解的value属性值为键,以参数为值
        * b>以param1,param2 ...为键,以参数为值
  •      <select id="checkLogin" resultType="Message">
            select username,password from message where username=#{arg0} and password = #{arg1}
          </select>
        <insert id="add1">
        insert into message(username,password) values ('${username}',"123456")
        </insert>
        <update id="update_username">
            update message set username =#{username}  where id =2;
        </update>

    动态sql

  • <!--模糊查询-->
       <select id="checkLoginByParam" resultType="Message">
            <!-- select * from message where username like "%"#{mohu}"%"-->
            <!-- select * from message where username like '%${mohu}%'-->
     </select>
    <!--动态表名-->
        <select id="getMessageList" resultType="Message">
            select id,username,password from  ${tableName};
        </select>
      <!--批量删除
        若为#{}得话会自动加上引号导致sql错误-->
        <delete id="delete_table">
            delete from message where id in(${ids})
        </delete>
    
    

    对应的mapper接口

    /**
         * 模糊查询表
         * @param username
         * @param password
         * @return
         */
        Message checkLoginByParam(@Param("username") String username, @Param("password")String password);
    
        /**
         * 动态设置表名
         */
        List<Message> getMessageList(@Param("tableName") String tableName);
    
        /**
         * 批量删除
         * @param ids
         * @return
         */
        int delete_table (@Param("ids") String ids);
    

    类型别名(typeAliases)

  • <typeAliases>
    <!--        <typeAlias type="entity.dao1.Message" alias="abc"></typeAlias>-->
    <!--        若不设置alias,当前类型拥有默认别名Message,不区分大小写-->
    <!--        <typeAlias type="entity.dao1.Message"></typeAlias>-->
    <!--        指定包设置类型别名,指定包下所有的类型将全部拥有,默认别名-->
            <package name="entity.dao1"/>
        </typeAliases>

    mybatis-config.xml引入映射文件的俩种方式

     <!--引入mybaties的映射文件-->
            <mapper resource="dao/UserMapper.xml"></mapper>
    <!--        以包的方式引入映射文件
            1.mapper接口和映射文件所在的包必须一致
            2.mapper接口的名字和映射文件的文字必须一致
    -->
            <package name="dao"/>
    <!--        <mapper resource="mappers/UserMapper.xml"/>-->
        </mappers>

  • resultMap

  •    <!--
        resultMap:设置自定义得映射关系
        id:唯一标识
        type:处理映射关系得实体类得类型
        常用得标签 id标签:处理主键和实体类中实现的映射关系
                  result:处理普通字段和实体类中属性的映射关系
                  column:映射关系中的字段名,必须是sql查询出的某个字段
                  property:设置映射关系中的属性的属性名,必须是处理的实体类类型中的属性名
                  collection:处理一对多的映射关系(处理集合类型的属性)
        -->
        <resultMap id="empresult" type="Emp">
            <id column="emp_id" property="emp_id"></id>
            <result column="emp_name" property="emp_name"></result>
            <result column="age" property="age"></result>
            <result column="sex" property="sex"></result>
        </resultMap>
        <select id="getEmpByEmpId" resultMap="empresult">
            select emp_id,emp_name,age,sex,dept_id from emp where emp_id = #{empid}
        </select>
         <resultMap id="empAndDeptResultMapOne" type="Emp">
            <id column="emp_id" property="emp_id"></id>
            <result column="emp_name" property="emp_name"></result>
            <result column="age" property="age"></result>
            <result column="sex" property="sex"></result>
            <result column="dept_id" property="dept.dept_id"></result>
            <result column="dept_name" property="dept.dept_name"></result>
        </resultMap>
    
    
    <resultMap id="empAndDeptResultMap" type="Emp">
            <id column="emp_id" property="emp_id"></id>
            <result column="emp_name" property="emp_name"></result>
            <result column="age" property="age"></result>
            <result column="sex" property="sex"></result>
            <!--
                association:处理多对一的映射关系(处理处理实体类类型的属性)
                property:设置需要处理映射关系的属性的属性名
                javaType:设置要处理的属性的类型
            -->
            <association property="dept" javaType="Dept">
                <id column="dept_id" property="dept_id"></id>
                <result column="dept_name" property="dept_name"></result>
            </association>
        </resultMap>
        <select id="getEmpAndDeptByEmpId" resultMap="empAndDeptResultMap">
            select emp_id,emp_name,age,sex,a.dept_id,b.dept_name
            from emp a
            left join dept b
            on a.dept_id = b.dept_id
            where a.emp_id=#{empid}
        </select>
      <resultMap id="deptAndEmpResultMaop" type="Dept">
            <id column="dept_id" property="dept_id"></id>
            <result column="dept_name" property="dept_name"></result>
            <collection property="emps" ofType="Emp">
                <!--ofType:设置集合类型的属性中存储的数据的类型-->
                <id column="emp_id" property="emp_id"></id>
                <result column="emp_name" property="emp_name"></result>
                <result column="age" property="age"></result>
                <result column="sex" property="sex"></result>
            </collection>
        </resultMap>
        <select id="getDeptAndmpBYDeptId" resultMap="deptAndEmpResultMaop">
            select emp_id,emp_name,age,sex,a.dept_id,b.dept_name
            from dept b left join  emp a
            on a.dept_id =b.dept_id
            where a.dept_id = 1
        </select>

  • 动态sql的增删查

    • 动态sql <if test="emp_name != null and emp_name !=''"> where 1=1

 <select id="getEmpByConditionone" resultType="Emp">
        select emp_id,emp_name,age,sex,dept_id from emp where 1=1
        <if test="emp_name != null and emp_name !=''">
            and emp_name = #{emp_name}
        </if>
        <if test="age != null and age !=''">
            and age  = #{age}
        </if>
        <if test="sex != null and sex !=''">
            and sex  = #{sex}
        </if>
    </select>
  • 2.where标签
        a.where标签中有条件成立,会自动生成where关键字
        b.会自动将where标签中内容前多余的and去掉   但是其中内容后多余的 and无法去掉
        c.若where标签中没有任何一个条件成立,则where标签没有任何功能
 <select id="getEmpByConditionone" resultType="Emp">
        select emp_id,emp_name,age,sex,dept_id from emp where 1=1
    <where>
        <if test="emp_name != null and emp_name !=''">
            and emp_name = #{emp_name}
        </if>
        <if test="age != null and age !=''">
            and age  = #{age}
        </if>
        <if test="sex != null and sex !=''">
            and sex  = #{sex}
        </if>
    </where>
  </select>
  • 3.trim
        prefix,suffix:在标签中内容前面或后面添加指定内容
        prefixOverrides,suffixOverrides:在标签中内容前面或后面去掉指定内容
 <select id="getEmpByConditionone" resultType="Emp">
        select emp_id,emp_name,age,sex,dept_id from emp where 1=1
    <trim prefix="where" suffixOverrides="and">
        <if test="emp_name != null and emp_name !=''">
            and emp_name = #{emp_name}
        </if>
        <if test="age != null and age !=''">
            and age  = #{age}
        </if>
        <if test="sex != null and sex !=''">
            and sex  = #{sex}
        </if>
    </trim>
  </select>
  • 4. choose,when,otherwise
        相当于java中的if...else if...else
        when至少设置一个,otherwise最多设置一个
<select id="getEmpByChoose" resultType="Emp">
    select emp_id,emp_name,age,sex,dept_id from emp
    <where>
        <choose>
            <when test="emp_name !=null and emp_name !=''">
                emp_name = #{emp_name}
            </when>
            <when test="age !=null and age !=''">
                age = #{age}
            </when>
            <when test="sex !=null and sex !=''">
                sex = #{sex}
            </when>

        </choose>
    </where>
</select>
  • 5. foreach
                collection = "empIds" 参数名Param 设置要循环的数组或集合
                item = “emp” 实体类名   设置用一个字符串来表示数组或集合中的每一个数据
                separator="or"          设置每次循环的数据之间的分隔符
                open = “循环的所有内容以什么开始”
                close = “循环以什么结束”
  • <!--批量添加-->
    <insert id="insertMoreEmp">
            insert into emp values
            <foreach collection="emps" item="emp" separator=",">
                (null,#{emp.emp_name},#{emp.age},#{emp.sex},null)
            </foreach>
        </insert>
    <!--批量删除-->
     <delete id="deleteMoreEmp1">
            delete  from emp where empid in
    
                <foreach collection="empIds" item="emp_id" separator="," open="(" close=")" >
                    #{emp_id}
                </foreach>
    
        </delete>
        <delete id="deleteMoreEmp">
            delete  from emp where
            <!--
                collection = "empIds" 参数名Param 设置要循环的数组或集合
                item = “emp” 实体类名   设置用一个字符串来表示数组或集合中的每一个数据
                separator="or"          设置每次循环的数据之间的分隔符
                open = “循环的所有内容以什么开始”
                close = “循环以什么结束”
            -->
            <foreach collection="empIds" item="emp_id" separator="or"  >
               emp_id =  #{emp_id}
            </foreach>
    
        </delete>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值