SpringBoot入坑-持久化操作

  前面內容中我們已經瞭解到了SpringBoot關於參數傳遞的相關知識,本篇我們一起來學習一下SpringBoot關於數據庫持久化操作的知識,這裏我們使用JPA進行數據庫的持久化操作。

  首先由於我們需要進行數據庫的操作,所以我們需要引入mysql的驅動包;這裏我們介紹兩種數據庫持久化操作:JdbcTemplate和JpaRepository所以同樣需要引入相應的包;這裏爲例方便進行數據的返回,我們引入阿里的fastjson:

<!-- mysql數據庫連接 start -->
        <!-- MYSQL -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- Spring Boot JDBC -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!-- Spring Data JPA -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- mysql數據庫連接 end -->

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.44</version>
        </dependency>

  接下來我們需要配置properties文件:

spring.datasource.url=jdbc:mysql://localhost:3306/girl
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.jpa.show-sql:true
spring.jpa.hibernate.ddl-auto:update

  這裏設置數據庫配置,當然我們也可以使用yml進行數據庫連接配置。

  有了數據庫連接,下面我們配置一下數據庫表映射:

@Entity
@Table(name = "girl")
public class Girl implements Serializable{

    private static final long serializableUID = 1L;

    @Id
    @GeneratedValue
    private Integer id;
    @Column(name = "name")
    private String name;
    @Column(name = "age")
    private Integer age;
    @Column(name = "birthday")
    private Date birthday;

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

  對於註解的含義,大家如有不懂可以到度娘搜一下,這裏不再贅述。

  配置好數據庫映射,下面我們就可以進行持久化操作了,這裏我們使用三層結構:action、service、dao,來實現持久化操作。這裏我們首先使用JdbcTemplate進行持久化操作。

  編寫我們的dao層業務邏輯:

@Repository
public class GirlDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public List<Girl> findGirls(){
        return jdbcTemplate.query("SELECT * FROM girl", new RowMapper<Girl>(){
            @Override
            public Girl mapRow(ResultSet resultSet, int i) throws SQLException {
                Girl girl = new Girl();
                girl.setId(resultSet.getInt("id"));
                girl.setName(resultSet.getString("name"));
                girl.setAge(resultSet.getInt("age"));
                girl.setBirthday(resultSet.getDate("birthday"));
                return girl;
            }
        });
    }

}

  這裏簡單說一下註解 @Service用於標註業務層組件、@Controller用於標註控制層組件(如struts中的action)、@Repository用於標註數據訪問組件,即DAO組件、@Component泛指組件,當組件不好歸類的時候,我們可以使用這個註解進行標註。

  下面編寫我們的service層:

@Service
public class GirlService {

    @Autowired
    private GirlDao girlDao;

    public List<Girl> findGirls(){
        List<Girl> girls = girlDao.findGirls();
        return girls;
    }

}

  通過@Autowired註解將Dao層注入

  最後是我們的控制層Action:

@RestController
public class GirlAction {

    @Autowired
    private GirlService girlService;

    @RequestMapping(value = "/findGirls", method = RequestMethod.GET)
    public String findGirls(){
        List<Girl> girls = girlService.findGirls();
        return JSON.toJSONString(girls);
    }

}

  到這裏我們的第一個例子就完工了,啓動項目,輸入http://localhost:8080/findGirls


   下面我們來看一下如何JpaRepository進行持久化操作,JPA是需要Provider來實現其功能的,Hibernate就是JPA Provider中很強的一個,應該說無人能出其右。從功能上來說,JPA就是Hibernate功能的一個子集。看到這裏我想你大概已經猜到JPA的用法了。下面我們簡單一起來使用一下。

  這裏JpaRepository就類似與上面的Dao層,爲了方便理解,這裏我就將JpaRepository作爲Dao層處理:

public interface GirlDaoJpa extends JpaRepository<Girl, Integer> {

    List<Girl> getGirlsByName(final String name);

    @Query("select g from Girl g where g.name = ?1")
    List<Girl> findGirlsByName(String name);

}

  你沒有看錯這裏的JpaRepository是一個接口,我們不需要進行接口實現,這就是JpaRepository的便利之處。如何進行使用呢?

  編寫我們的service層:

@Service
public class GirlServiceJpa {

    @Autowired
    private GirlDaoJpa girlDaoJpa;

    public Girl saveGirl(Girl girl){
        return  girlDaoJpa.save(girl);
    }

    public List<Girl> getGirlsByName(String name){
        return girlDaoJpa.getGirlsByName(name);
    }

    public List<Girl> findGirlsByName(String name){
        return girlDaoJpa.findGirlsByName(name);
    }

