栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring-Mybatis整合 从零开始

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring-Mybatis整合 从零开始

创建项目 1.通过maven的方式创建一个项目

2.创建POJO对象
public class Hello {
        private String str;
    
        public void setStr(String str) {
            this.str = str;
        }
    
        public String getStr(){
            return str;
        }
    
        @Override
        public String toString() {
            return "Hello{" +
                    "str='" + str + ''' +
                    '}';
        }
    }

然后创建 beans.xml (applicationContext.xml),在xml中配置相应的属性

3.之后就可以调用这个POJO类了
//使用xml加载就必须用下面的语法
            //获取spring的上下文对象
            ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
            //对象都在Spring中管理,要使用就直接取出来用
            Hello h = (Hello) context.getBean("hello");
            System.out.println(h.toString());

通过set()注入

IOC创建对象的方式 1.先编写POJO对象
    public class User {
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public User(){
            System.out.println("无参构造");
        }
        public void show(){
            System.out.println("name:"+name);
        }
    }
2.在applicationContext.xml文件中添加bean
    
    
    
        
            
        
    
3.通过测试可以发现,IOC通过无参构造注入
  public class MyTest {
      public static void main(String[] args) {
          //User user = new User();
          ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
          User user = (User)context.getBean("user");
          //System.out.println(user);
          user.show();
      }
  }

当没有无参构造时,有以下的方式进行构造函数注入

  
  
  
  
  
  
  
  
  
  
  
      
          
      

总结: 在配置文件加载的时候,容器中管理的对象就已经初始化了(不管你有没有调用).

Spring配置 1.别名
  
            
        
    
        

通过别名也可以获取到bean

    ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
            User user = (User)context.getBean("UUU");
2.Bean的配置
     
            
        
        
3.import

一般用于团队开发使用,可以将多个配置文件导入合并为一个

项目中有多个配合文件,就可以在总的配置文件中,通过import进行导入

依赖注入(DI) 1.构造器注入 2.set()方式注入[*]
  • 依赖:bean对象的创建依赖于容器
  • 注入:bean对象中所有的属性,由容器来注入
【环境搭建】 1.复杂类型
    public class Address {
    
        private String address;
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
    }
2.真实测试对象
    public class Student {
        private String name;
        private Address address;
        private String[] books;
        private List hobbys;
        private Map card;
        private Set games;
        private String wife;
        private Properties info;
    
    }
3.applicationContext.xml
    
    
    
        
        
    
            
    
            
    
            
                
                    红楼梦
                    三国演义
                    西游记
                    水浒传
                
            
    
            
                
                    听歌
                    看电影
                
            
    
            
                
                    
                    
                
            
    
            
                
                    LOL
                    CSGO
                
            
    
    
            
                
            
    
    
            
                
                    001
                    
                    root
                    123465
                
            
        
    
    
4.测试
    public class MyTest {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            Student student = (Student)context.getBean("student");
            System.out.println(student.toString());//此时只有name有值
        }
    }
    
3.其他方式 bean的作用域 1.单例模式(默认机制)
    
2.原型模式:每一次从容器中get都会产生新的对象
    
3.其余的request、session、application、这些只能在web开发中用到 Bean的自动装配

之前的是手动装配

  • 自动装配是Spring满足bean依赖一种方式
  • Spring会在上下文中自动寻找,并自动给bean装配属性
在Spring中有 3 种方式:
  1. 在xml中显示的配置
  2. 在java中显示配置
  3. 隐式的自动装配bean[*]
    在xml中显示的装配
    
    
    
        
        
        
            
            
            
        
    

通过ByName的方式:需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致

    
    
    
    
        
    

通过byType的方式(不用命名id也能找到):需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的类型一致

    
        
        
        
            
        
注解自动装配

使用注解:

  1. 导入约束。context约束
  2. 配置注解的支持

    
    
        
        
    
    
    public class People {
        @Autowired
        private Cat cat;
        @Autowired
        private Dog dog;
        private String name;
    }
@Autowired

直接在属性上使用,也可以在set方法上使用

使用Autowired我们可以不写set方法,前提是你这个自动装配的属性在IOC容器中存在,且符合名字byName

    
    
    
    
    
    public class People{
        @Autowired
        @Qualifier(value = "cat1")//在找不到的时候可以时候该注解找到对应的value
        private Cat cat;
        @Autowired
        @Qualifier(value = "dog1")
        private Dog dog;
        private String name;
    }
@Resource

先根据id找,找不到时根据类型type找,当都找不到时报错

    public class People {
    
        @Resource
        private Cat cat;
        @Resource
        private Dog dog;
        private String name;
    }

小结:@Autowired 和 @Resource 区别:

  • 都是用来自动装配的,都可以放在属性字段上
  • @Autowired通过byType方式实现,而且必须要求这个对象存在(不然包控制着)
  • @Resource默认通过byName方式实现,找不到时通过byType方式实现,都找不到就报错执行
  • 执行顺序不同:@Autowired通过byType实现。@Resource通过byName方式实现
使用注解开发

在spring4之后,要使用注解开发,必须保证aop的包导入

使用注解需要导入context约束,增加注解支持

    
    
    
    
        
    
        
    
    
1.bean @Component

组件,放在类上,说明这个类被spring管理,就是bean

    //@Component 等价于 
    @Component
    public class User {
        public String name = "ckl";
    }
    
    
    
    
        
    
    
    @Test
    public void test01(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = context.getBean("user",User.class);
        System.out.println(user.name);
    }
2.属性注入 @Value
    @Component
    public class User {
        //@Value("ckl")相当于 也可以放在set()上
        @Value("ckl")
        public String name;
    
    }
3.衍生的注解

@Component有几个衍生注解,我们在web开发中,会按照MVC三层架构分层:

  • dao : @Repository
      @Repository
      public class UserDao {
      }
  • service : @Service
      @Service
      public class UserService {
      }
  • controller : @controller
      @Controller
      public class UserController {
      }

这四个注解功能一样,都是代表将某个类注册到spring容器中,装配Bean

4.自动装配
  • @AutoWired:自动装配,通过类型,名字
    如果AutoWired不能唯一自动装配上属性,则需要通过@Qualifier(value=“xx”)
  • @Nullable 字段标记了这个注解,说明这个字段可以为null
  • @Resource: 自动装配,通过名字,类型
5.作用域
    @Component
    @Scope("singleton")
    public class User {
    
        @Value("ckl")
        public String name;
    }
6.小结

xml与注解:

  • xml更加万能,适用于任何场合,维护简单;
  • 注解不是自己的类不能使用,维护相对复杂

xml与注解的最佳实践:

  • xml用于管理
  • 注解只负责完成属性的注入
  • 在使用过程中,只需要注意:必须让注解生效,就需要开启注解支持
使用java的方式配置Spring

现在完全不使用Spring的xml配置,全权交给java处理

JavaConfig是Spring的一个子项目,在Spring4之后,成为一个核心功能

实体类:
    public class User {
    
        @Value("ckl")
        private String name;
        
        @Override
        public String toString() {
            return "User{" +"name='" + name + ''' +'}';
        }
    }
