spring實戰(僅僅是本人的學習筆記,可能會有錯誤,大家見諒)
簡介
1.spring是什麼?

2. spring優勢?
3. spring體系結構
Spring快速入門
開發步驟
- 導入坐标
- 建立bean
- 建立applicationContext.xml
- 在配置檔案中進行配置
- 建立ApplicationContext對象getBean
Spring配置檔案的配置
用于配置對象交由Spring來建立
預設情況下它調用的類中的無參構造函數,如果沒有無參構造函數則不能建立成功
基本屬性:
id:唯一辨別
class:Bean的全限定名稱
Bean标簽範圍配置
scope:值對象的作用範圍
取值範圍:
singleton:預設的,單例的
prototype:多裡的
request:web項目中,Spring建立一個Bean對象,将對象存入request對象
session: 将對象存入session域中
global session:Web項目中,應用在portlrt環境中,如果沒有portlet環境那麼globalSession 相當于session
Bean生命周期設定
Bean執行個體化的三種方式
- 無參構造
- 工廠靜态方法
- 工廠執行個體化方法執行個體化
依賴注入
如何将UserDao注入到UserServce?
Set方法
例如:
簡單方式:p命名空間
構造方法
例如:
bean容器可以注入集合,對象和普通的值
<bean id="userDao" class="com.itheima.Impl.UserDaoImpl">
<property name="list">
<list>
<value>"aaa"</value>
<value>"bbb"</value>
<value>"ccc"</value>
</list>
</property>
<property name="map">
<map>
<entry key="1" value-ref="user1"/>
</map>
</property>
<property name="properties">
<props>
<prop key="1">ppp</prop>
<prop key="2">ppp</prop>
<prop key="3">ppp</prop>
</props>
</property>
</bean>
引用其他配置檔案 分子產品開發
代碼:
Spring相關API
ApplicationContext的實作類
getBean()方法的使用:
id可以
寫類名也可以
Spring配置資料源(連接配接池的作用)
資料源(連接配接池) 的作用:
- 提高程式的性能
- 實作執行個體化資料源,初始化部分連接配接資源
- 使用連接配接資源時從資料源中擷取
- 使用完畢後将連接配接子淵歸還給資料源
常見資料源:DBCP,C3P00,BoneCP,Druid等
資料源開發步驟:
- 導入資料源的坐标和資料可驅動坐标
- 建立資料源對象
- 設定資料源的基本連接配接資料
- 使用資料子淵獲去連接配接資源和規劃資源
兩種擷取資料源的方式:
public void test2() throws Exception {
DruidDataSource dataSource=new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8");
dataSource.setPassword("123123");
dataSource.setUsername("root");
DruidPooledConnection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
@Test
//測試cp30資料源
public void test1() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8";
dataSource.setJdbcUrl(url);
dataSource.setUser("root");
dataSource.setPassword("123123");
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
通過properties擷取資料源:
//将必要的資料寫在properties中
jdbc.url=jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.username=root
jdbc.password=123123
//測試cp30資料源(加載properties版本)
public void test3() throws Exception {
ResourceBundle rb=ResourceBundle.getBundle("jdbc");
String driver=rb.getString("jdbc.driver");
String username=rb.getString("jdbc.username");
String password=rb.getString("jdbc.password");
String url=rb.getString("jdbc.url");
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setPassword(password);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setDriverClass(driver);
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
借助Spring配置資料源
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="root"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8"/>
<property name="password" value="123123"/>
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
</bean>
Spring加載Property配置檔案
核心:
Spring注解開發
Spring是輕代碼重配置的架構,配置比較繁重,影響開發效率,是以注解開發是一種趨勢,注解代替xml配置檔案可以簡化配置,提高開發效率。
Spring原始注解
主要是用于替代的配置
注意:使用注解的時候要在bean中配置元件掃描
通過@Value注入普通資料類型
@Vulue(${} )注入 properties中的資料
@Scope 設定到底讓你産生幾個Bean
Spring新注解
原始注解無法解決的事情:
SpringJunit 測試
內建步驟
Spring內建web環境
通過設定監聽器擷取spring容器檔案
- 編寫監聽類(實作 ServletContextListenser接口)
public class ContextLoaderListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//将想要放進容器中的東西建立出來
ApplicationContext app=new ClassPathXmlApplicationContext("SpringConfiguration.xml");
//建立一個serclet容器
ServletContext servletContext =servletContextEvent.getServletContext();
//将app放入接口中
servletContext.setAttribute("app",app);
System.out.println("監聽器實作建立過了");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
- 在web檔案中放入監聽器映射
<listener>
<listener-class>com.itheima.listener.ContextLoaderListener</listener-class>
</listener>
- 在web層取出這個檔案
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//擷取這個容器
ServletContext servletContext = req.getServletContext();
//擷取容器中的東西
ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app");
//實作
UserService userService = app.getBean(UserService.class);
userService.save();
}
}
在web中設定全局變量
- 在web檔案中設定全局參數
<!--web全局配置參數-->
<context-param>
<param-name>springConfiguration</param-name>
<param-value>SpringConfiguration.xml</param-value>
</context-param>
- 通過應用上下文擷取設定在web中設定的全局參數
ServletContext servletContext = req.getServletContext();
//讀取web中的全局變量
String springConfiguration = servletContext.getInitParameter("springConfiguration");
通過工具類擷取上下文應用的值
好處:以為ServletContext 的attribute的值是耦合死的,不友善程式設計,是以設計工具類來友善程式設計将想要擷取的放在上下文應用中
- 先存入
ApplicationContext app=new ClassPathXmlApplicationContext("SpringConfiguration.xml");
//建立一個serclet容器
ServletContext servletContext =servletContextEvent.getServletContext();
//将app放入接口中
servletContext.setAttribute("app",app);
System.out.println("監聽器實作建立過了");
- 編寫工具類
public class WebApplicationContext {
public static ApplicationContext getApplication(ServletContext servletContext){
return (ApplicationContext) servletContext.getAttribute("app");
}
}
- 通過工具類擷取到這個值
對于上述的這個工具類,Spring提供了一個包裝類供使用
SpringMVC簡介
開發過程
- 導入SpringMVC坐标
- 配置SpringMVC核心控制器和DispathServlet
- 建立Controller類和視圖頁面
- 使用注解配置Controller類彙總業務方法映射位址
- 配置SpringMVC核心檔案spring-mvc.xml
- 用戶端發起測試
Spring通路過程:
開發步驟:
- 導入springmvc的坐标
- 配置sprigmvc核心控制器DispathServlet
- 建立Controller類和視圖頁面
- 使用注解配置Controller類中業務方法的映厍位址
- 配置SpringMVC核心檔案spring-mvc.xml
- 用戶端發起請求測試
SpringMvc的元件解析
執行流程
注解解析:
@RequestMapping
作用:用于建立請求URL和處理方法之間的對應關系
位置:
類上:請求URL的第一集通路目錄。此處不寫的話就相當于應用 的根目錄
方法上:請求URL的第二集目錄,與類上的使用@RequestMapping标注的以及目錄一起組成通路虛拟路徑
屬性:
注解解析:
xml檔案的配置
- 内部資源視圖解析器
Spring學習筆記spring實戰(僅僅是本人的學習筆記,可能會有錯誤,大家見諒)
相關元件:
前段控制器:DispatcherServlet
處理映射器:HandlerMapping
處理擴充卡:HandlerAdapter
處理器:Handler
視圖解析器:View Resolver
視圖:View
注解和配置:
請求映射器:@RequestMapping
視圖解析器配置:
REDIRECT_URL_PREFIX=“redirect:”
FORWARD_URL_PREFIX=“forward:”
prefix=
suffix=
SpringMVC的資料響應:
(1)頁面跳轉
直接傳回字元串
通過ModelAndView對象傳回
(2)回寫資料
直接傳回字元串
傳回對象或集合
頁面跳轉:
1.傳回字元串的形式:
2.傳回ModelAndeViewer
以下5中方式均可以:
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/quick5")
public String save5(HttpServletRequest servletRequest){
servletRequest.setAttribute("username","張強");
return "success";
}
@RequestMapping("/quick4")
//modelView對象spring架構會自動注入建立
public String save4(Model model){
model.addAttribute("username","博學谷");
return "success";
}
@RequestMapping("/quick3")
//modelView對象spring架構會自動注入建立
public ModelAndView save3(ModelAndView modelAndView){
modelAndView.addObject("username","itheima");
modelAndView.setViewName("success");
return modelAndView;
}
@RequestMapping("/quick2")
public ModelAndView save2(){
//model:封裝資料
//view:展示資料
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("username","itheima");
//設定model名稱
modelAndView.setViewName("success");
return modelAndView;
}
@RequestMapping("/quick")
public String save(){
System.out.println("到達Controller層");
return "success";
}
}
回寫資料
-
直接傳回字元
Web基礎階段,用戶端通路伺服器端,如果想直接傳回寫字元串作為響應體傳回的話,隻需要使用response.getWriter().print(“Hello word”)即可,那麼在Controller中想直接回寫字元串該怎麼樣呢?
方法1. 通過response方法進行書寫
public void save6(HttpServletResponse response) throws IOException {
response.getWriter().println("zq");
}
方法2.直接傳回字元串,但是注意要對方法進行SpringBody的注釋,告知Springmvc架構,不進行視圖調準,直接進行資料響應。
@ResponseBody
public String save5() throws IOException {
return "ZQ";
}
将對象轉為joson格式傳回到頁面上
@RequestMapping("/quick8")
//告訴伺服器,我傳回的是字元串,不是個View
@ResponseBody
public String save8() throws IOException {
User user=new User();
user.setUsername("zq");
user.setAge(18);
//使用ObjectMapper類,需要配置依賴
ObjectMapper objectMapper = new ObjectMapper();
String s = objectMapper.writeValueAsString(user);
return s;
}
//objectMapper的依賴
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
-
傳回資料或集合
配置xml檔案,直接将對象轉為json傳過去
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</list>
</property>
</bean>
配置xml檔案比較麻煩,是以 可以通過配置注解來解決上面的事情,但是别忘記加入網址。
SpringMvc獲得請求參數
用戶端請求參數的格式是:name=vlaue&name=value
服務端要獲得請求參數,優勢還需要進行資料的封裝,SpringMVC可以接收如下啊類型的參數
- 基本類型參數
- POJO類型參數
- 數組類型參數
- 集合類型參數
獲得基本類型參數
Controller中的業務方法的參數名要與請求參數的name一緻,參數會自動映射比對
獲得POJO類型參數
Controller中的業務方法的POJO參數名要與請求參數的name一緻,參數會自動映射比對
獲得數組類型的參數
Controller中的業務方法數組名稱與請求參數的name一緻
封裝集合類型的參數
獲得集合參數時,要将集合參數包裝到一個對象中才可以,但是在對象集合前加入@RequestBody就可以直接進行擷取。
請求亂碼問題的解決
在web.xml配置全局過濾器即可
<!-- 配置資源過濾器解決亂碼問題-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
@RequestParam注解
将參數綁定,将請求的不是參數清單中對應的值得時候可以進行過參數的綁定,進而導緻仍然能夠列印這和名字。
擷取Restful風格的參數
通過@PathVariable注解記性占位符的比對擷取工作
自定義類型裝換器
springmvc已經提供了一些蟾宮的類型轉換器,例如将客戶的字元串轉為int
但是不是所有的資料類型都提供了轉換器,沒有提供的就需要自定義轉換器,例如:日期類型的資料就需要自定義轉換器。
步驟:
- 自定義轉換器實作Converter接口
- 在配置檔案中聲明轉換器
- 在中引用轉換器
獲得Servlet相關的API
擷取請求頭
檔案上傳
單檔案上傳:
1.檔案上傳用戶端三要素
表單項type=“file” 表單的送出方式是post 表單的enctype屬性是多部分呢表單形式,即enctype=“multipart/form-data”
2.檔案上傳原理
單檔案上傳實作:
3.注意,這裡的名字要和jsp中名字一一緻
多檔案上傳:
隻需要在jsp中多準備一個控件,然後在Controller層中設定一個數組,進行循環操作。
JdbcTemplate
具體代碼demo如下:
- 導入坐标,這裡面有一個注意事項,mysq-connector-java的版本要和mysql對應,不對應會導緻連接配接出錯的情況。
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
- 建立資料庫對應的實體類,類型和名字要對應上
public class Account {
private double money;
private String name;
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- 建立jdbcTemplate對象,并且執行資料操作
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8");
dataSource.setUser("root");
dataSource.setPassword("123123");
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
int row = jdbcTemplate.update("insert into account1 values(?,?)", "zs", 18);
System.out.println(row);
可以通過配置xml檔案來實作JdbcTempplate的建立和資料庫的連接配接
- 建立jdbc.properties檔案 new file
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.password=123123
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8
jdbc.user=root
- 配合xml檔案
<!-- 配置ComboPooledDataSource-->
<bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="password" value="${jdbc.password}"/>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
<property name="user" value="${jdbc.user}"/>
</bean>
<!-- 配置jdbcTemplate-->
<bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
<property name="dataSource" ref="comboPooledDataSource"/>
</bean>
- 調用
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate = app.getBean(JdbcTemplate.class);
int row = jdbcTemplate.update("insert into account1 values (?,?)", "ls", 188);
System.out.println(row);
增删改查模闆
@Test
//查數量
public void query(){
Long aLong = jdbcTemplate.queryForObject("select count(*) from account1", Long.class);
System.out.println(aLong);
}
@Test
public void queryOne(){
//查一個
Account account = jdbcTemplate.queryForObject("select * from account1 where name =?", new BeanPropertyRowMapper<Account>(Account.class), "zs");
System.out.println(account);
}
@Test
//查全部
public void queryAll(){
List<Account> accounts = jdbcTemplate.query("select * from account1", new BeanPropertyRowMapper<Account>(Account.class));
System.out.println(accounts);
}
@Test
public void delete(){
//删除
jdbcTemplate.update("delete from account1 where name=?","ls");
}
@Test
public void update(){
//更新
jdbcTemplate.update("update account1 set money=99999 where name=?","zs");
}
@Test
public void insert(){
//插入
jdbcTemplate.update("insert into account1 values(?,?)","ls",1565651);
}
SpringMVC攔截器
作用:
過濾器和攔截器的差別:
快速入門:
1.
public class Myinterceptor1 implements HandlerInterceptor {
//在目标方法執行之前執行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return true;
}
//在目标方法執行之後,視圖對象傳回之前執行
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
//在整個流程都執行完畢之後執行
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}
<!-- 配置攔截器-->
<mvc:interceptors>
<mvc:interceptor>
<!-- 對那些資源進行攔截-->
<mvc:mapping path="/**"/>
<bean class="com.itheima.interceptor.Myinterceptor1"/>
</mvc:interceptor>
</mvc:interceptors>
多個攔截器的執行的先後順序就是看誰在上誰在下
攔截方法說明
SpringMVC異常處理機制
異常處理思路:
異常處理的兩種方式:
- 使用SpringMVC提供的簡單異常處理器SimpleMappingExceptionResolver
- 使用Spring的異常處理接口HandlerExceptionResolver自定義自己的異常處理接口
1.使用MVC異常處理器
2. 自定義異常處理器
步驟:
public class MyExceptionResolver implements HandlerExceptionResolver {
/*
關鍵參數Exception 報異常的異常傳回對象,跳轉的錯誤視圖的資訊
*/
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ModelAndView modelAndView=new ModelAndView();
if(ex instanceof MyException){
modelAndView.addObject("info","自定義的異常");
}else if(ex instanceof ClassCastException){
modelAndView.addObject("info","類型轉換異常");
}
modelAndView.setViewName("error");
return modelAndView;
}
}
SpringAop
什麼是aop?
作用及其優勢
底層實作:
動态代理技術:
- jdk
public class ProxyTset {
public static void main(String[] args) {
//目标對象
final Target target = new Target();
//增強對象
final Advice advice = new Advice();
TargetInterface targetInterface=(TargetInterface) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
advice.before();
Object invoke = method.invoke(target, args);
advice.after();
return invoke;
}
}
);
targetInterface.save();
}
}
- cglib的動态代理
public class ProxyTset {
public static void main(String[] args) {
//目标對象
final Target target = new Target();
//增強對象
final Advice advice = new Advice();
//傳回值就是動态生成的代理技術
//1.建立增強器
Enhancer enhancer = new Enhancer();
//2.設定父類(目标 )
enhancer.setSuperclass(Target.class);
//3.設定回調
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//前置增強
advice.before();
method.invoke(target,args);
advice.after();
return null;
}
});
//4.建立代理對象
Target proxy= (Target) enhancer.create();
proxy.save();
}
}
相關概念:
解釋:
連接配接點被攔截到的方法就是連接配接點,切入點就是攔截到并且真的被增強的方法叫切入點
切面:切點加通知
注意事項:
- 需要編寫的内容: 技術實作的内容:
Spring學習筆記spring實戰(僅僅是本人的學習筆記,可能會有錯誤,大家見諒) aop底層使用哪種代理方式:Spring學習筆記spring實戰(僅僅是本人的學習筆記,可能會有錯誤,大家見諒) 知識要點:Spring學習筆記spring實戰(僅僅是本人的學習筆記,可能會有錯誤,大家見諒) Spring學習筆記spring實戰(僅僅是本人的學習筆記,可能會有錯誤,大家見諒)
基于XML的aop開發快速入門
快速入門
核心就在于xml文檔案的配置
<!--配置目标對對象-->
<bean id="target" class="com.itheima.proxy.aop.Target"/>
<!-- 配置通知-->
<bean id="myAspect" class="com.itheima.proxy.aop.MyAspect"/>
<!-- 配置織入:告訴spring架構,那些方法(切點)需要增強(前置,後置)-->
<aop:config>
<aop:aspect ref="myAspect">
<aop:before method="before" pointcut="execution(public void com.itheima.proxy.aop.Target.save())"/>
</aop:aspect>
</aop:config>
切點表達式的寫法
文法:
例子解釋:
- 指定包下面方法和類
- 指定方法下的沒有傳回值的
- 包下的任意類任意方法
- aop包以及子包都能增強
- 都任意
通知的類
切點表達式抽取
<aop:config>
<aop:aspect ref="myAspect">
<aop:pointcut id="pointcut1" expression="execution(* com.itheima.proxy.aop.*.* (..))"/>
<aop:around method="around" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
基于注解的aop開發快速入門
步驟:
- 注入目标類
@Component("target")
public class Target implements TargetInterface {
public void save() {
System.out.println("run save*********");
}
}
-
配置切面
類名的上面
@Component("myAspect")
@Aspect
public class MyAspect {
對應的增強方法
@Before("execution(* com.itheima.proxy.anno.*.* (..))")
public void before(){
System.out.println("前置增強************");
}
3.在xml檔案中配置目标類和自動代理
<context:component-scan base-package="com.itheima.proxy.anno"/>
<!-- 自動代理-->
<aop:aspectj-autoproxy/>
注解配置的AOP 類型
事務控制
程式設計式事務控制
接隻定義行為
事務定義對象:定義資訊對象
事務隔離級别
事務傳播行為
被動的封裝事務的資訊
聲明式事務控制
什麼是聲明式事務控制:
<!-- 配置平台事務管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven/>
<!-- 通知事務增強-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 設定事務的屬性資訊-->
<tx:attributes>
<!-- 這裡面可以增加多個方法-->
<tx:method name="*" isolation="DEFAULT" propagation="REQUIRED" timeout="-1" read-only="false"/>
</tx:attributes>
</tx:advice>
<!-- AOP事務的織入-->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.service.impl.*.*(..))"/>
</aop:config>
聲明式事務控制的要點:
- 平台事務配置器
- 事務通知的配置
- 事務aop織入的配置
基于注解的聲明式控制
MyBatis
原始的jdbc連接配接資料庫
插入資料
原始jdbc操作分析
什麼是mybatis
快速入門
步驟:
4.
<mapper namespace="userMapper">
<select id="findAll" resultType="com.itheima.domain.User">
select * from user
</select>
</mapper>
<!-- 配置資料源環境-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8"/>
<property name="username" value="root"/>
<property name="password" value="123123"/>
</dataSource>
</environment>
</environments>
<!--導入userMapper資源-->
<mappers>
<mapper resource="com/itheima/mapper/UserMapper.xml"/>
</mappers>
</configuration>
public class myBatisTest {
@Test
public void test1() throws IOException {
//通過Resource擷取資源檔案
InputStream resourceAsStream = Resources.getResourceAsStream(“sqlMapperConfig.xml”);
//建立Session工廠
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
//擷取Session對話
SqlSession sqlSession = build.openSession();
//調用命名空間,進行查詢
User user = new User();
user.setId(7);
user.setUsername(“lilian”);
user.setPassword(“123123”);
sqlSession.insert(“userMapper.insert”,user);
List<User> userList = sqlSession.selectList("userMapper.findAll");
System.out.println(userList);
//釋放資源
sqlSession.close();
}
}
映射檔案概述
增删改查操作
插入:
<!-- 插入操作-->
<insert id="insert" parameterType="com.itheima.domain.User">
insert into user values (#{id},#{username},#{password})
</insert>
<!-- 修改資料-->
<update id="update" parameterType="com.itheima.domain.User">
update user set username=#{username},password=#{password} where id=#{id}
</update>
<!-- 删除資料-->
<delete id="delete" parameterType="com.itheima.domain.User">
delete from user where id=#{id}
</delete>
知識小結:
增删改查映射配置與API:
MyBatis核心配置檔案層級關系
environment标簽
資料庫環境的配置,支援多環境配置
mapper
作用是用于加載映射的,加載方式有一下幾種:
properties
實際開發中,習慣将資料源的配置資訊單獨抽取成一個properties檔案,該标簽可以加載額外配置的properties。
typeAliases
類型别名是為Jva類型設定一個短的名字,原來的類型名稱配置如下:
已經将常用的類型定義好了别名
知識小結:
MyBatis響應的API
SqlSession工廠構造器SqlSessionFactoryBuilder
常用API:SqlSessionFactory build(InputStream inputStream)
MyBatis的Dao層實作
代理開發方式:
MyBatis映射檔案深入
- 動态sql語句描述
Spring學習筆記spring實戰(僅僅是本人的學習筆記,可能會有錯誤,大家見諒) 動态SQL ifSpring學習筆記spring實戰(僅僅是本人的學習筆記,可能會有錯誤,大家見諒) 動态SQL foreachSpring學習筆記spring實戰(僅僅是本人的學習筆記,可能會有錯誤,大家見諒) Sql片段抽取Spring學習筆記spring實戰(僅僅是本人的學習筆記,可能會有錯誤,大家見諒)
總結:
MyBatis 核心配置檔案深入
typeHandlers标簽
重新定義類型轉換器
開發步驟
1.
public class DateTypeHandler extends BaseTypeHandler<Date> {
//将java類型轉化成資料庫中需要的類型
public void setNonNullParameter(PreparedStatement ps, int i, Date parameter, JdbcType jdbcType) throws SQLException {
long time = parameter.getTime();
ps.setLong(i,time);
}
//将資料庫中的類型轉換成java類型
//columnName是資料庫中要轉換的字段的名稱
//rs查詢的結果集
public Date getNullableResult(ResultSet rs, String columnName) throws SQLException {
//将擷取到的資料轉換成long類型
long aLong = rs.getLong(columnName);
//然後轉換成date類型
Date date = new Date(aLong);
return date;
}
//将資料庫中的類型轉換成java類型
public Date getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
long aLong = rs.getLong(columnIndex);
Date date = new Date(aLong);
return date;
}
//将資料庫中的類型轉換成java類型
public Date getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
long aLong = cs.getLong(columnIndex);
Date date = new Date(aLong);
return date;
}
}
<!--自定義注冊器-->
<typeHandlers>
<typeHandler handler="itheima.handler.DateTypeHandler" javaType="java.util.Date"/>
</typeHandlers>
plugins标簽
- 在pom檔案中導入坐标
<!-- mybatis pager -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>com.github.miemiedev</groupId>
<artifactId>mybatis-paginator</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>0.9.4</version>
</dependency>
- 配置核心檔案中的插件
<!-- 配置plugins分頁助手-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
3.在測試中編寫測試的代碼
拓展:擷取與分頁相關的參數
MyBatis多表操作
多表查詢中,将多表查詢的結果和現實中的結果一一對應
一對一
<resultMap id="orderMap" type="order">
<!-- column是資料庫中查詢到的列,property是我們要封裝進的實體-->
<result column="oid" property="id"/>
<result column="ordertime" property="ordertime"/>
<result column="total" property="total"/>
<result column="uid" property="user.id"/>
<result column="username" property="user.username"/>
<result column="password" property="user.password"/>
<result column="birthday" property="user.birthday"/>
</resultMap>
<!--這裡結果要改成resultMap-->
<select id="findAll" resultMap="orderMap">
select *,o.id oid
from orders o inner join user u on u.id=o.uid
</select>
将查詢到的關聯表封裝在另一個類中的另一種封住方式:
<resultMap id="orderMap" type="order">
<result column="oid" property="id"/>
<result column="ordertime" property="ordertime"/>
<result column="total" property="total"/>
<!-- property是order中的屬性
javaType是實際的類
-->
<association property="user" javaType="user">
<result column="uid" property="id"/>
<result column="username" property="username"/>
<result column="birthday" property="birthday"/>
<result column="password" property="password"/>
</association>
</resultMap>
一對多
<resultMap id="userMapper" type="user">
<result property="id" column="uid"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<collection property="orderList" ofType="order">
<result column="oid" property="id"/>
<result column="ordertime" property="ordertime"/>
<result column="total" property="total"/>
</collection>
</resultMap>
<select id="findAll" resultMap="userMapper">
SELECT *,o.id oid FROM orders o INNER JOIN USER u ON u.id=o.uid
</select>
多對多
總結:
MyBatis的注解開發
**一對多 **