    public List<Girl> findGirls(){
        return girlDaoJpa.findAll();
    }

}

  不知道你注意到沒有,我並沒有在接口中添加save、findAll方法,這是因爲JpaRepository默認爲我們提供了保存和查詢方法。

  最後是我們的控制層邏輯:

@RestController
public class GirlJpaAction {

    @Autowired
    private GirlServiceJpa girlServiceJpa;

    @RequestMapping(value = "/saveGirlJAP", method = RequestMethod.POST)
    public String saveGirl(){
        Girl girl = new Girl();
        girl.setName("jap測試1");
        girl.setAge(26);
        girl.setBirthday(new Date());
        girl = girlServiceJpa.saveGirl(girl);
        if(null != girl && null != girl.getId()){
            return "添加成功";
        }else{
            return "添加失敗";
        }
    }

    @RequestMapping(value = "/getGirlByNameJAP", method = RequestMethod.GET)
    public String getGirlByName(){
        List<Girl> girls = girlServiceJpa.getGirlsByName("abc");
        return JSON.toJSONString(girls);
    }

    @RequestMapping(value = "/findGirlByNameJAP", method = RequestMethod.GET)
    public String findGirlByName() {
        List<Girl> girls = girlServiceJpa.findGirlsByName("abc");
        return JSON.toJSONString(girls);
    }

    @RequestMapping(value = "/findGirlsJPA", method = RequestMethod.GET)
    public String findGirls(){
        List<Girl> girls = girlServiceJpa.findGirls();
        return JSON.toJSONString(girls);
    }
}

   到這裏我麼關於JPA的簡單實用介紹完畢,最後我再補充三點。

  1、@Query通過註解參數使用:

@Query("select g from Girl g where g.name = :name")
List<Girl> findGirlsByName(@Param("name") String name);

  2、原生sql使用:

@Query(value = "select * from girl g where g.name like %:name%", nativeQuery = true)
List<Girl> findGirlsByName(@Param("name") String name);

  注意紅色字段,兩者的區別之處。

  最後聊一下JPA分頁查詢:

@Override
Page<Girl> findAll(@PageableDefault(page = 1, size = 20, sort = {"id"}, direction = Sort.Direction.ASC) Pageable pageable);

  這裏的@PageableDefault幫助我們個性化的設置pageable的默認配置。例如@PageableDefault(page = 1, size = 20, sort = { "id" }, direction = Sort.Direction.ASC)表示默認情況下我們按照id正序排列,每一頁的大小爲20,取第一頁數據。

  Pageable是一個接口,這裏我們需要編寫一個接口實現:

public class MyPageable implements Pageable {
    private int pageNumber;//當前請求分頁
    private int pageSize;//頁容量
    private Sort sort;//排序

    public void setPageNumber(int pageNumber) {
        this.pageNumber = pageNumber;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public void setSort(Sort sort) {
        this.sort = sort;
    }

    @Override
    public int getPageNumber() {
        return pageNumber;
    }

    @Override
    public int getPageSize() {
        return pageSize;
    }

    @Override
    public int getOffset() {
        return (pageNumber-1)*pageSize;
    }

    @Override
    public Sort getSort() {
        return sort;
    }

    @Override
    public Pageable next() {
        this.pageNumber = this.pageNumber+1;
        return this;
    }

    @Override
    public Pageable previousOrFirst() {
        this.pageNumber = 0 < this.pageNumber ? this.pageNumber-1 : 1;
        return this;
    }

    @Override
    public Pageable first() {
        this.pageNumber = 1;
        return this;
    }

    @Override
    public boolean hasPrevious() {
        return false;
    }
}

  好了配置好分頁持久層邏輯,下面就是我們的service層邏輯了:

public List<Girl> findGirlsByPage(Integer stateIndex, Integer maxNum){
        MyPageable myPageable = new MyPageable();
        myPageable.setPageNumber(stateIndex);
        myPageable.setPageSize(maxNum);
        myPageable.setSort(new Sort(Sort.Direction.DESC, new String[]{"id"}));
        return girlDaoJpa.findAll(myPageable).getContent();
    }

  這裏注意一個默認查詢返回的是Page<Girl>,我們通過getContent可以得到我們的List數據。

  最後是我們的action層:

@RequestMapping(value = "/findGirlsByPageJPA", method = RequestMethod.GET)
    public String findGirlsByPage(){
        List<Girl> girls = girlServiceJpa.findGirlsByPage(1, 5);
        return JSON.toJSONString(girls);
    }

   好了到這裏關於SpringBoot的相關內容就先和大家探討到這裏,如果您與更好的見解,歡迎留言討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章