配置文件类
    @Configuration //本身就是一个@Component,@Configuration代表这是一个配置类,就和bean.xml一样
    //@ComponentScan("com.ckl.pojo")
    public class MyConfig {
    
        //注册一个bean 就相当于 写的一个bean标签
        //这个方法的返回值相当于 bean标签的class属性
        @Bean
        public User getUser(){
            return new User();//返回要注入到bean的对象
        }
    }
测试类:
    public class MyTest {
        @Test
        public void test01(){
            //如果完全使用了配置类方式去做,就只能通过AnnotationConfig 上下文来获取容器,通过配置类的class对象加载
            ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
            User user = (User) context.getBean("getUser");//方法名
            System.out.println(user.toString());
        }
    }

这种纯java的配置方式,在springboot中随处可见

代理模式

代理模式分类:静态代理和动态代理

静态代理:

角色分析:

  • 抽象角色:一把会使用接口或者抽象类解决
  • 真实角色:被代理的角色
  • 代理角色:代理真实角色,代理真实角色后,我们一把会做一些附属操作
  • 客户:访问代理对象的人
代码步骤: 1. 接口
       //租房
       public interface Rent {
           public void rent();
       }
2. 真实角色
       //房东
       public class Host implements Rent{
           public void rent(){
               System.out.println("房东要出租房子");
           }
       }
