spring笔记

    【如果你要使用的是spring6,那么还需要配置一个spring里程碑版本的仓库】
                     <repository>
                 <id>repository.spring.milestone</id>
                 <name>Spring Milestone Repository</name>
                 <url>https://repo.spring.io/milestone</url>
             </repository>
             <dependency>
                 <groupId>org.springframework</groupId>
                 <artifactId>spring-context</artifactId>
                 <version>6.0.0-M2</version>
             </dependency>
             
    【获取spring容器当中的bean对象】    
         这个是获取spring容器对象,ClassPathXmlApplicationContext专门从类路径下加载文件
                ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
         获取spring文件当中配置的bean对象
                  applicationContext.getBean("这里写xml文件bean当中的id属性值");    

    【技巧】
            * 1.获取的bean是Object类型的,我们不使用强转直接转化为原本的类型 
                   Vip vipBean = applicationContext.getBean("vipBean", Vip.class);
                   这样使用getbean方法直接获取的对象是它原本的类的类型
                   
    【日志文件log4j2的使用】
          第一步::首先加入依赖
              <dependency>
                  <groupId>org.apache.logging.log4j</groupId>
                  <artifactId>log4j-core</artifactId>
                  <version>2.19.0</version>
              </dependency>
              <dependency>
                  <groupId>org.apache.logging.log4j</groupId>
                  <artifactId>log4j-slf4j2-impl</artifactId>
                  <version>2.19.0</version>
              </dependency>          
          第二步::再类的根路径下(resource)文件当中创建log4j2.xml文件,文件名必须是log4j2.xml不能更改
          
