小言_互联网的博客

mybatis(一)

320人阅读  评论(0)

一、概述

1、什么是框架?

框架就是软件的半成品,已经实现了很多功能,但是这些功能可以解决大部份软件的共性问题,现有的框架和你的产品业务无关,但是可以快速的帮你完成软件框架搭建,功能实现,部署。

高楼搭建:
​ 打好地基,做框架(梁 板 柱),在每个楼层做隔断(小房间),进入装修
​ 好处:速度快,结构稳定 , 非常灵活,定制化开发

高性能软件
​ 使用框架 完成基础功能搭建(梁 板 柱),我们在根据不同业务在框架之上进行定制化开发
​ 好处:开发速度快,周期短,稳定(一个非常初级的工程师都可以使用框架开发出非常稳定,可靠的应用),给了开发者很大的灵活性

后续学的都是框架:mybatis,spring,srpingmvc,springboot,springcloud,dubbo,mycat 目的: 高并发,高可靠

2、什么是ORM框架?

ORM:ORM(Object Relational Mapping)对象关系映射,简单理解,数据表中的一条数据可以映射为软件中的一个对象

ORM框架:解决的问题就是如何将数据表中的数据,读取出来,直接转换为对象,将java中的对象直接保存到数据库中,有时候也成为持久层框架,数据落地到数据库,掉电不丢失

包含:对象 增删改查 到数据库中

Java中常用orm:

mybatis: 常用,短小精悍,定制化sql语句
hibernate: 功能强大,不需要写sql语句,但是性能相对较差,不能根据需求优化sql, 逐步被淘汰
jdbcTemplate:底层封装了hibernate

使用JDBC完成ORM操作的缺点

  • 存在大量的冗余代码。

  • 手工创建 Connection、Statement 等。

  • 手工将结果集封装成实体对象。

  • 查询效率低,没有对数据访问进行过优化(Not Cache)。

3、什么是mybatis?

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)

概述:

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。

官网:

https://mybatis.org/mybatis-3/zh/index.html

二、mybatis 入门

1、创建mybatis java工程

2、引入依赖

<dependencies>

        <!--
            mybatis jar 依赖
        -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <!--
            mysql驱动
        -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <!--
            日志相关依赖 :记录日志 到文件  控制台中
        -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
        <!-- 单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>


    </dependencies>

3、创建一个实体类

/**
 * 学生 与 student_tb 对应
 */
public class Student implements Serializable {
   

    private int id;

    private String name;

    private int age;

    private String sex;

    private float height;

    public Student() {
   
    }

    public Student(int id, String name, int age, String sex, float height) {
   
        this.id = id;
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.height = height;
    }

    public int getId() {
   
        return id;
    }

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

    public String getName() {
   
        return name;
    }

    public void setName(String name) {
   
        this.name = name;
    }

    public int getAge() {
   
        return age;
    }

    public void setAge(int age) {
   
        this.age = age;
    }

    public String getSex() {
   
        return sex;
    }

    public void setSex(String sex) {
   
        this.sex = sex;
    }

    public float getHeight() {
   
        return height;
    }

    public void setHeight(float height) {
   
        this.height = height;
    }

    @Override
    public String toString() {
   
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", height=" + height +
                '}';
    }
}

4、创建一个接口及对应映射


/**
 * 学相关增删改查
 * 现在 不要自己 实现这个接口 StudentDao
 *      我们只要告诉mybatis 要实现这个接口
 *          还要告诉实现的接口中的方法执行 哪个sql
 *
 */
public interface StudentDao {
   


    /**
     * 查找所有学生
     *   select * from student_tb;
     * @return
     */
    List<Student> findAllStudent();
}
<?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 和 接口的映射
                    表中列名 和实体类 属性的映射
    namespace 命名空间 和mybatis 二级缓存相关
-->
<mapper namespace="com.qfedu.dao.StudentDao">


    <!--
        select 代表执行 查询sql
               id="findAllStudent"  对应namespace="com.qfedu.dao.StudentDao" 的那个方法
                resultType="com.qfedu.entity.Student" 返回值类型 类 Student 并且存放到List 中
                                                       将每一行结果转化为 student 放到list
    -->
    <select id="findAllStudent" resultType="com.qfedu.entity.Student">
        select id,name,age,sex,height from student_tb
    </select>


</mapper>

5、配置mybatis 配置文件

在resources 下创建 mybatisConfig.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">
<!--
    mybatis主配置
