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
  • 相关阅读:
    LintCode "Maximum Gap"
    LintCode "Wood Cut"
    LintCode "Expression Evaluation"
    LintCode "Find Peak Element II"
    LintCode "Remove Node in Binary Search Tree"
    LintCode "Delete Digits"
    LintCode "Binary Representation"
    LeetCode "Game of Life"
    LintCode "Coins in a Line"
    LintCode "Word Break"
  • 原文地址:https://www.cnblogs.com/drq1/p/8532951.html
Copyright © 2011-2022 走看看