【Bean注入】  

 spring6-dependency-injection
    【set注入】 
           第一步:在我们需要创建接口对象的类当中创建这个对象的set方法,一般直接使用set加对象属性名
            第二步:在我们的spring.xml文件当中编写   <!--set注入-->
               <bean id="userDaoBean" class="com.xsh.spring6.dao.UserDao"/>
               <bean id="userServiceBean" class="com.xsh.spring6.service.UserService">(这里的id就是去掉set然后首字母该小写)
               <property name="userDao" ref="userDaoBean"></property>
               </bean>    
    【构造注入】
            第一步:在我们需要创建接口对象的类当中创建这个对象的构造方法
            第二步:    <bean id="userDaoBean" class="com.xsh.spring6.dao.UserDao"/>
                        <bean id="vipDaoBean" class="com.xsh.spring6.dao.VipDao"/>
                        <bean id="customerServiceBean" class="com.xsh.spring6.service.CustomerService">
                            <constructor-arg index="0" ref="userDaoBean"/>
                            <constructor-arg index="1" ref="vipDaoBean"/>(这里的index是我们构造方法当中需要传入值的序号)
                               (也可以把index改为使用name,name就是构造方法当中传入值的属性名)
                        </bean>
    
    【set注入专题】  不给属性注入,属性的默认值就是null
            *1.简单类型注入
                 一个user类,类当中有username,password,age三个属性
                      <bean id="userBean" class="com.xsh.spring6.bean.User">
                          <property name="username" value="zhangsan"/>
                          <property name="password" value="123456"/>
                          <property name="age" value="21"/>(简单类型可以直接使用value进行赋值)
                      </bean>
            *2.注入数组类型
                   <bean id="daYeBean" class="com.xsh.spring6.bean.DaYe">
                       <property name="aiHaos">
                           <array>
                               <value>抽烟</value>
                               <value>喝酒</value>
                               <value>烫头</value>(如果是复杂类型的话
                                                      要使用<ref bean="这里写复杂类型的bean的id"/>)
                           </array>
                       </property>
                   </bean>
            *3.map集合注入   set-di.xml
                    <bean id="personBean" class="com.xsh.spring6.bean.Person">
                        <property name="phone">
                            <map key-type="java.lang.String" value-type="java.lang.String">
                                <entry key="zhangsan" value="123456"/>
                                <entry key="lisi" value="1234567"/>
                                (如果不是简单类型 使用 key-ref="" value-ref="")
                            </map>
                        </property>
                    </bean>    
          *4.特殊符号的注入
                第一种:使用实体符号  比如  < - &lt; 这个是小于号和它的尸体符号
                第二种:使用 <![CDATA[]]>这个符号里面的不会被xml文件解析,只会被认为是普通字符串
                
          *5.p命名空间注入   简化set方法注入
               第一步  在spring.xml文件当中加入 xmlns:p="http://www.springframework.org/schema/p"
               第二步 <bean id="pDogBean" class="com.xsh.spring6.bean.PDog" p:name="zhangsan" p:age="21" p:brith-ref="brithBean">
                          <property name="pass" value="2 &lt; 3"/> <!--测试特殊符号注入-->
                      </bean>
                      <bean id="brithBean" class="java.util.Date"/>
           *6.c命名空间注入 简化构造方法注入    spring-c.xml    
                 第一步:在spring.xml文件当中加入 xmlns:c="http://www.springframework.org/schema/c"    
                 第二步:    <bean id="cDogBean" class="com.xsh.spring6.bean.CDog" c:_0="zhangsan" c:_1="21">
                                 <constructor-arg name="sex" value="男"></constructor-arg>(这里可以直接写在前面的bean当中)
                             </bean>    
           *7.配置复用    spring-util.xml
                  第一步:在配置文件当中加入
                         xmlns:util="http://www.springframework.org/schema/util
                         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
                  第二步: <util:properties id="prop">
                                <prop key="driver">com.mysql.cj.jdbc.Driver</prop>
                                <prop key="url">jdbc:mysql://localhost:3306/spring6</prop>
                                <prop key="user">root</prop>
                                <prop key="password">123456</prop>
                            </util:properties>    
                            
        *8.自动装配   自动装配是建立在set方法之上的
            根据名字自动装配(autowire="byName")  spring-autowire.xml
                        <bean id="order" class="com.xsh.spring6.bean.Order"></bean>
                        <bean id="orderServiceBean" class="com.xsh.spring6.service.OrderService" autowire="byName"></bean>
                 <!--这里加上autowire="byName"就是根据名字自动装配
                 如果使用自动装配的话,拿我们的索要创建的接口对象bean
                 的id不能随便写,只能是set方法当中去掉set,首字母改小写,差不多就是属性名字--> 

        【xml引入外部文件】 spring6-dependency-injection  》》  spring-properties.xml
                第一步:在配置文件当中加入        
                             xmlns:context="http://www.springframework.org/schema/context"
                              http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                第二步:    <!--引入外部文件-->
                            <context:property-placeholder location="jdbc.properties"/>
                            <bean id="myDataSourceBean" class="com.xsh.spring6.jdbc.MyDataSource">
                                <property name="driver" value="${driverClass}"/>
                                <property name="url" value="${url}"/>
                                <property name="password" value="${password}"/>
                                <property name="user" value="${user}"/>
                            </bean>          
                            
    【bean的作用域】   spring6-004-scope
              单例与多例::  bean默认情况下是单例的,在spring上下文初始化的时候实例化对象,而不是在getBean的时候实例化        
                   多例模式: 将scope设置成 prototype  多例模式上下文时候并不会初始化这些bean,在调用getBean的时候初始化
                     <bean id="stringBean" class="com.xsh.spring.bean.StringBean" scope="prototype"></bean>
                其实scope有4个值:prototype,singleton,request,session
                
     【自定义一个scope】 一般是为了创建线程获取与主线程不是同一个的对象
         第一步:在spring.xml文件将scope注册到spring容器当中
                  使用方式就是entry标签当中的key
                 <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
                     <property name="scopes">
                         <map>
                             <entry key="threadScope">
                                 <bean class="org.springframework.context.support.SimpleThreadScope"/>
                             </entry>
                         </map>
                     </property>
                 </bean>
                 <bean id="sBean" class="com.xsh.spring.bean.StringBean" scope="threadScope"></bean>
                 
        主线程调用之后,我们还可以创建一个线程再次调用,另一个线程拿到的和主线程的不是同一个对象
                     //使用另一个线程获取对象
                     new Thread(new Runnable() {
                         @Override
                         public void run() {
                             StringBean sb3 =applicationContext.getBean("sBean", StringBean.class);
                             System.out.println(sb3);
                         }
                     }).start();    
                     
    【工厂】  spring6-simple-factory    
         简单工厂模式::     com.xsh.simple.factory.pojo
         工厂方法模式:: com.xsh.spring.factory.method
         