-->
<configuration >

    <!--配置mybatis环境
        default="mysql" 选择哪一个环境
    -->
    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源
               POOLED 连接池形式 
            -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/java2102"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>


    <!--
         <mappers> 配置
    -->
    <mappers>
        <!--
            告诉mybatis 要根据配置文件StudentDao.xml 的配置 生成 对应的接口实现类
        -->
        <mapper resource="com/qfedu/dao/StudentDao.xml"></mapper>
    </mappers>

</configuration>

6、配置日志

在resouces目录下创建log4j.properties


7、测试类

public class TestMyBatis01 {
   


    private  SqlSession sqlSession;

    @Before // 初始化 sqlSes sion
    public void init() throws IOException {
   

        // 读取mybatis "mybatisConfig.xml"
        InputStream inputStream = Resources.getResourceAsStream("mybatisConfig.xml");

        // 工厂辅助类,帮助初始化 工厂   SqlSessionFactoryBuilder 建造者模式
        SqlSessionFactoryBuilder sessionFactoryBuilder = new SqlSessionFactoryBuilder();

        //SqlSessionFactory  SqlSession 工厂,工厂设计模式
        SqlSessionFactory sqlSessionFactory = sessionFactoryBuilder.build(inputStream);

        // 创建sql 连接 相当于 jdbc connection
         sqlSession =  sqlSessionFactory.openSession();

    }

    @Test
    public void finsAllStudentTest(){
   

       //第一种: 调用方法全限定名 不回用
//       List<Student> studentList =  sqlSession.selectList("com.qfedu.dao.StudentDao.findAllStudent");

        // 第二种
        // 获取mapper 就是获取 接口StudentDao.class 对应的实现 对象
        StudentDao studentDao  =    sqlSession.getMapper(StudentDao.class);
        List<Student> studentList =    studentDao.findAllStudent();

       for (Student student:studentList){
   
           System.out.println("student:"+student);
       }
    }

    @After // 释放连接
    public void destroy(){
   

        sqlSession.close();

    }

}

8、mybatis工具


三、基于mybatis实现curd

根据id 查选学生

 /**
     * 根据 id 查找学生
     * @param id
     * @return
     */
    Student findStudentById(int id);
 <!--
         select id,name,age,sex,height from student_tb where id = #{
   id}
                #{
   id} 获取对应方法中的 参数  占位符
                parameterType="integer" 请求参数类型 int  integer
                 parameterType="java.lang.Integer"

                 parameterType 可以省略不写

                尽量不要再  <select 中 写注释 否则容器干扰日志
    -->
    <select id="findStudentById" resultType="com.qfedu.entity.Student"  >
        /*   是的发送到发送到*/
         <!--sdfsdfsdfds -->
         select id,name,age,sex,height from student_tb where id = #{
   id}
    </select>

测试:

 @Test// 根据iD 查询学生
    public void findStudentByIdTest(){
   

        Student student =  studentDao.findStudentById(1);
        System.out.println("student:"+student);
    }

增加学生

 /**
     * 增加学生
     *      返回值 int 代表的是受影响的行数
     * @param student
     * @return
     */
    int addStudent(Student student);
 <!--
          #{
   name}  获取参数student对象中的属性值   addStudent(Student student);
    -->
    <insert id="addStudent" >
        insert into student_tb (name,age,sex,height) values (#{
   name},#{
   age},#{
   sex},#{
   height})
    </insert>

测试:

/**
     * 增加学生
     * 一开启自动提交
     *   sqlSessionFactory.openSession(true);
     */
    @Test
    public void addStudentTest(){
   

        Student student = new Student();

        student.setName("gaoyuan");
        student.setAge(20);
        student.setSex("M");
        student.setHeight(175);

        int num =  studentDao.addStudent(student);

        if (num>0){
   
            System.out.println("增加成功");
        }
    }

更新学生

 /**
     * 更新学生
     * @param student
     * @return
     */
    int updateStudent(Student student);
 <!--
        更新学生
        where id = #{
   id}  必须要写
    -->
    <update id="updateStudent">
        update student_tb set  name = #{
   name},age=#{
   age},sex=#{
   sex},height=#{
   height} where id = #{
   id}
    </update>

测试:

 /**
     * 更新 学生 根据id
     */
    @Test
    public void  updateStudentTest(){
   
        Student student = new Student();

        student.setName("gaoyuan");
        student.setAge(24);
        student.setSex("M");
        student.setHeight(175);
        student.setId(4);

        int num =  studentDao.updateStudent(student);
        if (num>0){
   
            System.out.println("更新成功");
        }
    }

删除学生

 /**
     * 根据 id 删除 学生
     * @param id
     * @return
     */
    int deleteStudentById(int id);
