一、 Java API 不用config配置文件

SqlSessionUtil.java

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import dao.PersonMapper;
import entity.Person;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;

/**
 * @author 发现更多精彩  关注公众号:木子的昼夜编程
 * 一个生活在互联网底层,做着增删改查的码农,不谙世事的造作
 * @create 2021-09-04 17:15
 */
public class SqlSessionUtil {
    // 数据库配置
    private static String user = "root";
    private static String password = "123456";
    private static Integer port = 3306;
    private static String url = "jdbc:mysql://127.0.0.1:3306/test";
    public static SqlSession getSession(){
        // 1. 创建 DataSources
        MysqlDataSource dataSource = new MysqlDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(password);
        dataSource.setPort(port);
        dataSource.setUrl(url);
        dataSource.setUseSSL(true);
        // 2. 创建 TransactionFactory
        TransactionFactory tsf = new JdbcTransactionFactory();
        // 3. 创建 Environment
        Environment ev = new Environment("development", tsf, dataSource);
        // 4. 创建Configuration
        Configuration cfg = new Configuration(ev);
        // 4.1 注册别名
        cfg.getTypeAliasRegistry().registerAlias("person", Person.class);
        // 也可以直接指定包路径
        // cfg.getTypeAliasRegistry().registerAliases("entity");
        // 4.2 添加Mapper映射
        cfg.addMapper(PersonMapper.class);
        // 也可以直接指定包名
        //cfg.addMappers("dao");
        // 5. 创建SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
        // 6. 创建SqlSessionFactory
        SqlSessionFactory factory  = ssfb.build(cfg);
        return factory.openSession();
    }
}

PersonMapper.java

package dao;


import entity.Person;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * @author 发现更多精彩  关注公众号:木子的昼夜编程  分享一个生活在互联网底层做着增删改查的码农的感悟与学习
 * @create 2021-08-30 21:54
 */
public interface PersonMapper {

    // 测试
    @Select({"select name,age from person"})
    List<Person> select();
}

TestMain02.java

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import dao.PersonMapper;
import entity.Person;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;

import java.sql.SQLException;
import java.util.List;

/**
 * @author 发现更多精彩  关注公众号:木子的昼夜编程
 * 一个生活在互联网底层,做着增删改查的码农,不谙世事的造作
 * @create 2021-09-04 10:26
 */
public class TestMain02 {

    public static void main(String[] args) throws SQLException {

        // 7. 创建 SqlSession
        try (SqlSession sqlSession = SqlSessionUtil.getSession()) {
            // 8. 后边就是常规操作了
            PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
            List<Person> list = mapper.select();
            System.out.println(list);
        }
    }
}

输出结果:

Mybatis 入门 第十篇_hibernate

可以看到这里没有用xml配置文件,创建SqlSession、查询数据库都是在JAVA类里完成的

二、 Java API 增删改查

我经历过很多项目,大部分的项目负责人包括我自己不是很喜欢用注解的方式写SQL,原因可能因为

第一不好管理sql ,第二维护成本比较高 可能还有其他原因,但是不管用不用,你不能不会,你必须掌握简单的使用方式,保不齐哪一天你去一个项目组,那技术负责人就喜欢用注解方式写SQL呢?

下边我写一个增删改查的例子:

PersonMapper.java

package dao;


import entity.Person;
import org.apache.ibatis.annotations.*;

import java.math.BigDecimal;
import java.sql.PseudoColumnUsage;
import java.util.List;

/**
 * @author 发现更多精彩  关注公众号:木子的昼夜编程  分享一个生活在互联网底层做着增删改查的码农的感悟与学习
 * @create 2021-08-30 21:54
 */
public interface PersonMapper {

    // 列表
    @Select({"select id , `name`,age,salary,job_name jobName from person"})
    List<Person> select();

    // 增加
    @Insert("insert into person (`name`,job_name,salary,age) value (#{name},#{jobName},#{salary},#{age})")
    void insert(Person p);

    // 修改工资
    @Update("update person set salary = #{salary} where id = #{id}")
    void update(@Param("id") Long id, @Param("salary") BigDecimal salary);

    // 删除记录
    @Delete("delete from person where id = #{id}")
    void delete(Long id);

    // 根据薪资范围查询person
    @Select("select  id ,  name,age,salary,job_name jobName from person where salary between #{start} and #{end}")
    List<Person> listBySalary(@Param("start") BigDecimal start, @Param("end") BigDecimal end);


}

TestMain03.java

import dao.PersonMapper;
import entity.Person;
import org.apache.ibatis.session.SqlSession;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

/**
 * @author 发现更多精彩  关注公众号:木子的昼夜编程
 * 一个生活在互联网底层,做着增删改查的码农,不谙世事的造作
 * @create 2021-09-04 10:26
 */
public class TestMain03 {