【Bean实例化的四种方式】   spring6-005-instantiation
        (这里需要注意的是简单工厂当中的是静态方法,而方法模式当中的不是静态get方法,
          所以方法模式需要创建对象调用get,而简单工厂不需要使用对象调用,直接类调用
          FactoryBean需要实现,这个方法其实就是第三种方式的简化版本)
            <!--bean实例化的第一种方式,构造方法实例-->
            <bean id="userBean" class="com.xsh.spring6.bean.User"></bean>
            
            <!--bean实例化第二种方式,通过简单工厂实例化对象,需要告诉spring框架调用那个类的那个方法获取bean-->
            <!--factory-method属性指定的就是工厂类房中的静态方法,也就是告诉spring框架那个类可以获取bean-->
            <bean id="starBean" class="com.xsh.spring6.bean.StarFactory" factory-method="get"/>
            
            <!--spring提供的实例化方式,第三种,通过工厂方法模式,通过factory-bean属性 + factory-method属性共同完成-->
            <!--告诉spring调用那个对象的那个方法来获取Bean-->
            <bean id="gunFactory" class="com.xsh.spring6.bean.GunFactory"/>
            <!--factory-bean告诉spring调用那个类,factory-method告诉spring调用那个方法-->
             <bean factory-bean="gunFactory" factory-method="get"/>
            
            <!--spring提供的实例化方式第四种,通过factoryBean来实现
             由于你编写的类实现了factoryBean,所以不需要指定factory-bean和factory-method这两个属性,factoryBean会自动帮你实现-->
            <!--通过FactoryBean这个Bean,主要是对普通Bean进行加工处理-->
            <bean id="person" class="com.xsh.spring6.bean.PersonFactory"/>
            
    【FactoryBean实战之注入Date【
             spring6-005-instantiation  》》》  DateSpring.xml    
                    <!--工厂Bean,返回普通Bean:Date-->  DateFactory这个类实现了FactoryBean
                    <bean id="dateBean" class="com.xsh.spring6.pojo.DateFactory">
                        <property name="strDate" value="2001-11-28"></property>
                    </bean>(这里是将字符串传入工厂里,转化成Date)
                    <!--将我们的Date赋值给Student的Date属性-->
                    <bean id="student" class="com.xsh.spring6.pojo.Student">
                        <property name="date" ref="dateBean"/>
                    </bean>
                    
    【Bean的生命周期】      spring6-006-bean-lifecycle
        生命周期之五步
               其中init和destroy这两个方法自己写了,需要到Bean容器当中进行配置
                 /*
                 * Bean生命周期
                 * 第一步:实例化Bean(调用无参数构造方法)
                 * 第二步:给bean属性赋值(调用set方法)
                 * 第三步:初始化Bean(会调用init方法,这个方法需要我们自己配置)
                 * 第四步:使用Bean
                 * 第五步:销毁Bean(会调用Bean的destroy方法,这个方法也需要我们自己配置)
                 * */
        生命周期之七步:;
             七步的话就是多了一个Bean后处理器
                【配置Bean后处理器】
                    写一个类去实现BeanPostProcessor这个类,重写其中的两个方法
                    围绕init方法前后执行
                    /*
                 * Bean生命周期
                 * 第一步:实例化Bean(调用无参数构造方法)
                 * 第二步:给bean属性赋值(调用set方法)
                 * 第三步:执行Bean后处理器before方法
                 * 第四步:初始化Bean(会调用init方法,这个方法需要我们自己配置)
                 * 第五步  执行Bean后处理器的after方法
                 * 第六步:使用Bean
                 * 第七步:销毁Bean(会调用Bean的destroy方法,这个方法也需要我们自己配置)
                 * */
        
        【将自己new出来的对象纳入spring容器当中去管理】   spring6-006-bean-lifecycle 》》 bean
                 DefaultListableBeanFactory dlbf = new DefaultListableBeanFactory();
                 dlbf.registerSingleton("stuBean",stu);
                 Object stuBean = dlbf.getBean("stuBean");
                 
            循环依赖: 循环依赖只有在两个Bean都是scope="prototype"的时候,才会出现异常,
             循环依赖一般是使用    scope="singleton"和构造注入一起实现        
             
             
    【反射机制的调用】 spring6-revlew-reflect    
            四要素:调用那个对象的那个方法,传入什么参数,返回什么值;
               //获取类
                Class<?> clazz = Class.forName("com.xsh.spring.reflect.SomeService");
                //获取方法  首先是方法名字,再是方法的传入参数的类型
                Method doSome = clazz.getDeclaredMethod("doSome", String.class, int.class);
                //创建对象
                Object obj = clazz.newInstance();
                //执行方法
                Object zhangsan = doSome.invoke(obj, "zhangsan", 20);//这里传入的参数,对象,传入的参数    

