zoukankan      html  css  js  c++  java
  • Java进阶知识14 Hibernate查询语言(HQL),本文以hibernate注解版为例讲解

    1、简单概述          

    1.1、

    1) SQL:面向的是数据库 select * from tableName;
    2) HQL查询(Hibernate Query language): hibernate 提供的面向对象的查询语言。
        例:Session.createQuery(“from tableName”)  //和第1)点的SQL语句恒等的,查询出来的效果是一样的
    3) Criteria 查询,完全面向对象的查询(Query By Criteria  ,QBC)
    4) SQLQuery, 本地SQL查询,逻辑比较复杂,HQL很难实现

          缺点:不能跨数据库平台,如果改了数据库,sql语句有可能要改
          使用场景: 对于复杂sql,hql实现不了的情况,可以使用本地sql查询

    HQL查询要注意:
          1、使用hql查询的时候 auto-import="true" 要设置true,如果是false,写hql的时候,要指定类的全名,例如:
               1.1、 Query q = session.createQuery("from Employee"); //auto-import="true"的时候
                1.2、Query q = session.createQuery("from com.shore.model.Employee"); //auto-import="false"的时候

           2、用注解版时,auto-import="true" (默认为true)写不写类的全名,都是可以的。用xml 配置版时,需要指定 auto-import="true" ,这样省代码,不指定为true,则像上面第1点的第1.2小点那样写。

    1.2、查询全部列

    1 Query query = session.createQuery("from Employee"); //OK
    2 Query query = session.createQuery("from com.shore.model.Employee"); //OK
    3 Query query = session.createQuery("select * from Employee"); //错误,不支持 *
    4 Query query = session.createQuery("select e from Employee e"); // OK
    5 System.out.println(query.list()); //把结果打印到控台上

    1.3、查询指定的列

    1 Query query = session.createQuery("select name,sex,salary from Employee");
    2 System.out.println(query.list());

    1.4、查询指定的列,自动封装为对象

    1 Query query = session.createQuery("select new com.shore.model.SubEmployee(name,sex,salary) from Employee");
    2 System.out.println(query.list());

    1.5、条件查询

      1.5.1、条件查询之占位符(?)

    1 Query query = session.createQuery("select new com.shore.model.SubEmployee(name,sex,salary) from Employee where department_id = ?");
    2 //query.setParameter(0, 1);//或者下面的setInteger(0, 1)方法也行
    3 query.setInteger(0, 1);
    4 System.out.println(query.list());

      1.5.2、条件查询之命名参数(:

    1 Query query = session.createQuery("select new com.shore.model.SubEmployee(name,sex,salary) from Employee where department_id = :deptID");
    2 query.setParameter("deptID", 1);
    3 System.out.println(query.list());

      1.5.3、条件查询之范围查询(between .... and  ... )

    1 Query query = session.createQuery("select new com.shore.model.SubEmployee(name,sex,salary) from Employee where department_id between :d1 and :d2");
    2 query.setParameter("d1", 1);   //也可以用占位符?实现
    3 query.setParameter("d2", 2);
    4 System.out.println(query.list());

      1.5.4、条件查询之模糊查询   like

    1 Query query = session.createQuery("select new com.shore.model.SubEmployee(name,sex,salary)  from Employee where name like ?");
    2 query.setParameter(0, "%三%");
    3 System.out.println(query.list());

    1.6、聚合函数统计

    1 Query query = session.createQuery("select count(*) from Employee where name like ?");
    2 query.setParameter(0, "%三%");
    3 System.out.println(query.list());

    1.7、分组查询(group by

    1 //MySQL数据库写法:select department_id,count(*) from employee group by department_id;
    2
    Query query = session.createQuery("select department,count(*) from Employee group by department_id"); //根据部门外键 3 System.out.println(query.list());

    1.8、连接查询 (内连接、外连接、左/右连接等)

      内连接:Join == inner join  //交集
      左连接:Left join,以左边的表为主表,如果没有join上,左边表数据完整,右边表的数据可能为空 。//左边表的所有数据+右边表的交集部分
      右连接:Right join,以右边的表为主表,如果没有join上,右边表数据完整,左边表的数据可能为空。//右边表的所有数据+左边表的交集部分
      外连接:Outer join  //并集

     1 1) 内连接   【映射已经配置好了关系,关联的时候,直接写对象的属性即可】
     2 Query q = session.createQuery("from Employee e inner join e.department"); //department是Employee实体中映射的一个外键(Employee表中的department_id)
     3 
     4 2) 左外连接
     5 Query q = session.createQuery("from Employee e left join e.department");
     6 
     7 3) 右外连接
     8 Query q = session.createQuery("from Department d right join d.employee"); //映射的一个外键(employee_id)
     9 
    10 4) 迫切内连接    【使用fetch, 会把右表的数据,填充到左表对象中!】
    11 Query q = session.createQuery("from Employee e inner join fetch e.department");
    12 q.list();
    13         
    14 5) 迫切左外连接
    15 Query q = session.createQuery("from Employee e left join fetch e.department");

    1.9、HQL查询优化

    1 Query query = session.getNamedQuery("getAllDept"); //定义一个参数名 getAllDept
    2 query.setParameter(0, 10);

      然后在对应的xml 配置文件中 写SQL语句。(对于发杂的SQL语句,可以这样做,方便项目发布后,还可以修改)

    1 比如在:Employee.hbm.xml 在xml中存放sql语句 2     <query name="getAllDept">  //这里的参数名 getAllDept 要和上面的对应
    3         <![CDATA[
    4             from Employee d where department_id < ?;  //这里写SQL语句,不是HQL语句
    5         ]]>
    6     </query>

    2、HQL查询语言 实例  

    2.1、创建 Employee类、Department类、SubEmployee类、HomeTown类

     1 package com.shore.model;
     2 
     3 import javax.persistence.CascadeType;
     4 import javax.persistence.Entity;
     5 import javax.persistence.GeneratedValue;
     6 import javax.persistence.Id;
     7 import javax.persistence.ManyToOne;
     8 import org.hibernate.annotations.Type;
     9 
    10 /**
    11  * @author DSHORE/2019-9-25
    12  * 多对一,单向关联(注解版)
    13  */
    14 @Entity
    15 public class Employee {//员工  (“多”的一方),在多的一方加外键
    16     private Integer id;
    17     private String name;
    18     private Boolean sex;
    19     private Float salary;
    20     private Department department;
    21     private Integer homeId;
    22 
    23     @Id
    24     @GeneratedValue
    25     public Integer getId() {
    26         return id;
    27     }
    28     public void setId(Integer id) {
    29         this.id = id;
    30     }
    31     public String getName() {
    32         return name;
    33     }
    34     public void setName(String name) {
    35         this.name = name;
    36     }
    37 
    38     @Type(type="yes_no")
    39     public Boolean getSex() {
    40         return sex;
    41     }
    42     public void setSex(Boolean sex) {
    43         this.sex = sex;
    44     }
    45     public Float getSalary() {
    46         return salary;
    47     }
    48     public void setSalary(Float salary) {
    49         this.salary = salary;
    50     }
    51 
    52     @ManyToOne(cascade=CascadeType.ALL)
    53     public Department getDepartment() {
    54         return department;
    55     }
    56     public void setDepartment(Department department) {
    57         this.department = department;
    58     }
    59 
    60     @Override
    61     public String toString() {
    62         return "Employee [id=" + id + ", name=" + name + ", sex=" + sex
    63                 + ", salary=" + salary + ", department=" + department + "]";
    64     }
    65     public Integer getHomeId() {
    66         return homeId;
    67     }
    68     public void setHomeId(Integer homeId) {
    69         this.homeId = homeId;
    70     }
    71 }

    Department类

     1 package com.shore.model;
     2 
     3 import javax.persistence.Entity;
     4 import javax.persistence.GeneratedValue;
     5 import javax.persistence.Id;
     6 
     7 /**
     8  * @author DSHORE/2019-9-25
     9  * 多对一,单向关联(注解版)
    10  */
    11 @Entity
    12 public class Department {//部门 (“一”的一方)
    13     private Integer id;
    14     private String name;
    15     private String description;
    16 
    17     @Id
    18     @GeneratedValue
    19     public Integer getId() {
    20         return id;
    21     }
    22     public void setId(Integer id) {
    23         this.id = id;
    24     }
    25     public String getName() {
    26         return name;
    27     }
    28     public void setName(String name) {
    29         this.name = name;
    30     }
    31     public String getDescription() {
    32         return description;
    33     }
    34     public void setDescription(String description) {
    35         this.description = description;
    36     }
    37     @Override
    38     public String toString() {
    39         return "Department [id=" + id + ", name=" + name + ", description="
    40                 + description + "]";
    41     }
    42 }

    SubEmployee类

     1 package com.shore.model;
     2 
     3 /**
     4  * @author DSHORE/2019-9-25
     5  *
     6  */
     7 public class SubEmployee {//查询指定的列,自动封装为对象时 用到(此处不需要创建数据库表)
     8     private String name;
     9     private Boolean sex;
    10     private Float salary;
    11 
    12     public SubEmployee(String name, Boolean sex, Float salary) {
    13         super();
    14         this.name = name;
    15         this.sex = sex;
    16         this.salary = salary;
    17     }
    18 
    19     public SubEmployee() {
    20         super();
    21     }
    22 
    23     public String getName() {
    24         return name;
    25     }
    26 
    27     public void setName(String name) {
    28         this.name = name;
    29     }
    30 
    31     public Boolean getSex() {
    32         return sex;
    33     }
    34 
    35     public void setSex(Boolean sex) {
    36         this.sex = sex;
    37     }
    38 
    39     public Float getSalary() {
    40         return salary;
    41     }
    42 
    43     public void setSalary(Float salary) {
    44         this.salary = salary;
    45     }
    46 
    47     @Override
    48     public String toString() {
    49         return "SubEmployee [name=" + name + ", sex=" + sex + ", salary="
    50                 + salary + "]";
    51     }
    52 }

    HomeTown类

     1 package com.shore.model;
     2 
     3 /**
     4  * @author DSHORE/2019-9-25
     5  *
     6  */
     7 //后来加入的,没配注解,数据库表和数据都是手动创建的
     8 public class HomeTown {//在使用“连接查询”时用到(内连接、外连接、左/右连接等)
     9     private Integer id;
    10     private String address;
    11 
    12     public Integer getId() {
    13         return id;
    14     }
    15     public void setId(Integer id) {
    16         this.id = id;
    17     }
    18     public String getAddress() {
    19         return address;
    20     }
    21     public void setAddress(String address) {
    22         this.address = address;
    23     }
    24 }

    2.2、创建 hibernate.cfg.xml 核心配置文件

     1 <?xml version='1.0' encoding='utf-8'?>
     2 <!DOCTYPE hibernate-configuration PUBLIC
     3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
     4         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
     5 
     6 <hibernate-configuration>
     7     <session-factory>
     8         <!-- Database connection settings -->
     9         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    10         <property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
    11         <property name="connection.username">root</property>
    12         <property name="connection.password">123456</property>
    13 
    14         <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    15         <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
    16         <property name="show_sql">true</property>
    17         <property name="hbm2ddl.auto">update</property>
    18 
    19         <mapping class="com.shore.model.Employee" />
    20         <mapping class="com.shore.model.Department" />
    21     </session-factory>
    22 </hibernate-configuration>

    2.3、开始测试

      1 package com.shore.test;
      2 
      3 import java.util.ArrayList;
      4 import java.util.List;
      5 
      6 import org.hibernate.Query;
      7 import org.hibernate.Session;
      8 import org.hibernate.SessionFactory;
      9 import org.hibernate.Transaction;
     10 import org.hibernate.cfg.AnnotationConfiguration;
     11 import org.junit.AfterClass;
     12 import org.junit.BeforeClass;
     13 import org.junit.Test;
     14 
     15 import com.shore.model.Department;
     16 import com.shore.model.Employee;
     17 
     18 /**
     19  * @author DSHORE/2019-9-19
     20  *
     21  */
     22 public class MyTest {
     23     public static SessionFactory sessionFactory = null;
     24     public static Session session = null;
     25 
     26     @BeforeClass
     27     public static void buildSessionFactory() {
     28         sessionFactory = new AnnotationConfiguration().configure()
     29                 .buildSessionFactory();
     30     }
     31 
     32     @AfterClass
     33     public static void close() {
     34         session.close();
     35         sessionFactory.close();
     36     }
     37 
     38     /**
     39      * 单向多对一:多个员工 对 一个部门
     40      */
     41     /*@Test
     42     public void testAdd() {//插入数据
     43         session = sessionFactory.openSession();
     44         Transaction transaction = session.beginTransaction();
     45         Department dept1 = new Department();
     46         Department dept2 = new Department();
     47         dept1.setName("总裁办");
     48         dept1.setDescription("秘书");
     49         dept2.setName("市场部");
     50         dept2.setDescription("经理");
     51 
     52         Employee em1 = new Employee();
     53         em1.setName("张三");
     54         em1.setSex(true);
     55         em1.setSalary(5999.00f);
     56         em1.setDepartment(dept1);
     57 
     58         Employee em2 = new Employee();
     59         em2.setName("李四");
     60         em2.setSex(true);
     61         em2.setSalary(5999.00f);
     62         em2.setDepartment(dept2);
     63 
     64         Employee em3 = new Employee();
     65         em3.setName("王五");
     66         em3.setSex(true);
     67         em3.setSalary(5999.00f);
     68         em3.setDepartment(dept1);
     69 
     70         Employee em4 = new Employee();
     71         em4.setName("赵六");
     72         em4.setSex(true);
     73         em4.setSalary(5999.00f);
     74         em4.setDepartment(dept1);
     75 
     76         Employee em5 = new Employee();
     77         em5.setName("田七");
     78         em5.setSex(true);
     79         em5.setSalary(5999.00f);
     80         em5.setDepartment(dept2);
     81 
     82         session.save(em1); // 先创建dept1并数据,后创建em1并插入数据
     83         session.save(em2); // 先创建dept2并数据,后插入em2的数据
     84         session.save(em3);
     85         session.save(em4);
     86         session.save(em5);
     87         transaction.commit();
     88     }*/
     89 
     90     /**
     91      * hql :1、查询全部列
     92      */
     93     @SuppressWarnings("unchecked")
     94     @Test
     95     public void testListAllEmployee() {
     96         session = sessionFactory.openSession();
     97         Transaction transaction = session.beginTransaction();
     98         List<Employee> list = new ArrayList<Employee>();
     99         Query query = session.createQuery("select e from Employee e");
    100         //或者这样写:Query query = session.createQuery("from Employee"); 效果是一样的
    101         list = query.list();
    102         transaction.commit();
    103 
    104         System.out.println("!!!!!!!!!!!!!!");
    105         if (list != null && list.size() > 0) {
    106             for (int j = 0; j < list.size(); j++) {
    107                 System.out.println(j + ":" + list.get(j));
    108             }
    109         }
    110         /** testListAllEmployee()运行结果:
    111          * !!!!!!!!!!!!!!
    112          * 0:Employee [id=1, name=张三, sex=true, salary=5999.0, department=Department [id=1, name=总裁办, description=秘书]]
    113          * 1:Employee [id=2, name=李四, sex=true, salary=5999.0, department=Department [id=2, name=市场部, description=经理]]
    114          * 2:Employee [id=3, name=王五, sex=true, salary=5999.0, department=Department [id=1, name=总裁办, description=秘书]]
    115          * 3:Employee [id=4, name=赵六, sex=true, salary=5999.0, department=Department [id=1, name=总裁办, description=秘书]]
    116          * 4:Employee [id=5, name=田七, sex=true, salary=5999.0, department=Department [id=2, name=市场部, description=经理]]
    117          */
    118     }
    119 
    120     /**
    121      * hql: 2、查询指定的列
    122      */
    123     @Test
    124     public void testListSubField() {
    125         session = sessionFactory.openSession();
    126         Transaction transaction = session.beginTransaction();
    127         Query query = session.createQuery("select name,sex,salary from Employee");
    128         System.out.println(query.list());
    129         transaction.commit();
    130         /** testListSubField()运行结果:
    131          * [[Ljava.lang.Object;@259a8416, [Ljava.lang.Object;@4355d3a3, [Ljava.lang.Object;@37b994de, [Ljava.lang.Object;@78dc9766, [Ljava.lang.Object;@5a57e787]
    132          */
    133     }
    134 
    135     /**
    136      * hql: 3、查询指定的列,自动封装为对象
    137      * 注意:必须要提供带参数构造器;必须在hql封装类前面要加上package名称
    138      */
    139     @Test
    140     public void testListSubFieldsToObj() {
    141         session = sessionFactory.openSession();
    142         Transaction transaction = session.beginTransaction();
    143         Query query = session.createQuery("select new com.shore.model.SubEmployee(name,sex,salary) from Employee");
    144         System.out.println(query.list());
    145         transaction.commit();
    146         /** testListSubFieldsToObj()运行结果:
    147          * [SubEmployee [name=张三, sex=true, salary=5999.0], SubEmployee [name=李四, sex=true, salary=5999.0], SubEmployee [name=王五, sex=true, salary=5999.0], SubEmployee [name=赵六, sex=true, salary=5999.0], SubEmployee [name=田七, sex=true, salary=5999.0]]
    148          */
    149     }
    150 
    151     /**
    152      * hql: 4 、条件查询
    153      *      4.1、条件查询之占位符(?)
    154      */
    155     @Test
    156     public void testListByConditions1() {
    157         session = sessionFactory.openSession();
    158         Transaction transaction = session.beginTransaction();
    159         Query query = session.createQuery("select new com.shore.model.SubEmployee(name,sex,salary) " +
    160                         "from Employee where department_id=?"); //用department_id或department都是可以的
    161         //query.setParameter(0, 1);//或者下面的setInteger(0, 1)方法也行
    162         query.setInteger(0, 1); //类似于JDBC中的 PreparedStatement
    163         System.out.println(query.list());
    164         transaction.commit();
    165         /** testListByConditions1()运行结果:
    166          * [SubEmployee [name=张三, sex=true, salary=5999.0], SubEmployee [name=王五, sex=true, salary=5999.0], SubEmployee [name=赵六, sex=true, salary=5999.0]]
    167          */
    168     }
    169     
    170     /**
    171      * hql: 4.2、条件查询之命名参数(:)
    172      */
    173     @Test
    174     public void testListByConditions2() {
    175         session = sessionFactory.openSession();
    176         Transaction transaction = session.beginTransaction();
    177         Query query = session.createQuery("select new com.shore.model.SubEmployee(name,sex,salary) " +
    178                         "from Employee where department_id=:deptID");
    179         query.setParameter("deptID", 1);
    180         System.out.println(query.list());
    181         transaction.commit();
    182         /** testListByConditions2()运行结果:
    183          * [SubEmployee [name=张三, sex=true, salary=5999.0], SubEmployee [name=王五, sex=true, salary=5999.0], SubEmployee [name=赵六, sex=true, salary=5999.0]]
    184          */
    185     }
    186     
    187     /**
    188      * hql: 4.3、条件查询之范围查询
    189      * between 1 and 10    []闭区间  mysql    1<=x<=10
    190      */
    191     @Test
    192     public void testListByConditions3() {
    193         session = sessionFactory.openSession();
    194         Transaction transaction = session.beginTransaction();
    195         Query query = session.createQuery("select new com.shore.model.SubEmployee(name,sex,salary) " +
    196                         "from Employee where department_id between :d1 and :d2");
    197         query.setParameter("d1", 1);   //也可以用占位符?实现
    198         query.setParameter("d2", 2);
    199         System.out.println(query.list());
    200         transaction.commit();
    201         /** testListByConditions3()运行结果:
    202          * [SubEmployee [name=张三, sex=true, salary=5999.0], SubEmployee [name=王五, sex=true, salary=5999.0], SubEmployee [name=赵六, sex=true, salary=5999.0]]
    203          */
    204     }
    205     
    206     /**
    207      * hql: 4.4、条件查询之模糊查询  like
    208      */
    209     @Test
    210     public void testListByConditions4() {
    211         session = sessionFactory.openSession();
    212         Transaction transaction = session.beginTransaction();
    213         Query query = session.createQuery("select new com.shore.model.SubEmployee(name,sex,salary) " +
    214                         "from Employee where name like ?");
    215         query.setParameter(0, "%三%");
    216         System.out.println(query.list());
    217         transaction.commit();
    218         /** testListByConditions4()运行结果:
    219          * [SubEmployee [name=张三, sex=true, salary=5999.0]]
    220          */
    221     }
    222     
    223     /**
    224      * hql: 5、聚合函数统计
    225      */
    226     @Test
    227     public void testListByCount() {
    228         session = sessionFactory.openSession();
    229         Transaction transaction = session.beginTransaction();
    230         Query query = session.createQuery("select count(*) " +
    231                         "from Employee where name like ?");
    232         query.setParameter(0, "%三%");
    233         System.out.println(query.list());
    234         transaction.commit();
    235         /** testListByCount()运行结果:
    236          * [1]
    237          */
    238     }
    239     
    240     /**
    241      * hql: 6、分组查询group by
    242      */
    243     @Test
    244     public void testListByDept() {
    245         session = sessionFactory.openSession();
    246         Transaction transaction = session.beginTransaction();
    247         Query query = session.createQuery("select department,count(*) " +
    248                         "from Employee group by department_id");
    249         System.out.println(query.list());
    250         transaction.commit();
    251         /** testListByDept()运行结果:
    252          * [[Ljava.lang.Object;@3b35b1f3, [Ljava.lang.Object;@4235e6e3]
    253          */
    254     }
    255     
    256     /**
    257      * hql: 7、连接查询
    258      *    7.1、内连接 
    259      */
    260     @Test
    261     public void testListByInnerJoin() {
    262         session = sessionFactory.openSession();
    263         Transaction transaction = session.beginTransaction();
    264         Query query = session.createQuery("from Employee e inner join e.department");
    265         System.out.println(query.list());
    266         transaction.commit();
    267         /**
    268          * 运行结果:
    269          * [[Ljava.lang.Object;@60c9630a, [Ljava.lang.Object;@4585572a, [Ljava.lang.Object;@351daa0e, [Ljava.lang.Object;@2e879860, [Ljava.lang.Object;@4824de7d]
    270          */
    271     } 
    272     
    273     /**
    274      * 7.2、左连接
    275      */
    276     @Test
    277     public void testListByLeftJoin() {
    278         session = sessionFactory.openSession();
    279         Transaction transaction = session.beginTransaction();
    280         Query query = session.createQuery("from Employee e left join e.department");
    281         System.out.println(query.list());
    282         transaction.commit();
    283         /**
    284          * 运行结果:
    285          * [[Ljava.lang.Object;@5d15126e, [Ljava.lang.Object;@126d2380, [Ljava.lang.Object;@3b35b1f3, [Ljava.lang.Object;@4235e6e3, [Ljava.lang.Object;@60c9630a]
    286          */
    287     } 
    288     
    289     /**
    290      * 7.3、右连接
    291      */
    292     @Test
    293     public void testListByRightJoin() {
    294         session = sessionFactory.openSession();
    295         Transaction transaction = session.beginTransaction();
    296         Query query = session.createQuery("from Employee e right join e.department");
    297         System.out.println(query.list());
    298         transaction.commit();
    299         /**
    300          * 运行结果:
    301          * [[Ljava.lang.Object;@4235e6e3, [Ljava.lang.Object;@60c9630a, [Ljava.lang.Object;@4585572a, [Ljava.lang.Object;@351daa0e, [Ljava.lang.Object;@2e879860]
    302          */
    303     } 
    304 }

    数据库表的原数据图:

        

    1 SELECT 
    2     a.name,a.sex,b.address
    3 FROM
    4    (SELECT NAME,sex,homeId FROM employee WHERE homeId=1) a 
    5 LEFT JOIN
    6    (SELECT id,address FROM hometown WHERE id = 1) b
    7 ON 
    8    a.homeId = b.id; --MySQL语言 左连接查询

    结果图:

    原创作者:DSHORE

    作者主页:http://www.cnblogs.com/dshore123/

    原文出自:https://www.cnblogs.com/dshore123/p/11588358.html

    欢迎转载,转载务必说明出处。(如果本文对您有帮助,可以点击一下右下角的 推荐,或评论,谢谢!

  • 相关阅读:
    C# 实现 Snowflake算法生成唯一性Id
    kafka可视化客户端工具(Kafka Tool)的基本使用(转)
    docker 安装kafka
    Model类代码生成器
    使用docker 部署rabbitmq 镜像
    Vue 增删改查 demo
    git 提交代码到库
    Android ble蓝牙问题
    mac 配置 ssh 到git (Could not resolve hostname github.com, Failed to connect to github.com port 443 Operation timed out)
    okhttp
  • 原文地址:https://www.cnblogs.com/dshore123/p/11588358.html
Copyright © 2011-2022 走看看