3. 代理角色
       //中介
       public class Proxy implements Rent{
       
           private Host host;
       
           public Proxy() {
           }
       
           public Proxy(Host host) {
               this.host = host;
           }
       
           public void rent() {
               seeHouse();
               host.rent();
               hetong();
               fare();
           }
           //看房
           public void seeHouse(){
               System.out.println("中介带你看房");
           }
           //收中介费
           public void fare(){
               System.out.println("收中介费");
           }
           //签合同
           public void hetong(){
               System.out.println("签合同");
           }
       }
4. 客户端访问代理角色
       //租客
       public class Client {
           public static void main(String[] args) {
               //房东要租房子
               Host host = new Host();
               //代理,中介棒房东租房子,但需要有一些附属操作[中介费,看房子。。。]
               Proxy proxy = new Proxy(host);
       
               proxy.rent();
       
           }
       }
代理模式好处:
  1. 可以使真实角色更加纯粹,不用去关注一些公共的业务
  2. 公共交给代理角色,实现了业务的分工
  3. 公共业务发生扩展时,方便集中管理
缺点:
  • 一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率变低
加深理解:

接口:

    public interface UserService {
        public void add();
        public void delete();
        public void update();
        public void query();
    }

真实对象:

    //真实对象
    public class UserServiceImpl implements UserService{
    
        public void add() {
            System.out.println("增加一个用户");
        }
        public void delete() {
            System.out.println("删除一个用户");
        }
        public void update() {
            System.out.println("修改一个用户");
        }
        public void query() {
            System.out.println("查询用户");
        }
    }

代理对象:

    public class UserServiceProxy implements UserService{
        private UserServiceImpl userService;
    
        public void setUserService(UserServiceImpl userService) {
            this.userService = userService;
        }
    
        public void add() {
            log("add()");
            userService.add();
        }
        public void delete() {
            log("delete()");
            userService.delete();
        }
        public void update() {
            log("update()");
            userService.update();
        }
        public void query() {
            log("query()");
            userService.query();
        }
    
        //添加日志方法
        public void log(String msg){
            System.out.println("[Debug] 使用了"+msg+"方法");
        }
    }

客户:

    public class Client {
        public static void main(String[] args) {
            UserServiceImpl userService = new UserServiceImpl();
            //userService.add();
            UserServiceProxy userServiceProxy = new UserServiceProxy();
            userServiceProxy.setUserService(userService);
            userServiceProxy.add();
            userServiceProxy.delete();
        }
    }
动态代理:
  • 动态代理和静态代理角色一样
  • 动态代理类是动态生成的,不是我们直接写好的
  • 动态代理分为2大类:基于接口的动态代理、基于类的动态代理
    • 基于接口—JDK动态代理[*]
    • 基于类—cglib
    • java季节吗实现:javasist

需要了解两个类:Proxy:代理 InvocationHandler:调用处理程序

    
    package com.ckl.demo04;
    
    import com.ckl.demo03.Rent;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    //用这个类:自动生成代理类
    public class ProxyInvocationHandler implements InvocationHandler {
        //被代理的接口
        private Object target;
    
        public void setTarget(Object target) {
            this.target = target;
        }
    
        //生成得到代理类
        public Object getProxy(){
            return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
        }
    
        //处理代理实例,并返回结果
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            getLog(method.getName());
            Object result = method.invoke(target, args);
            return result;
        }
    
        //附属功能,添加日志
        public void getLog(String msg){
            System.out.println("执行了"+msg+"方法");
        }
    }

    public class Client {
        public static void main(String[] args) {
            //真实角色
            UserServiceImpl userService = new UserServiceImpl();
            //代理角色,一开始并不存在
            ProxyInvocationHandler pih = new ProxyInvocationHandler();
    
            pih.setTarget(userService);//设置要代理的对象
            //动态生成代理类
            UserService proxy = (UserService)pih.getProxy();
    
            proxy.add();
        }
    }