------------------------------------------------------------
【spring注解式开发】  
         注解开发扫描原理:  spring6-review-annotation 
           (自定义注解配置,解析注解,获取注解当中的值)
           
    spring6-007-ioc-annotation
        【声明Bean的注解】
            @Component
            @Controller
              @Service        
            @Repository   (这四个是同一个意思,只是为了增强可读性,分别使用再不同的业务层)
        注解的使用:: 第一步:添加aop依赖,就是spring的依赖
                         第二步:再配置文件当中添加context(引入外部文件)命名空间
                         第三步:在配置文件当中指定扫描的包
                         <!--给spring框架指定要扫描那些包-->
                       组件扫描::  <context:component-scan base-package="这里写的需要扫描包的地址"/>
            如果让单个声明Bean生效那么在context当中配置        
        
        【负责注入的注解:】
        
        *1.@Value注解:  
            直接使用@Value,可以用在属性上,并且使用Value注解的话,可以不提供set属性赋值,
           一般是简单类型,还可以用在set方法和构造方法上    
        *2.@Autowired:@Qualifier    一般是非简单类型
            Autowired如果单个使用的话,是根据类型自动装配,如果想根据名字自动装配的话,需要连同@Qualifier一起使用
              例子::    @Autowired
                          @Qualifier("orderDaoImplMysql")
                          private OrderDao orderDao;
                          (直接在属性上使用,Qualifier指定你所要创建的对象,因为impl下面有多个类,根据类型指定会报错)
        *3.@Resource ::默认根据名字装配,byName,没有指定name时,使用属性名作为name,
                   通过name找不到的话自动启动类型自动装配
                      第一步: 使用这个的话需要引入依赖
                        <dependency>
                            <groupId>jakarta.annotation</groupId>
                            <artifactId>jakarta.annotation-api</artifactId>
                            <version>2.1.1</version>
                        </dependency>
                      第二步:然后可以直接作用在属性上或者set方法上,但是不能作用在构造方法上
                       @Resource(name = "personDaoMysql")  这里的name属性是我们配置的Bean的id
                       
         使用类代替注解配置xml文件,(Bean容器)
                   创建一个类加上:@Configuration(这个必须)
                                   @ComponentScan({"cn.xsh.spring.dao","cn.xsh.spring.service"})(包扫描配置)
                    然后获取容器对象也不是ClassPathXmlApplicationContext
                    而是:AnnotationConfigApplicationContext,传的是我们的类对象
                        
        
    【jdbcTemplate】   spring-008-jdbc
                使用第一步::在配置文件当中配置:
                                <!--配置jdbcTemplate-->
                                <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
                                    <property name="dataSource" ref="myds"/>(这里配置的是我们的数据源))
                                </bean>
                第二步就是获取对象:调用对象的方法,记住,在jdbctemplate当中insert,delete,update都是调用update方法
                                    查询语句的话调用 .queryForObject方法
                                          queryForObject(sql, new BeanPropertyRowMapper<>(User.class), 2);1.sql语句,返回值的类型,这里我们是创建的user对象,2是像sql语句当中的 ?传值                                
                                    批量添加,修改,删除的话使用:.batchUpdate(sql,list)
                                    查询多个.queryForList
                                    
                jdbc回调函数其中也有例子
                
    【使用德鲁伊连接池 DruidDataSource】
         第一步:导入依赖      <dependency>
                                 <groupId>com.alibaba</groupId>
                                 <artifactId>druid</artifactId>
                                 <version>1.2.18</version>
                               </dependency>
        第二步:在xml文件当中配置Bean
 ----------------------------------------------------------
 【GOF代理模式机制】 
       【 静态代理】 就是简单工厂生产类似  static-proxy
        【jdk 动态代理机制】:程序运行阶段,在内存当中动态生成代理类   dynamic-proxy-jdk
                    //获取目标对象
        OrderService target = new OrderServiceImpl();
        //创建代理对象
        /*这里需要传入三个参数
          newProxyInstance:翻译为新代理对象
          1.ClassLoader loader  类加载器
             类加载器,这个是在内存当中生成的字节码也是class文件,要执行也得先加载到内存当中,加载类就需要类加载器,所以需要指定类加载器
             并且jdk要求,目标类的类加载器和代理类的类加载器要一致
          2.Class<?>[] interfaces  实现的接口
            代理类和目标类实现同一个接口
            在内存当中生成代理类的时候,这个代理类是你需要告诉他实现那些接口
          3.InvocationHandler h
            调用处理器  ,这里一般是你具体需要加强什么代码,所以我们可以创建一个类来继承InvocationHandler类
             从而实现加强代码,第三个传入的参数也就是那个类的对象
        * */
         OrderService orderService =  (OrderService)Proxy.newProxyInstance(target.getClass().getClassLoader(),
                                                                            target.getClass().getInterfaces(),
                                                                            new TimerInvocationHandler(target));
        //代理对象调用方法
        orderService.generate();

        /**其中继承InvocationHandler接口实现invoke方法
          /*invoke当中有三个参数
        第一个参数,Object proxy 代理对象的引用,这里引用较少
        第二个参数:Method method 调用的那个方法
        第三个参数 Object[] args 方法传入的值
        * */

        //调用目标对象上的目标方法,四要素,那个方法,那个对象,传入的参数,返回值
        Object retValue = method.invoke(target, args);
        */

    【CGLIB动态代理】 
       //创建字节码增强器
        Enhancer enhancer = new Enhancer();
       //告诉CGLIB父类是谁
       enhancer.setSuperckass(“这里写父类”)
       //设置回调(等同于jdk动态代理调用处理器,InvocationHandler
                    只是在CGLIB当中是MethodInterceptor )
        enhancer.setCallBack(new "这里写继承了MethodInterceptor接口的类")            
      //然后就可以调用了
         Object o = enhancer.create();


    【面向切面编程】


         1.* 切面编程七大术语:
                连接点(joinpoint)描述的位置
                切点(pointcut) 本质上就是方法(真正织入切面的那个方法叫做切点)
                通知(Advice) 通知又叫做增强代码,就是具体增强的那个代码
                切面:切点 + 通知 
                  切面一般需要使用@Aspect注解进行标记
             *1.前置通知@Before 目标方法执行之前的通知
             *2.后置通知 @AfterReturning 目标方法执行之后的通知
             *3.环绕通知 @Around 目标方法之前添加通知,同时目标方法之后添加通知 (范围是最大的)
             *4.异常通知 @AfterThrowing 发生异常之后执行的通知
             *5.最终通知 @After 放在finally语句块当中的通知         
                  
                  
         2.* 切点表达式
             execution([访问控制权限修饰符] 返回值类型 [全限定类名] 方法名(形式参数列表) [异常])
               []这个里面代表可选    
  
    【*.spring aop基于注解式准备工作】     spring-009-aspectj-aop-anno 详解看
       1.依赖文件
          比之前的多一个aspects依赖  <dependency>
                          <groupId>org.springframework</groupId>
                          <artifactId>spring-aspects</artifactId>
                          <version>6.0.0-M2</version>
                      </dependency>
        2.引入命名空间: context 和 aop 两个命名空间
             context是组件扫描 
             aop是开启自动管理
             <!--组件扫描-->
             <context:component-scan base-package="com.xsh.spring.service"/>
             
             <!--开启自动aspectj自动代理-->
             <!--spring容器在扫描类的时候,查看该类上是否有@Aspect注解,如果有,就给它生成自动代理-->
             <!-- expose-proxy="true"表示使用CGLIB自动代理
                  expose-proxy="false" 表示接口使用JDk动态代理,反之则使用CGLIB代理
             -->
             <aop:aspectj-autoproxy expose-proxy="true"/>
        3.目标类 
            就是service类的构建 要声明Bean
        4.切面类 
           切面类需要使用@Aspect注解进行标记 
            然后再切面类当中进行通知的编写
            @Order 这个是切面执行顺序的,数字越小,优先级越高
            
        5.如果使用全注解开发的话 
            新建一个类,代替spring.xml文件
              添加下面的注解
                @Configuration
                @ComponentScan({"com.xsh.spring.service"})  组件扫描--
                @EnableAspectJAutoProxy(proxyTargetClass = true)  启用aspectj的自动代理机制

    *.基于xml文件     spring6-010-aspectj-aop-xml 不使用注解,使用xml文件进行配置
            还是一样要引入context和aop命名空间
                     <!--纳入spring ioc管理-->
           目标类   <bean id="userService" class="com.xsh.spring6.service.UserService"/>
           切面类   <bean id="timerAspect" class="com.xsh.spring6.service.TimerAspect"/>
             
              <!--aop的配置-->
              <aop:config>
                  <!--切点表达式-->
                  <aop:pointcut id="myPointcut" expression="execution(* com.xsh.spring6.service..*(..))"/>
                  <!--切面=通知+切点-->
                  <aop:aspect ref="timerAspect">
                      <aop:around method="aroundAdvice" pointcut-ref="myPointcut"/>
                  </aop:aspect>
              </aop:config>
              
              
              
    【开启事务】   spring6-011-tx-bank
      1.添加依赖 jdbc,spring-context,数据库依赖,德鲁伊连接池,@Resource,junit依赖
      2.配置文件当中: 添加context,tx命名空间
                   <!--配置组件扫描-->
               <context:component-scan base-package="com.xsh.spring6.bank"/>
              
               <!--配置数据源-->
               <bean id="mydateSource" class="com.alibaba.druid.pool.DruidDataSource">
                   <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
                   <property name="url" value="jdbc:mysql://localhost:3306/mvc"/>
                   <property name="username" value="root"/>
                   <property name="password" value="Xx20011128"/>
               </bean>
               
               <!--配置jdbcTemplate-->
               <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
                   <property name="dataSource" ref="mydateSource"/>
               </bean>
             
               <!--配置事务管理器-->
               <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                   <property name="dataSource" ref="mydateSource"/>
               </bean>
               <!--开启事务注解驱动器,开启事务注解,告诉spring,采用注解的方式去控制事务-->
               <tx:annotation-driven transaction-manager="txManager"/>
        3.那里需要使用事务管理,直接加上注解  @Transactional    
            *.Transactional 一共有7中传播行为    传播行为看里面的保存数据的方法
                ·REQUIRED:支持当前事务,如果没有就新建一个    (默认)    
                ·SUPPORTS:支持当前事务,如果当前没有事务,就以非事务的方式执行
                ·MANDATORY:必须运行再一个事务中,如果当前没有事务正在发生,将抛出一个异常
                ·Requires_NEW:开启一个新的事务,如果之前存在事务,则将之前的事务挂起
                ·NOT_SUPPORTED:以非事务的的方式运行,如果存在事务,就将事务挂起
                ·NEVER:以非事务方式运行,如果有事务存在,抛出异常
                ·NETED:如果当前正有一个事务正在进行当中,则再该事务当中在嵌套一个事务,如果没有事务,则像REQUIRED一样,创建一个事务
            *.使用例子: @Transactional(propagation = Propagation.REQUIRED)                
        4.dao层操作直接使用德鲁伊连接池        
        
        5.使用全注解去配置spring.xml文件 看这个类Spring6Config
           测试方法看  NoXmlTest

