zoukankan      html  css  js  c++  java
  • 九、持久层框架(MyBatis)

    一、基于MyBatis的对象关系配置(基于XML方式的配置)

    注:  MyBatis不能像Hibernate那样,在实体类上配置上注解或者配置xml映射文件,系统启动后就可以自动创建表。因为MyBatis是基于SQL语句的方式来完成ORM映射的,不是像Hibernate那样将字段与属性完全映射出来,所以不能实现自动建表。

    1、一对多的关系

    Category分类和Product产品是一对多的关系。一个分类对应多个产品

      1.1、修改Category的pojo实体类,给分类提供产品Product的集合

    package com.demo.pojo;
    
    import java.util.List;
    
    public class Category{
        private int id;
        private String name;
        List<Product> products;//产品集合属性
        
        //属性的getter/setter方法
        public int getId(){
            return id;
        }
        public void setId(int id){
            this.id=id;
        }
        public String getName(){
            return name;
        }
        public void setName(String name){
            this.name=name;
        }
        public List<Product> getProducts(){
            return products;
        }
        public void setProducts(List<Product> products){
            this.products=products;
        }
    }
    View Code

      1.2、修改Category的xml映射文件(Category.xml)

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DID Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
            <mapper namespace="com.demo.pojo">
                <!--resultType和resultMap的区别:1、resultType是直接返回类型的,也就是pojo对象的实体
                2、resultMap是对外部resultMap的引用,是key-value关系的映射
                3、resultType和resultMap是不能同时存在的-->
                <resultMap type="Category" id="categoryBean">
                    <id column="cat_id" property="id"/><!--由于Category和Product都有id和name属性,mybatis不知道谁是谁的,所以要别名加以区分-->
                    <result column="cat_name" property="name"/>
                    
                    <!--一对多,property:集合属性值,ofType:集合元素类型-->
                    <collection property="products" ofType="Product">
                        <id column="pro_id" property="id"/>
                        <result column="pro_name" property="name"/>
                        <result column="price" property="price">
                    </collection>
                </resutlMap>
                
                <!--关联Category和Product的表的查询语句-->
                <select id="listCategory" resultMap="categoryBean">
                    select A.*,B.* from category_table A left join product_table B on A.id=B.id
                </select>
            </mapper>
    View Code

      1.3、修改mybatis-config.xml

    在mybatis-config.xml中增加对Category.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>
        <typeAliases>
          <package name="com.demo.pojo"/>
        </typeAliases>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/demo?characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="admin"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <mapper resource="com/demo/pojo/Category.xml"/>
            <mapper resource="com/demo/pojo/Product.xml"/>
        </mappers>
    </configuration>
    View Code

      1.4、测试一对多TestMyBatis

    package com.demo.Test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import com.demo.pojo.Category;
    import com.demo.pojo.Product;
    
    public class TestMyBatis{
        public static void main(String[] args){
            String resource="mybatis-config.xml";
            InputStream inputStream=Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession session=sqlSessionFactory.openSession();
            
            List<Category> list=session.selectList("listCategory");
            
            for(Category category:list){
                System.out.println(category);
                List<Product> pro_list=category.getProducts();
                for(Product product:pro_list){
                    System.out.println(product);
                }
            }
            
            session.commit();
            session.close();
        }
    }
    View Code

    2、多对一的关系

    也就是一对多的反过来吧,Product产品和Category分类是多对一,多个产品对应一个分类。

      2.1修改Product的pojo实体类,提供Category属性

    package com.demo.pojo;
    
    public class Product{
        private int id;
        private String name;
        private float price;
        private Category category;//分类属性
        
        //属性的getter/setter方法
        public int getId(){
            return id;
        }
        public void setId(int id){
            this.id=id;
        }
        public String getName(){
            return name;
        }
        public void setName(String name){
            this.name=name;
        }
        public float getPrice(){
            return price;
        }
        public void setPrice(float price){
            this.price=price;
        }
        public Category getCategory(){
            return category;
        }
        public void setCategory(Category category){
            this.category=category;
        }
    }
    View Code

      2.2、修改Prodcut.xml映射文件

    使用assocation标签进行多对一的关系关联,配置。同样还是老问题,因为Category和Product实体类的属性都有id,name所有要进行别名来区分。

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DID Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
            <mapper namespace="com.demo.pojo">
                <!--resultType和resultMap的区别:1、resultType是直接返回类型的,也就是pojo对象的实体
                2、resultMap是对外部resultMap的引用,是key-value关系的映射
                3、resultType和resultMap是不能同时存在的-->
                <resultMap type="Product" id="productgoryBean">
                    <id column="pro_id" property="id"/><!--由于Category和Product都有id和name属性,mybatis不知道谁是谁的,所以要别名加以区分-->
                    <result column="pro_name" property="name"/>
                    
                    <!--多对一的关系,property:属性名称,javaType属性的类型-->
                    <association property="category javaType="Category">
                        <id column="cat_id" property="id"/>
                        <result column="cat_name" property="name"/>
                    </association>
                </resutlMap>
                
                <!--关联Category和Product的表的查询语句-->
                <select id="listproduct" resultMap="productBean">
                    select A.*,B.* from product_table A left join category_table B on A.id=B.id
                </select>
            </mapper>
    View Code

      2.3、测试TestMyBatis,代码同上,不在写。

    3、多对多的关系

    在多对一的基础上,延伸为多对多,User和Product的关系,用户可以购买多个产品,多个也可以购买同一个产品,但是多对多关系比较复杂,为了维护多对多的关系,必须建立一个中间表。可以建立一个Menu表来作为维护表。

      3.1、建立User表

    --创建user表
    create user_table(
        id int(10) not null auto_increment,
        name varchar(50) default null,
        primary key(id)
    )engine=myisam auto_increment=1 default charset=utf-8;

      3.2、建立Menu表

    --建立Menu表
    create menu_table(
        id int(10) not null auto_increment,
        pro_id int(10),--产品的id
        usr_id int(10),--用户的id
        number int,
        primary key(id)
    )auto_increment=1 default charset=utf-8;

      3.3、建立User的实体类

    给user的pojo加入Menu菜单的属性

    package com.demo.pojo;
    
    import java.util.List;
    
    public class User {
        private int id;
        private String name;
        
        List<Menu> menu;//中间表的属性
        
        //属性的getter/setter方法
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public List<Menu> getMenu() {
            return menu;
        }
        public void setMenu(List<Menu> menu) {
            this.menu = menu;
        }
    
    }
    View Code

      3.4、建立Menu的实体类

    用来维护User和Product的关系

    package com.demo.pojo;
    
    public class Menu {
        private int id;
        private int number;//数量
        private User user;//用户
        private Product product;//产品
        
        //属性的getter/setter方法
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public int getNumber() {
            return number;
        }
        public void setNumber(int number) {
            this.number = number;
        }
        public User getUsers() {
            return user;
        }
        public void setUser(User user) {
            this.user = user;
        }
        public Product getProduct() {
            return product;
        }
        public void setProduct(Product product) {
            this.product = product;
        }
        
    }
    View Code

      3.5、配置User.xml的映射文件

    加入对Product属性的配置,以及Menu自己属性的配置

    <?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.demo.pojo">
            <resultMap type="User" id="userBean">
            
                <!--配置User属性-->
                <id column="usr_id" property="id" />
                <result column="usr_name" property="name" />
                
                <!--配置Menu自己特有的属性-->
                <collection property="menu" ofType="Menu">
                    <id column="menu_id" property="id" />
                    <result column="number" property="number" />
                    <!--配置User与Product的关系-->
                    <association property="product" javaType="Product">
                        <id column="pro_id" property="id"/>
                        <result column="pro_name" property="name"/>
                        <result column="price" property="price"/>
                    </association>                
                </collection>
                
            </resultMap>
            
            <select id="listUser" resultMap="userBean">
                select A.*,B.*,C.* from user_table A
                    left join menu_table B    on A.id =B.id 
                    left join product_ table C on A.id = C.id 
            </select>
                
            <select id="getUser" resultMap="userBean">
                select A.*,B.*,C.* from user_table A
                    left join menu_table B on A.id =B.id 
                    left join product_ table C on A.id = C.id 
                where A.id = #{id} 
            </select>
        </mapper>
    View Code

      3.6、配置Product.xml的映射文件

    加入对Category的属性配置,实现Prodcut与Category的多对一关系

    <?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.demo.pojo">
            <resultMap type="Product" id="productBean">
                <id column="pro_id" property="id" />
                <result column="pro_name" property="name" />
                <result column="price" property="price" />
        
                <!-- 配置Product与Category的多对一的关系 -->
                <!-- property: 指的是属性名称, javaType:指的是属性的类型 -->
                <association property="category" javaType="Category">
                    <id column="cat_id" property="id"/>
                    <result column="cat_name" property="name"/>
                </association>
            </resultMap>
    
            <select id="listProduct" resultMap="productBean">
                select A.*,B.* from category_ table A 
                    left join product_ table B on A.id = B.id
            </select>    
            <select id="getProduct" resultMap="productBean">
                select A.*,B.* from category_ table A 
                    left join product_ table B on A.id = B.id
                where A.id = #{id}
            </select>    
        </mapper>
    View Code

      3.7、配置Menu.xml的映射文件

    <?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.demo.pojo">
        
            <insert id="addMenu" parameterType="Menu">
                insert into menu_table 
                    values(null,#{user.id},#{product.id},#{number})
            </insert>    
            <insert id="deleteMenu" parameterType="Menu">
                delete from menu_table 
                    where usr_id = #{user.id} and pro_id = #{product.id}
            </insert>    
        
        </mapper>
    View Code

      3.8、在mybatis-config.xml配置文件中加入上面的映射文件就行。

    二、基于MyBatis的对象关系配置(基于注解方式的配置)

     1、一对多的关系

    实现注解方式配置,肯定要增加Mapper接口,还是举例Category分类和Product产品的一对多关系

      1.1、增加CategoryMapper接口

    注解:@Select注解:获取Category类,也就是用来给select语句起作用的

       @Results注解:有两个注解,@Result获取结果,@Many中调用ProductMapper的listProduct()方法实现一对多关系

    import org.apache.ibatis.annotations.Results;
    import org.apache.ibatis.annotations.Select;
    
    import com.demo.pojo.Category;
    
    public interface CategoryMapper{
        
        @Select(" select * from category_table ")
        @Results({
                                @Result(property="id",column="id"),
                                @Result(property="products",javaType=List.class,column="id",many=@Many(select="com.demo.mapper.ProductMapper.listProduct"))
                        })//@Many中调用ProductMapper的listProduct()方法实现一对多关系
        public List<Category> list();
    }
    View Code

      1.2、增加ProductMapper接口

    package com.demo.mapper;
     
    import java.util.List;
    
    import org.apache.ibatis.annotations.Select;
    
    import com.demo.pojo.Product;
     
    public interface ProductMapper {
     
        @Select(" select * from product_table where id = #{id}")
        public List<Product> listProduct(int id);
        
    }
    View Code

      1.3、将CategoryMapper和ProductMapper配置到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>
        <typeAliases>
          <package name="com.demo.pojo"/>
        </typeAliases>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/demo?characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="admin"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
                <!--将基于注解配置的实体类映射文件Mapper添加进来-->
            <mapper class="com.demo.mapper.CategoryMapper"/>  
            <mapper class="com.demo.mapper.ProductMapper"/>  
        </mappers>
    </configuration>
    View Code

      1.4、测试注解方式TestMyBatis

    package com.demo;
      
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import com.demo.mapper.ProductMapper;
    import com.demo.pojo.Product;
      
    public class TestMybatis {
      
        public static void main(String[] args) throws IOException {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession session = sqlSessionFactory.openSession();
            //加载基于注解方式的映射文件
            ProductMapper mapper = session.getMapper(ProductMapper.class);
    
            List<Category> list= mapper.list();
            for (Category category: list) {
                System.out.println(category.getName());
                             List<Product>  pro_list=category.getProducts();
                            for(Product product:pro_list){
                                System.out.println(product.getName());
                            }
                    }
    
            session.commit();
            session.close();
      
        }
    }    
    View Code

    2、多对一关系

    同样是反过来,都是增加Mapper接口,Product和Category是多对一关系

      2.1、修改CategoryMapper接口

    package com.demo.mapper;
     
    import org.apache.ibatis.annotations.Select;
    
    import com.demo.pojo.Category;
     
    public interface CategoryMapper {
        @Select(" select * from category_table where id = #{id}")
        public Category get(int id);
        
    }
    View Code

      2.2、修改ProductMapper接口

    package com.demp.mapper;
     
    import java.util.List;
    
    import org.apache.ibatis.annotations.One;
    import org.apache.ibatis.annotations.Result;
    import org.apache.ibatis.annotations.Results;
    import org.apache.ibatis.annotations.Select;
    
    import com.demo.pojo.Product;
     
    public interface ProductMapper {
        @Select(" select * from product_table ")
        @Results({  
            @Result(property="category",column="cid",one=@One(select="com.demo.mapper.CategoryMapper.get"))  
        }) //@One表示多对一关系
        public List<Product> list();
    }
    View Code

      2.3、测试注解方式TestMyBatis

    package com.demo;
      
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import com.demo.mapper.ProductMapper;
    import com.demo.pojo.Product;
      
    public class TestMybatis {
      
        public static void main(String[] args) throws IOException {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession session = sqlSessionFactory.openSession();
            //加载基于注解方式的映射文件
            ProductMapper mapper = session.getMapper(ProductMapper.class);
    
            List<Product> list= mapper.list();
            for (Product product : list) {
                System.out.println(product + "	对应的分类是:	" + product.getCategory().getName());
            }
    
            session.commit();
            session.close();
      
        }
    }
    View Code

    3、多对多的关系

    还是一样,User和Product的多对多关系

      3.1、修改ProductMapper接口

    提供一个根据id获取product_table数据的get方法

    package com.demo.mapper;
    
    import org.apache.ibatis.annotations.Select;
    
    import com.demo.pojo.Product;
    
    public interface ProductMapper{
        @Select(" select * from product_table where id=#{id}")
        public Product get(int id);
    }
    View Code

      3.2、建立UserMapper接口

    提供一个list方法,用来建立一对多关系

    package com.demo.mapper;
    
    import java.util.List;
    
    import org.apache.ibatis.annotations.Many;
    import org.apache.ibatis.annotations.Result;
    import org.apache.ibatis.annotations.Results;
    import org.apache.ibatis.annotations.Select;
    
    import com.demo.pojo.User;
    
    public interface UserMapper {
        
        @Select(" select * from user_table where id = #{id}")
        @Results({  
                @Result(property="id",column="id"),
            @Result(property="menu",column="id",javaType=List.class,many=@Many(select="com.demo.mapper.MenuMapper.listMenu"))  
        })     
        public List<User> list();
    }
    View Code

      3.3、建立MenuMapper接口

    提供listMenu方法,建立Product的多对一关系。

    package com.demo.mapper;
    
    import java.util.List;
    
    import org.apache.ibatis.annotations.One;
    import org.apache.ibatis.annotations.Result;
    import org.apache.ibatis.annotations.Results;
    import org.apache.ibatis.annotations.Select;
    
    import com.demo.pojo.Menu;
    
    public interface MenuMapper {
        
        @Select(" select * from menu_table where id = #{id}")
        @Results({  
            @Result(property="product",column="id",one=@One(select="com.demo.mapper.ProductMapper.get"))  
        })     
        public List<Menu> listMenu(int id);
    }
    View Code

      3.4、把注解的映射文件加入到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>
        <typeAliases>
          <package name="com.demo.pojo"/>
        </typeAliases>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/demo?characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="admin"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
        <!--注释掉原来基于xml配置方式的映射文件-->
                <!--
            <mapper resource="com/demo/pojo/Category.xml"/>
            <mapper resource="com/demo/pojo/Product.xml"/>
            <mapper resource="com/demo/pojo/User.xml"/>
            <mapper resource="com/demo/pojo/Menu.xml"/>
            -->
            <mapper class="com.demo.mapper.MenuMapper"/>
            <mapper class="com.demo.mapper.UserMapper"/>
            <mapper class="com.demo.mapper.ProductMapper"/>
        </mappers>
    </configuration>
    View Code

      3.5、测试注解方式TestMyBatis

    package com.demo;
      
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import com.demo.mapper.ProductMapper;
    import com.demo.pojo.Product;
      
    public class TestMybatis {
      
        public static void main(String[] args) throws IOException {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession session = sqlSessionFactory.openSession();
            //加载基于注解方式的映射文件
            UserMapper mapper = session.getMapper(UserMapper.class);
    
            List<User> list= mapper.list();
            for (User user : list) {
                        System.out.println(user.getName());
                        List<Menu> menu_list=user.getMenu();
                        if(menu_list!=null){
                            for(Menu menu:menu_list){
                                System.out.println(menu.getProduct().getId(),menu.getProduct().getName(),menu.getProduct().getPrice(),menu.getNumber());
                            }
                        }
                    }
    
            session.commit();
            session.close();
      
        }
    }
    View Code
  • 相关阅读:
    Python 反射
    Python 类描述符-Descriptor
    Python 面向对象三大特性-多态
    Python 面向对象三大特性-继承
    Python 面向对象三大特性-封装
    面向对象编程
    python之mysqldb模块安装
    Redis应用-分布式锁
    ide phpStorm使用git的命令行工具
    mysql中用命令行复制表结构(数据)
  • 原文地址:https://www.cnblogs.com/drq1/p/8532951.html
Copyright © 2011-2022 走看看