动态代理的好处:
  1. 可以使真实角色的操作更加纯粹,不用去关注一些公共的业务
  2. 公共业务交给代理角色,实现了业务的分工
  3. 公共业务发生扩展时,方便集中管理
  4. 一个动态代理类代理的是一个接口,一把 就是对应的一类业务
  5. 一个动态代理类可以代理多个类,只要是实现了同一个接口即可!
AOP

使用Spring实现AOP

需要导入一个依赖包:

    
        org.aspectj
        aspectjweaver
        1.9.2
    
方式一:

使用spring的API接口

applicationContext.xml
    
            
            
            
    
    
            
    
                
    
                
                
            
接口:
    public interface UserService {
            public void add();
            public void delete();
            public void update();
            public void select();
    }
真实对象:
    public class UserServiceImpl implements UserService{
        public void add() {
            System.out.println("增加用户");
        }
    
        public void delete() {
            System.out.println("删除用户");
        }
    
        public void update() {
            System.out.println("修改用户");
        }
    
        public void select() {
            System.out.println("查询用户");
        }
    }
前置
    public class BeforeLog implements MethodBeforeAdvice{
    
        //method:要执行的目标对象的方法
        //objects:参数  o:目标对象
        public void before(Method method, Object[] objects, Object o) throws Throwable {
            System.out.println(o.getClass().getName()+"的"+method.getName()+"被执行了");
        }
    }
后置
    public class AfterLog implements AfterReturningAdvice {
    
        //o:返回值
        public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
            System.out.println("执行了"+method.getName()+"方法,返回结果为:"+o);
        }
    }
测试
    @Test
    public void Test1(){
        ApplicationContext con = new ClassPathXmlApplicationContext("applicationContext.xml");
        //动态代理 代理的是接口
        //UserServiceImpl userservice = con.getBean("userservice", UserServiceImpl.class);
        UserService userService = con.getBean("userservice",UserService.class);
        userService.add();
    }
方式二:

自定义类来实现AOP[主要是切面定义]

    public class DiyPointCut {
        public void before(){
            System.out.println("方法执行前");
        }
    
        public void after(){
            System.out.println("方法执行后");
        }
    }

    
            
        
    
            
    
                
    
                
                
            
        
方式三:
      	
        
        
    
        
    
        

切面:

    @Aspect //标注这个类是一个切面
    public class AnnotationPointCut {
    
        @Before("execution(* com.ckl.service.UserServiceImpl.*(..))")
        public void before(){
            System.out.println("方法执行前");
        }
        @After("execution(* com.ckl.service.UserServiceImpl.*(..))")
        public void after(){
            System.out.println("执行后");
        }
    
        //在环绕增强中,我们可以给定一个参数,代表我们要获取处理切入的点
        @Around("execution(* com.ckl.service.UserServiceImpl.*(..))")
        public void aroud(ProceedingJoinPoint jp) throws Throwable {
            System.out.println("环绕前:");
    
            //System.out.println("***"+jp.getSignature()+"**");;//可以获得签名
    
            //执行方法  我们的目标方法
            Object proceed = jp.proceed();
    
            System.out.println("环绕后");
        }
    }

    @Test
    public void Test1(){
        ApplicationContext con = new ClassPathXmlApplicationContext("applicationContext.xml");
        //动态代理 代理的是接口
        //UserServiceImpl userservice = con.getBean("userservice", UserServiceImpl.class);
        UserService userService = con.getBean("userservice",UserService.class);
        userService.add();
    }