【spring整合mybatis】

1.pojo类

package com.xsh.bank.pojo;

public class Account {
    private int id;
    private String actno;
    private Double balance;

    public Account(int id, String actno, Double balance) {
        this.id = id;
        this.actno = actno;
        this.balance = balance;
    }

    public Account() {
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", actno='" + actno + '\'' +
                ", balance=" + balance +
                '}';
    }

    public int getId() {
        return id;
    }

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

    public String getActno() {
        return actno;
    }

    public void setActno(String actno) {
        this.actno = actno;
    }

    public Double getBalance() {
        return balance;
    }

    public void setBalance(Double balance) {
        this.balance = balance;
    }
}

2.mapper接口

package com.xsh.bank.mapper;

import com.xsh.bank.pojo.Account;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Configuration("accountMapper")
public interface AccountMapper {//该接口不需要写实现类,通过mybatis代理机制生成实现类
    //这里就是dao,只需要编写crud方法即可
    int insert(Account account);
    int deleteByActno(String actno);
    int update(Account account);
    Account selectByActno(String actno);
    List<Account> selectAll();


}

3.业务层service

接口

package com.xsh.bank.service;

import com.xsh.bank.pojo.Account;

import java.util.List;

public interface AccountService {//Service接口

    /**
     * 开户
     * */
    int save(Account account);
    /**
     * 销毁户
     * */
    int deleteByAccount(String actno);
    /**
     * 修改账户
     * */
    int modify(Account account);
    /**
     * 查询账户
     * */
    Account getByActno(String actno);
    /**
     * 查询所有账户
     * */
    List<Account> getAll();

