idea 建立JPA項目(一)


一、建立項目

 

依賴項選擇:

 

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>JPADemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>JPADemo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

 二、設置數據源 application.properties

#應用名稱
spring.application.name=springboot-demo
server.port=8888
server.servlet.context-path=/website
#編碼格式
server.tomcat.uri-encoding=utf-8
#數據庫相關配置
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.url=jdbc:sqlserver://127.0.0.1:1433/springbootTestDB
spring.datasource.username=sa
spring.datasource.password=6617saSA

#指定連接池最大的空閑連接數量
spring.datasource.max-idle=10
#指定連接池等待連接返回的最大等待時間,毫秒單位
spring.datasource.max-wait=10000
#指定必須保持連接的最小值(For DBCP and Tomcat connection pools)
spring.datasource.min-idle=5
#指定啟動連接池時,初始建立的連接數量
spring.datasource.initial-size=5
#session生命周期
server.servlet.session.timeout=30m

三、創建User的實體類(省略了getter&setter方法)

package com.example.jpademo.Entity;
import lombok.Data;
import javax.persistence.*;
/*使用JPA注解配置映射關系,告訴JPA這是一個實體類(和數據表映射的類)*/
@Data
@Entity
@Table(name = "t_user") //@Table來指定和哪個數據表對應;如果省略,默認表名就是該類名的小寫:user
public class User {
    @Id //表示這個屬性是數據表中的主鍵
    @GeneratedValue(strategy = GenerationType.IDENTITY) //還是一個自增的主鍵
    private Long id;
    @Column(name = "firstName", length = 50) 
    private String firstName;
    @Column(name = "lastName", length = 50)
    private String lastName;
    @Column //省略的情況,默認列名就是屬性名,均是小寫
    private String Email;  //String數據庫默認定義為varchar(255)

    protected User() {};
    public User(String firstName,String lastName){
        this.firstName=firstName;
        this.lastName=lastName;
    }
}

 

使用JPA的一個好處就是,它能夠根據實體類自動幫我們創建對應的數據庫表,只需簡單配置幾步即可:
在application.properties文件中增加(jpa 也是spring下的一個屬性,所以它也是在spring這個層級下的):

#update:表的生成策略,第一次啟動根據實體建立表結構,之后啟動會根據實體的改變更新表結構,之前的數據都在。 
spring.jpa.hibernate.ddl-auto=create 
#在控制台輸出SQL 
spring.jpa.show-sql=true 
spring.jpa.properties.hibernate.format_sql=true

 

運行主程序,錯誤!!!

 

 四、安裝Sql Server JDBC驅動

 建立目錄jdbc , 將mssql-jdbc-6.4.0.jre8.jar拷貝到該目錄,加入庫中:

 

運行仍然錯誤!

 

 錯誤原因:數據源的url定義錯誤

錯誤:spring.datasource.url=jdbc:sqlserver://127.0.0.1:1433/springbootTestDB

正確:spring.datasource.url=jdbc:sqlserver://127.0.0.1:1433;DatabaseName=springbootTestDB

 

修改后運行結果:

 

 建立的數據庫:

 

 

 

說明:

JPA命名數據庫字段的規則: 

@Column(name = "firstName", length = 50) private String firstName;
雖然用
@Column 命名了數據庫字段名稱,但是數據庫中仍然用 first_name 而不是 firstName , 原因:駝峰命名的字段改為用下划線隔開的的方式。

如果改為
@Column(name = "firstname", length = 50) 改為小寫,數據庫字段名稱就是 firstname
private String firstName;

默認Java對象的駝峰式命名對應數據庫的下划線命名

五、創建接口(持久層接口)

JPA中有許多封裝好的對數據庫進行操作的方法,不需要再寫sql語句,而是直接調用其中的方法,就可以完成對數據的操作。持久層接口需繼承JpaRepository類。

package com.example.jpademo.Dao;
import com.example.jpademo.Entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User,Long> {
}

 

 六、修改入口類

package com.example.jpademo;

import com.example.jpademo.Dao.UserRepository;
import com.example.jpademo.Entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class JpaDemoApplication {
    private static final Logger log= LoggerFactory.getLogger(JpaDemoApplication.class);
    public static void main(String[] args)
    {
        SpringApplication.run(JpaDemoApplication.class, args);
    }

    @Bean
    public CommandLineRunner demo(UserRepository respository)
    {
        return (args) -> {
            respository.save(new User("張","少華"));
            respository.save(new User("李","三立"));
            respository.save(new User("王","大海"));
            respository.save(new User("王","大海"));
            respository.save(new User("王","大海"));

            log.info("-----------------------------------");
            for(Object user: respository.findAll()) {
                log.info(user.toString());
            }

            log.info("-----------------------------------");
            respository.findById(1L).ifPresent(
                    user-> {
                        log.info("User found with findBtId(1L):");
                        log.info(user.toString());
                    }
            );
        };
    }
}

 

 運行結果:

 