<!--
        根据id  删除学生
    -->
    <delete id="deleteStudentById">
        delete from  student_tb where  id = #{
   id}
    </delete>
 /**
     * 根据id 删除学生
     */
    @Test
    public void deleteStudentByIdTest(){
   

      int num =    studentDao.deleteStudentById(1);
      if (num>0){
   
          System.out.println("删除成功");
      }
    }

注意

在增删改时,必须使用
1.自动提交 或者 手动commit

  sqlSession =  sqlSessionFactory.openSession(true);

2.更新 删除 必须加限定条件 where

四、获取自增id

自增id:当增加一条数据时,如果主键自增,则增的一行数据 id + 1
获取自增id :获取添加数据后的 增加的id

接口:

  /**
     * 获取 自增id(必须有自增主键)
     *
     *
     * @param student
     * @return
     */
    int addStudentReturnId(Student student);

对应mapper :

<!--
        获取取自增id  第一种方式
             select last_insert_id() 获取最后插入的id
             keyColumn="" 生成自增id  的 列
              keyProperty="id" 在插入数据时parameterType="com.qfedu.entity.Student" 中的 属性id
              resultType="int" 自增id 返回值类型

              order="AFTER" 在插入之后执行
                <selectKey  整个标签意义就算是在执行 insert 之后 执行   select last_insert_id()
                                                                    并将查询 到的id 设置到 对象参数student   addStudentReturnId(Student student))
    -->
<!--    <insert id="addStudentReturnId" parameterType="com.qfedu.entity.Student">
         insert into student_tb (name,age,sex,height) values (#{
   name},#{
   age},#{
   sex},#{
   height})

         <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
             select last_insert_id()
         </selectKey>
    </insert>-->

     <!--
        第二种方式获取自增id
            useGeneratedKeys="true" 获取自增id
            keyColumn="id" 读取那一列
            keyProperty="id" 设置到参数 Student 对象 那个属性 id
     -->
    <insert id="addStudentReturnId" parameterType="com.qfedu.entity.Student" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
        insert into student_tb (name,age,sex,height) values (#{
   name},#{
   age},#{
   sex},#{
   height})


    </insert>

测试:

 /**
     * 获取自增id
     */
    @Test
    public void addStudentReturnIdTest(){
   

        Student student = new Student();

        student.setName("小明");
        student.setAge(20);
        student.setSex("M");
        student.setHeight(175);

        int num =  studentDao.addStudentReturnId(student);

        if (num>0){
   
            System.out.println("增加成功");
            System.out.println("自增id:"+student.getId());
        }

    }

五、模糊查询

like 模糊查询

/**
     * 根据名称模糊 查询
     * @param name
     * @return
     */
    List<Student> findStudentByLikeName(String name);
 <!--
        模糊查询 第一种方式#{
   name}

        resultType="com.qfedu.entity.Student" 将查询结果的每一行转化为 对应类型对象
         #{
   name} 获取参数 findStudentByLikeName(String name) name
          #{
   name} 是占位符  仅仅是替换 ?  输入的只能是值

        select id,name,age,sex,height from student_tb where name like ?
    -->
    <!--<select id="findStudentByLikeName" resultType="com.qfedu.entity.Student">
         select id,name,age,sex,height from student_tb where name like #{
   name}
    </select>-->

    <!--
            模糊查询 第二种方式  ${
   value}
            ${
   value} 就是获取     findStudentByLikeName(String name);  name,只能是value
            '%${value}%'   ${
   value} 他作用 是 将 参数进行 简单的替换 组装为新的 sql

                            如果传递的参数 是一个 sql 子语句,他会先执行 子语句,此时会发生 sql注入,造成数据安全
        select id,name,age,sex,height from student_tb where name like '%小%'  仅仅是替换
    -->

    <select id="findStudentByLikeName" resultType="com.qfedu.entity.Student">
         select id,name,age,sex,height from student_tb where name like '%${value}%'
    </select>

测试:

 /**
     * 模糊查询
     */
    @Test
    public void findStudentByLikeNameTest(){
   

        // #{name}   %小% 只要含有 小 的行都查询出来
//       List<Student> studentList  = studentDao.findStudentByLikeName("%小%");


        // 第二种模糊查询 ${value}
        List<Student> studentList  = studentDao.findStudentByLikeName("小");

        for (Student student:studentList){
   
            System.out.println("student:"+student);
        }
    }

#{}vs${}区别?

#{}是获取参数中的属性值,并讲java中的类型转化为数据库中的类型
$ { } 为sql语句拼接,以${value} 获取参数中的值


转载:https://blog.csdn.net/xue_yun_xiang/article/details/116464527
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场