    /**
     * 转账业务
     * */
    void transfer(String fromactno,String toactno,Double money);

}

实现类

package com.xsh.bank.service.impl;

import com.xsh.bank.mapper.AccountMapper;
import com.xsh.bank.pojo.Account;
import com.xsh.bank.service.AccountService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLOutput;
import java.util.List;

@Transactional
@Service("accountService")
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountMapper accountMapper;

    @Override
    public int save(Account account) {
        int count = accountMapper.insert(account);
        return count;
    }

    @Override
    public int deleteByAccount(String actno) {
        int count = accountMapper.deleteByActno(actno);
        return count;
    }

    @Override
    public int modify(Account account) {
        int count = accountMapper.update(account);
        return count;
    }

    @Override
    public Account getByActno(String actno) {
        Account account = accountMapper.selectByActno(actno);
        return account;
    }

    @Override
    public List<Account> getAll() {
        List<Account> accounts = accountMapper.selectAll();
        return accounts;
    }

    /**
     * 转账业务
     * */
    @Override
    public void transfer(String fromactno, String toactno, Double money) {
        Account account1 = accountMapper.selectByActno(fromactno);
        if(account1.getBalance()<money){
            throw new RuntimeException("余额不足");
        }
        Account account2 = accountMapper.selectByActno(toactno);
        account1.setBalance(account1.getBalance()-money);
        account2.setBalance(account2.getBalance()+money);
        int count = accountMapper.update(account1);
        count += accountMapper.update(account2);
        if(count == 2){
            System.out.println("转账成功");
        }else{
            throw new RuntimeException("转账失败");
        }

    }




}