七、程序擴展:創建UserCrudRepository

package com.example.jpademo.Dao;
import com.example.jpademo.Entity.User;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
public interface UserCrudReposity extends CrudRepository<User,Long> {
    List<User> findByLastName(String lastName);    //根據JPA命名規則,自動生成SQL
}

八、修改入口類的代碼

package com.example.jpademo;

import com.example.jpademo.Dao.UserCrudReposity;
import com.example.jpademo.Dao.UserRepository;
import com.example.jpademo.Entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class JpaDemoApplication {
    private static final Logger log= LoggerFactory.getLogger(JpaDemoApplication.class);
    public static void main(String[] args)
    {
        SpringApplication.run(JpaDemoApplication.class, args);
    }

    @Bean
    public CommandLineRunner demo(UserCrudReposity respository)
    {
        return (args) -> {
            respository.save(new User("張","少華"));
            respository.save(new User("李","三立"));
            respository.save(new User("王","大海"));
            respository.save(new User("王","大海"));
            respository.save(new User("王","大海"));
            log.info("");
            log.info("-----------------------------------");
            for(Object user: respository.findAll()) {
                log.info(user.toString());
            }
            log.info("");
            log.info("-----------------------------------");
            respository.findById(1L).ifPresent(
                    user-> {
                        log.info("User found with findBtId(1L):");
                        log.info(user.toString());
                    }
            );
            log.info("");
            log.info("\n\n------------ 以大海的查詢結果 -----------------------");
            for(Object user: respository.findByLastName("大海")) {
                log.info(user.toString());
            }

            log.info("\n\n------------ 以大海的查詢結果 -----------------------");
            respository.findByLastName("大海").forEach(user->{     // 默認的命名規則
                log.info(user.toString());
            });
        };
    }
}

 

運行結果:

 

 九、JPA訪問數據庫的命名規則(命名查詢)

public interface UserCrudReposity extends CrudRepository<User,Long> {
    List<User> findByLastName(String lastName);
}

前面定義的接口中的方法:List<User> findByLastName(String lastName) 並沒有實現代碼,這里JPA采用了默認的命名規則,參見:

https://docs.spring.io/spring-data/jpa/docs/2.0.9.RELEASE/reference/html/#jpa.repositories    參見  5.3.2. 的Table 3

 使用命名查詢來聲明實體查詢是一種有效的方法,並且適用於少量查詢。

 

十、使用 @Query注釋創建自定義查詢

 

package com.example.jpademo.Dao;
import com.example.jpademo.Entity.User;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
public interface UserCrudReposity extends CrudRepository<User,Long> {
    List<User> findByLastName(String lastName);
 @Query("select u from User u where u.lastName like %?1% or u.Email like %?2%")
    List<User> findByEmailAndFirstName(String lastname , String email);
}

十一、定義控制器

package com.example.jpademo.Controller;

import com.example.jpademo.Dao.UserCrudReposity;
import com.example.jpademo.Entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@Controller
@RequestMapping(path="/demo")
public class UserController {
    //@Autowired是spring的自動裝配,可用於構造器、變量域、方法、注解類型上。當需要從bean工廠中獲取一個bean時,
    // Spring會自動為我們裝配該bean中標記為@Autowired的元素。
    @Autowired
    private UserCrudReposity userCrudReposity;
    @GetMapping(path="/add")
    @ResponseBody
    //在瀏覽器中輸入 http://localhost:8888/website/demo/add?firstname=張&lastname=宇航,
    public String addNewUser(@RequestParam String firstname,@RequestParam String lastname)
    {
        User user=new User(firstname,lastname,"");
        userCrudReposity.save(user);
        return "saved";
    }

    //http://localhost:8888/website/demo/finduser/大海
    @GetMapping(path="/finduser/{lastname}")  //1個占位符
    @ResponseBody
    public String finduser(@PathVariable("lastname") String lastname) {
        List<User> userList= userCrudReposity.findByLastName(lastname);
        String users="";
        for(User user:userList) {
            users+=user.toString()+"   ";
        }
        return users;
    }

    //http://localhost:8888/website/demo/finduser?lastname=大海&email=139
    @GetMapping(path="/finduser")  //用請求參數
    @ResponseBody
    public String finduser1(@RequestParam String lastname,@RequestParam String email) {
        List<User> userList= userCrudReposity.findByEmailAndFirstName(lastname,email);
        String users="";
        for(User user:userList) {
            users+=user.toString()+"   ";
        }
        return users;
    }