整合MyBatis方式一 步骤: 1.导入jar包
  • junit
  • mybatis
  • mysql数据库
  • spring相关
  • aop织入
  • mybatis-spring 【new】
 
      
          4.0.0
      
          org.example
          0512_Spring_MyBatis
          1.0-SNAPSHOT
      
          
              
                  junit
                  junit
                  4.13.2
                  test
              
              
                  mysql
                  mysql-connector-java
                  8.0.25
              
              
                  org.mybatis
                  mybatis
                  3.5.2
              
              
                  org.springframework
                  spring-webmvc
                  5.3.8
              
      
              
                  org.springframework
                  spring-jdbc
                  5.3.8
              
              
      
                  org.aspectj
                  aspectjweaver
                  1.9.2
              
              
      
                  org.mybatis
                  mybatis-spring
                  2.0.2
              
          
      
      
2.编写代码 1.实体类
    public class User {
        private int id;
        private String username;
        private String password;
    
        public int getId(){}
        public void setId(int id){}
        public String getUsername(){}
        public void setUsername(String username){}
        public String getPassword(){}
        public void setPassword(String password){}
        public String toString(){}
    }
2.Mapper映射
    public interface UserMapper {
        public List selectUser();//一个查询方法
    }
3.Mapper接口实现类
    public class UserMapperImpl implements UserMapper{
        //我们的所有操作都使用sqlSession执行,
        //在之前现在DOI使用sqlSessionTemplates
        private SqlSessionTemplate sqlSession;
    
        public void setSqlSession(SqlSessionTemplate sqlSession){
            this.sqlSession = sqlSession;
        }
    
        public List selectUser() {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List users = mapper.selectUser();
            return users;
        }
    }
4.Mapper.xml配置文件编写sql语句
    
    
    
    
    
        
            select * from mybatis.test;
        
    
    
2.5 编写spring-dao.xml文件
    
    
    
        
        
            
            
            
            
        
    
        
        
            
        
            
            
        
    
    
    ```

##### 2.6 编写mybatis-config.xml文件
```xml
    
    
    
    
    
        
            
        
    
    
2.7 编写 applicationContext.xml文件

每编写一个实体类[Bean对象], 就需要在配置文件中加入

    
    
    
        
    
        
            
        
         
            
        
    
3.测试
    @Test
    public void test3(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper userMapper = context.getBean("userMapper2",UserMapper.class);
        for (User user : userMapper.selectUser()) {
            System.out.println(user);
        }
    }
MyBatis 1.编写实体类
    public class User {
        private int id;
        private String username;
        private String password;
        public int getId(){}
        public void setId(int id){}
        public String getUsername(){}
        public void setUsername(String username){}
        public String getPassword() {}
        public void setPassword(String password) {}
        public String toString() {}
    }
2.编写核心配置文件
    
    
    
    
    
        
            
        
    
        
            
                
                
                    
                    
                    
                    
                
            
        
    
    
        
            
        
    
3.编写接口
    public interface UserMapper {
        public List selectUser();//一个sql查询的方法
    }
4.编写Mapper.xml
    
    
    
    
        
        
    
5.测试
    @Test
        public void test1() throws IOException {
            String resources = "mybatis-config.xml";//加载配置文件
            InputStream in = Resources.getResourceAsStream(resources);
            SqlSessionFactory builder = new SqlSessionFactoryBuilder().build(in);
            SqlSession sqlSession = builder.openSession(true);
    
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List list = mapper.selectUser();
            for (User user :
                    list) {
                System.out.println(user);
            }
        }
声明式事务

Spring中有声明式事务【AOP】和编程式事务【需要在代码中,进行事务管理】

  • 一组业务,要么都成功,要么都失败
  • 确保完整性和一致性
事务ACID原则
  1. 原子性
  2. 一致性
  3. 隔离性
  4. 持久性
开启事务配置

在spring-dao.xml中

    
    
    
    
    
        
    
     
            
        
            
                
            
                
                
                
            
        
        
        
            
            
        
    
为什么需要事务
  1. 不配置事务,可能存在数据提交不一致的情况
  2. 如果我们不在Spring中去配置声明式事务,我们就需要在代码中手动配置事务
  3. 事务在项目的开发中非常重要,涉及到数据的一致性和完整性问题
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/881749.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号