4.在resources下配置mapper配置,记住,文件所放的位置要和前面配置的Mapper接口的位置一致

   在其中写数据库的操作,dao层

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.xsh.bank.mapper.AccountMapper">
    <insert id="insert">
        insert into t_act values(#{id},#{actno},#{balance});
    </insert>
    <delete id="deleteByActno">
        delete from t_act where actno = #{actno}
    </delete>
    <update id="update">
        update t_act set balance = #{balance} where actno = #{actno};
    </update>
    <select id="selectByActno" resultType="Account">
        SELECT id, actno, balance from t_act where actno = #{actno}
    </select>
    <select id="selectAll" resultType="Account">
        SELECT id, actno, balance from t_act
    </select>

</mapper>

5.外部文件类,数据流 jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mvc
jdbc.username=root
jdbc.password=Xx20011128

6.mybatis核心文件的配置(mybatis-config.xml)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--斑海猪我们打印mybatis日志信息,sql语句-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
</configuration>

7.spring.xml文件的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

<!--上面引入了context,tx的命名空间-->
    
    <!--组件扫描-->
    <context:component-scan base-package="com.xsh.bank"/>
    
    <!--引入外部的属性配置文件-->
    <context:property-placeholder location="jdbc.properties"/>

    <!--数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!--配置SqlSessionFactoryBean-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"/>
        <!--注入mybatis核心配置文件路径-->
        <property name="configLocation" value="mybatis-config.xml"/>
        <!--指定别名包-->
        <property name="typeAliasesPackage" value="com.xsh.bank.pojo"/>
    </bean>

    <!--Mapper扫描配置器-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.xsh.bank.mapper"/>
    </bean>

    <!--配置事务管理器  注入数据源-->
    <bean id="txMapper" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--启用事务注解-->
    <tx:annotation-driven transaction-manager="txMapper"/>

</beans>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值