    //http://localhost:8888/website/demo/finduser/大海/139
    @GetMapping(path="/finduser/{lastname}/{email}")  //2個占位符
    @ResponseBody
    public String finduser2(@PathVariable("lastname") String lastname, @PathVariable("email") String email) {
        List<User> userList= userCrudReposity.findByEmailAndFirstName(lastname,email);
        String users="";
        for(User user:userList) {
            users+=user.toString()+"  ";
        }
        return users;
    }

}

 

 十二、擴展

數據庫訪問:

package com.example.jpademo.Dao;
import com.example.jpademo.Entity.User;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
public interface UserCrudReposity extends CrudRepository<User,Long> {
    List<User> findByLastName(String lastName);

    @Query("select u from User u where u.lastName like %?1%  or  u.Email like %?2%")
    List<User> findByEmailAndFirstName(String lastname  , String email);

    @Query("select u from User u where u.firstName=?1 and u.lastName=?2")
    public List<User> queryUser(String fname,String lname);

    @Query("select u from User u where u.firstName=:fname and u.lastName=:lname")
    public List<User> queryUser1(@Param("fname") String firstname, @Param("lname") String lastname);

    @Transactional
    @Modifying(clearAutomatically = true)
    //@Modifying
    @Query("update User u set u.Email = ?1 where u.lastName=?2")
    int updateEmailBylastName(String email,String lastName);
}

控制器:

package com.example.jpademo.Controller;

import com.example.jpademo.Dao.UserCrudReposity;
import com.example.jpademo.Entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@Controller
@RequestMapping(path="/demo")
public class UserController {
    //@Autowired是spring的自動裝配,可用於構造器、變量域、方法、注解類型上。當需要從bean工廠中獲取一個bean時,Spring會自動為我們裝配該bean中標記為@Autowired的元素。
    //@Autowired-標記要通過 Spring 依賴注入自動裝配的構造函數,字段或 setter 方法。
    @Autowired
    private UserCrudReposity userCrudReposity;
    @GetMapping(path="/add")
    @ResponseBody
    //在瀏覽器中輸入 http://localhost:8888/website/demo/add?firstname=張&lastname=宇航
    public String addNewUser(@RequestParam String firstname,@RequestParam String lastname)
    {
        User user=new User(firstname,lastname,"");
        userCrudReposity.save(user);
        return "saved";
    }

    //http://localhost:8888/website/demo/finduser/大海
    @GetMapping(path="/finduser/{lastname}")  //1個占位符
    @ResponseBody
    public String finduser(@PathVariable("lastname") String lastname) {
        List<User> userList= userCrudReposity.findByLastName(lastname);
        String users="";
        for(User user:userList) {
            users+=user.toString()+"   ";
        }
        return users;
    }

    //http://localhost:8888/website/demo/finduser?lastname=大海&email=139
    @GetMapping(path="/finduser")  //用請求參數
    @ResponseBody
    public String finduser1(@RequestParam String lastname,@RequestParam String email) {
        List<User> userList= userCrudReposity.findByEmailAndFirstName(lastname,email);
        String users="";
        for(User user:userList) {
            users+=user.toString()+"   ";
        }
        return users;
    }

    //http://localhost:8888/website/demo/finduser/大海/139
    @GetMapping(path="/finduser/{lastname}/{email}")  //2個占位符
    @ResponseBody
    public String finduser2(@PathVariable("lastname") String lastname, @PathVariable(value = "email") String email) {
        List<User> userList= userCrudReposity.findByEmailAndFirstName(lastname,email);
        String users="";
        for(User user:userList) {
            users+=user.toString()+"  ";
        }
        return users;
    }

 @GetMapping(path="/queryUser") @ResponseBody public String queryUser(@RequestParam String firstname,@RequestParam String lastname) { List<User> userList= userCrudReposity.queryUser(firstname,lastname); String users=""; for(User user:userList) { users+=user.toString()+"  "; } return users; } @GetMapping(path="/queryUser1") @ResponseBody public String queryUser1(@RequestParam String firstname,@RequestParam String lastname) { List<User> userList= userCrudReposity.queryUser1(firstname,lastname); String users=""; for(User user:userList) { users+=user.toString()+"  "; } return users; } @GetMapping(path="/update") @ResponseBody public String update(@RequestParam String lastname,@RequestParam String email) { userCrudReposity.updateEmailBylastName(email,lastname); return "update"; }
}

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM