mybatis_增删改查

MyBatis单表添加操作分析

# 在前面创建了第一个mybatis程序,在程序中实现了一个向数据库中添加数据的操作,代码如下

<insert id="insertStudent" parameterType="com.doaoao.bean.Student">
    INSERT INTO t_student(name,age,score) VALUES (#{name},#{age},#{score})
</insert>

id:在上方代码中定义的 id ,是该SQL语句的唯一标识,可以用来代表该SQL语句,在Java代码中要使用到该标识

parameterType:传入参数的类型,因为mybatis可以自动识别,所以可以不用配置

{}:里面要填写的内容是javabean中的属性,其底层是通过反射机制,调用bean类的相关属性的get方法来获取值

# 在dao的实现类中,手动对事务进行提交

//SqlSession继承了AutoCloseable接口,所以可以自动关闭
try(SqlSession sqlSession = MyBatisUtil.getSqlSession()) {
    //新增数据操作
    sqlSession.insert("insertStudent", student);
    //提交SqlSession
    sqlSession.commit();
}

 可以将事务的提交变为"自动提交"或"不自动提交事务",修改util包下的MyBatisUtil类

//自动提交事务
sqlSessionFactory.openSession(true);

//不自动提交事务
sqlSessionFactory.openSession(false);
sqlSessionFactory.openSession();        // 不写就是默认为false

# 获取插入数据的主键

1:修改StudentMapper.xml文件中的内容

    <insert id="insertStudent" parameterType="com.doaoao.bean.Student">
        INSERT INTO t_student(name,age,score) VALUES (#{name},#{age},#{score})
        <selectKey resultType="int" keyProperty="id" order="AFTER">
            SELECT @@identity
        </selectKey>
    </insert>
<!--
resultType:返回值类型(id的类型为int类型)
keyPeroperty:此处写"id",要与Student中的id名称一样
order:该属性有两个值,一个为 AFTER(语句执行之后),一个为 BEFORE(语句执行之前)
-->

当进行上方这样的配置后,当mybatis完成数据的插入后,会将该数据的主键查询出来

2:重写Student的toString方法

// 从写Student中的toString方法
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }

// 修改测试类
package com.doaoao.test;

import com.doaoao.bean.Student;
import com.doaoao.dao.StudentDao;
import com.doaoao.dao.impl.StudentDaoImpl;
import org.junit.Test;

public class StudentTest01 {
    @Test
    public void insertStudent(){
        StudentDao studentDao = new StudentDaoImpl();
        Student student = new Student("刘德华", 52, 98.50);

        // 插入之前 id 的默认值为0
        System.out.println("插入之前:" + student);

        studentDao.insertStudent(student);

        // 插入后可以获取数据在表中的自增id
        System.out.println("插入之后:"+ student);
    }
}

// 最后输出
插入之前:Student{id=0, name='刘德华', age=52, score=98.5}
插入之后:Student{id=3, name='刘德华', age=52, score=98.5}

 # 注:在事务提交之前,已经获取到主键的id,也就是说,不管当前是提交还是回滚,都是先获取到主键的id,当执行SQL语句后,数据库就会给该行数据分配一个id,如果回滚的化,当前这个主键就无法再使用,当下次再进行插入数据时,会在该回滚主键id的后方再分配一个id。所以可以得出的结论是,主键的生成和事务没有关系,只要执行了SQL语句,mysql就会为其分配一个主键

MyBatis单表删除操作

1:再StudentMapper.xml中添加删除操作(和insert一样,添加在mapper标签中)

<!-- 注: #{id}中的id只是起到一个占位符的作用,也可写成#{XXX}-->
<delete id="deleteStudent">
    DELETE FROM t_student where id=#{id}
</delete>

2:在StudentDao接口中添加deleteStudent方法,再在StudentDaoImpl类中实现

// 在StudentDao中添加接口方法
void deleteStudent(int id);


// 实现接口方法
@Override
public void deleteStudent(int id) {
    try(SqlSession sqlSession = MyBatisUtil.getSqlSession()){

        // 删除
        sqlSession.delete("deleteStudent",id);

        // 提交SqlSession
        sqlSession.commit();
    }
}

3:在测试类中添加测试方法

package com.doaoao.test;

import com.doaoao.bean.Student;
import com.doaoao.dao.StudentDao;
import com.doaoao.dao.impl.StudentDaoImpl;
import org.junit.Before;
import org.junit.Test;

public class StudentTest01 {
    private StudentDao studentDao;
   // 执行测试方法前执行该初始化语句 
  @Before
public void initStudentDao(){ studentDao = new StudentDaoImpl(); } @Test public void insertStudent(){       // 插入语句省略 } @Test public void deleteStudent(){ studentDao.deleteStudent(2); // 将id为1的数据删除 } }

 ...

MyBatis单表修改数据

1:在StudentMapper.xml文件中添加如下内容

    <update id="updateStudent">
        UPDATE t_student set name=#{name},age=#{age},score=#{score} where id=#{id}
    </update>

2:在StudentDao中添加接口 updateStudent,并在实现类中实现该接口

// 添加接口方法
void updateStudent(Student student);

// 实现该接口
    @Override
    public void updateStudent(Student student) {
        try(SqlSession sqlSession = MyBatisUtil.getSqlSession()){
            // 修改数据操作
            sqlSession.update("updateStudent",student);

            // 提交SqlSession
            sqlSession.commit();
        }
    }

3:创建测试类

    @Test
    public void updateStudent(){
        Student student = new Student("李连杰",40,88.88);
        student.setId(3);
        studentDao.updateStudent(student);
    }

...

MyBatis单表查询所有数据

1:在StudentMapper.xml中添加查询语句 resultType为返回的类型,利用的是别名的方法,在mybatis中配置别名方式

    <!-- 查询中尽量别用 * 号,会影响查询效率 -->
    <select id="selectAllStudents" resultType="student">
        SELECT id,name,age,score FROM t_student
    </select>

2:在StudentDao中添加查询方法接口,在实现类中实现该接口

// 添加接口
List<Student> selectedAllStudent();

// 实现接口
    @Override
    public List<Student> selectedAllStudent() {
        List<Student> result = null;
        try(SqlSession sqlSession = MyBatisUtil.getSqlSession()){
            result = sqlSession.selectList("selectAllStudents");
        }
        return result;
    }

3:编写实现方法

    @Test
    public void selectAllStudents(){
        List<Student> students = studentDao.selectedAllStudent();
//        students.forEach((student)->{
//            System.out.println(student);
//        });
        System.out.println(students);
    }

.... 

MyBatis查找单个对象

1:修改StudentMapper.xml文件中的内容

<select id="selectStudentById" resultType="student">
    SELECT id,name,age,score FROM t_student where id=#{id}
</select>

2:在StudentDao中添加接口,在实现类中实现接口

// 添加接口
    Student selectStudentById(int id);

// 实现接口
    @Override
    public Student selectStudentById(int id) {
        Student student = null;
        try(SqlSession sqlSession = MyBatisUtil.getSqlSession()) {

            //根据id查询数据操作
            student = sqlSession.selectOne("selectStudentById", id);
        }
        return student;
    }

3:添加测试类

    @Test
    public void selectStudentById(){
        Student student = studentDao.selectStudentById(3);
        System.out.println(student);
    }
MyBatis模糊查询

1:修改StudentMapper.xml文件中的内容

<select id="selectStudentByName" resultType="student">
    SELECT id,name,age,score FROM t_student where name like '%' #{name} '%'
</select>

2:在StudentDao中添加接口,在实现类中实现接口

// 接口
List<Student> selectStudentByName(String name);

// 接口实现
@Override
public List<Student> selectStudentByName(String name) {
    List<Student> result = null;

    try(SqlSession sqlSession = MyBatisUtil.getSqlSession()) {

        //查询数据操作
        result = sqlSession.selectList("selectStudentByName",name);
    }

    return result;
}

3:添加测试类

@Test
public void selectStudentByName(){
    List<Student> students = studentDao.selectStudentByName("张");
    students.forEach((student)->{
        System.out.println(student);
    });
}

# 模糊查询的另一种写法

<select id="selectStudentByName" resultType="student">
    SELECT id,name,age,score FROM t_student where name like '%${value}%'
</select>

因为我们传入的name是String字符串类型,所以这里需要注意的是${}中的内容只能写value,如果写上name会报错

可以通过控制台打印的sql语句看出来

 

SELECT id,name,age,score FROM t_student where name like '%张%'

 

上面这种方式相当于直接拼接到字符串中,该方式可能会存在SQL注入的问题。

$和#的区别

#其实是占位符,通过控制台打印的sql语句可以看出,#是以?进行占位的,#可以防止SQL注入的问题

$是字符串拼接,所添加的参数会被直接拼接到SQL语句中(如上所示),该方式会有SQL注入问题,

建议使用#{}

...

MyBatis中字段名和属性名不一致的情况

在开发过程中,可能会遇到数据库表中字段名和实体类中的属性名不一致的情况

例如在数据库表t_student中有有一个字段为 address ,然后再实体类Student中命名为 addr,如果想要进行操作,可利用下面的方式

## 使用别名方式

    <select id="selectStudentByAddress" resultType="student">
        SELECT id,name,age,score,address addr FROM t_student where id=#{id}
    </select>

## 使用结果映射

将数据库中的字段和实体类中的字段建立一个映射关系

    <resultMap id="studentMapper" type="student">
        <id column="id" property="id" />
        <result column="address" property="addr" />
    </resultMap>

    <select id="selectStudentByAddress" resultType="studentMapper">
        SELECT id,name,age,score,address FROM t_student where id=#{id}
    </select>

在标签resultMap中的属性id的值设置为 studentMapper,然后再标签select张的属性resultType的值设置为与resultMap相同的studentMapper

resultMap中的type来指定要映射的实体类

再resultMap中添加一个id的属性来指定主键,可以提高mybatis的查询性能 

...

posted @ 2019-04-13 22:49  一头牛这么多人放  阅读(263)  评论(0编辑  收藏  举报