    public static void main(String[] args) throws SQLException {

        try (SqlSession sqlSession = SqlSessionUtil.getSession()) {
            PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
            // 1. 查询
            System.out.println("初始值:");
            List<Person> list = mapper.select();
            System.out.println(list);
            // 2. 删除
            mapper.delete(1L);
            System.out.println("删除后的值:");
            List<Person> list02 = mapper.select();
            System.out.println(list02);
            // 3. 新增值
            Person insert =  new Person();
            insert.setName("小明");
            insert.setAge(18);
            insert.setJobName("开发工程师(初级)");
            insert.setSalary(BigDecimal.valueOf(60000));
            mapper.insert(insert);
            System.out.println("新增后的值:");
            List<Person> list03 = mapper.select();
            System.out.println(list03);
            // 4. 更新值 给小月月涨工资
            mapper.update(2L, BigDecimal.valueOf(888888));
            System.out.println("更新后的值:");
            List<Person> list04 = mapper.select();
            System.out.println(list04);
            // 5. 查询工资是5万到10万的员工
            List<Person> lists = mapper.listBySalary(BigDecimal.valueOf(50000), BigDecimal.valueOf(100000));
            System.out.println("根据薪资范围查询的值:");
            System.out.println(lists);


        }
    }
}

输出结果:

Mybatis 入门 第十篇_sql_02

跟用xml写sql差不多吧~

三、读取插入后自增列的值

@Insert("insert into person (`name`,job_name,salary,age) value (#{name},#{jobName},#{salary},#{age})")
    @SelectKey(resultType = Long.class, keyProperty = "id",
            statement = {"SELECT LAST_INSERT_ID()"}, before = false)
    Long insert(Person p);
public static void main(String[] args){

    try (SqlSession sqlSession = SqlSessionUtil.getSession()) {
        PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
        // 3. 新增值
        Person insert =  new Person();
        insert.setName("小明");
        insert.setAge(18);
        insert.setJobName("开发工程师(初级)");
        insert.setSalary(BigDecimal.valueOf(60000));
        mapper.insert(insert);
        System.out.println("插入数据自增id:"+insert.getId());
    }
}

经验证,是可以返回的。

四、注解sql怎么动态呢 - 第一种方法

例如根据名称是否为空来查询,前几篇写过的,不知道有人记得没。

@Select({
    "<script>",
    "select * from person ",
    "<where>",
    "<if test='name != null and name !=\"\" '>name like concat('%',#{name},'%')</if>",
    "</where>",
    "</script>"
})
List<Person> select(@Param("name") String name);

五、 注解Sql怎么动态呢 - 第二种方法 SelectProvider

可以指定Java类来组合自己的SQL

PersonMapper.java

@SelectProvider(type = MySqlBuilder.class , method = "listByNameAndAge")
List<Person> selectByAgeAndName(@Param("name") String name, @Param("age") Integer age);

MySqlBuilder.java

package sql;

import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.jdbc.SQL;

/**
 * @author 发现更多精彩  关注公众号:木子的昼夜编程
 * 一个生活在互联网底层,做着增删改查的码农,不谙世事的造作
 * @create 2021-09-04 19:06
 */
public class MySqlBuilder {

    public static String listByNameAndAge(@Param("name") final String name, @Param("age") final Integer age){
        System.out.println("自定义SQL");
        return new SQL(){{
            SELECT("*");
            FROM("person  ");
            WHERE(" 1=1 ");
            if (name != null) {
                AND().WHERE("name like concat('%',#{name},'%')");
            }
            if (age != null) {
                AND().WHERE("age = #{age}");
            }
            // 排序
            ORDER_BY("id");
        }}.toString();
    }
}

测试:

public static void main(String[] args){
    try (SqlSession sqlSession = SqlSessionUtil.getSession()) {
        PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
        // 3. 新增值
        List<Person> list = mapper.selectByAgeAndName("小月", 19);
        System.out.println(list);
    }
}

这个真的就是了解,万一哪一天遇到了不会很懵逼的说这是个啥玩意,但是遇到的概率应该会很小很小

六、 上一篇说过databaseId 那注解方式是什么样的呢

@Select(value = "SELECT 'mysql' ", databaseId = "mysql")
@Select(value = "SELECT 'oracle' ", databaseId = "oracle")
@Select("SELECT '其他'")  
String getType();

可以直接写多个Select标签

七、 Results Result

像xml一样指定sql字段与实体类字段的对应关系和类型

@Results(id="personResult", value = {
    @Result(property = "name",column = "name" , 
            javaType = String.class ,jdbcType = JdbcType.VARBINARY),
    @Result(property = "jobName",column = "job_name" , 
            javaType = String.class ,jdbcType = JdbcType.VARBINARY),
    @Result(property = "age",column = "age" , 
            javaType = Integer.class ,jdbcType = JdbcType.INTEGER),
    @Result(property = "salary",column = "salary" , 
            javaType = BigDecimal.class ,jdbcType = JdbcType.DECIMAL)
})
@Select("select * from person")
List<Person> select();

其实还有很多包括**@ConstructorArgs** 、@ResultType@ResultMap等一些注解

如果想了解更多可以看一下官方文档,但是我个人觉得理解有这种实现方式即可,不用太深的了解这些东西,如果时间充足去了解了解Spring的一些原理比这个强

下集预告:

Mybatis缓存了解

有事儿没事儿关注公众号:木子的昼夜编程
Mybatis 入门 第十篇_mysql_03