package cn.itcast.dao;

import cn.itcast.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

public interface UserDao extends JpaRepository<User,Integer>, JpaSpecificationExecutor<User> {

    /**
     * 根据客户名称查询
     *      使用jpql形式查询
     * jpql: from User where name = ?
     *
     * 配置jpql语句使用@Query注解
     */
    @Query(value = "from User where name = ?1")
    public User findJpql(String name);

    /**
     * 根据客户名称和客户id查询客户
     *      jpql: from User where name = ? and id = ?
     * 默认情况下
     *      占位符的位置要与jpql语句的位置相同
     * 可以指定位置
     *      用?索引的方式，指定站位的取值来源
     */
    @Query(value = "from User where name = ?1 and id = ?2")
    public User findUserNameAndId(String username, Integer userId);

    /**
     * 根据ID更新客户的名称
     *  更新5号客户的名称，将名称改为张三，男
     *  sql: update jpa set name = ?,sex = ? where id = ?
     *  jpql: update User set name = ?1,sex = ?2 where id = ?3
     */
    @Query(value = "update User set name = ?1,sex = ?2 where id = ?3")
    @Modifying//当前执行的方法是一个更新操作
    public void updateUser(String name, String sex, Integer id);

    /**
     * @Query(value = "")
     * value: 可以写jpql也可以写sql
     * nativeQuery(默认值为false): false (jpql查询) | true (本地查询sql查询)
     *
     * 使用sql形式查询
     *      查询全部客户
     *      select * from jpa
     */
    @Query(value = "select * from jpa",nativeQuery = true)
    public List<User> findSql();

    @Query(value = "select * from jpa where name like ?1",nativeQuery = true)
    public List<User> findSql1(String name);


    /**
     * 方法名的约定:
     *      findBy: 查询
     *              对象中的属性名(首字母大写),查询的条件
     *      findByName: 根据用户名查询
     *  在Jpa的运行阶段会根据方法名称进行解析
     *          会根据方法名称解析 findBy  xxx(实体类)
     *                                  属性名  where name =
     */

    public User findByName(String name);

    public User findByNameAndAgeAndSex(String name, Integer age,String sex);

    /**
     * 默认的是=查询，findBy + 属性名称
     *
     *  模糊查询
     *  findBy + 属性名 + 查询方式(like | isnull)
     */
    public List<User> findByNameLike(String name);

    /**
     * 多条件查询
     * findBy + 属性名 + 查询方式 + 多条件连接符(and|or) + 属性名 + 查询方式
     */
    public List<User> findByNameLikeAndAge(String name, Integer age);
}
