转Hibernate3.0

Hibernate3.0
预备知识:
Core Java
JDBC
SQL
 
Hibernate理论基础
1.     什么是hibernate?
2.     hibernate的知识内容
3.     什么是对象持久化?对象持久化有什么用?(解决的问题)
4.     如何对象持久化?
5.     如何用数据库的方法做对象持久化?
6.     ORM(对象关系映射)是什么?有什么作用?
7.     ORM从对象到表所要考虑的问题
8.     什么是ORM框架?有什么用?
9.     使用hibernate的方法做对象持久化的工作,程序员应该怎么做?
10. hibernate有什么用?
11. 程序员和hibernate的整体工作流程
 
什么是hibernate:
持久化的框架,属于设计方面的内容,类库,用来做对象持久化的,什么是对象持久化呢?
 
Hibernate的知识内容:
语法部分(类库)
程序设计思想,也就是持久层的设计
 
什么是对象持久化?对象持久化有什么用?(解决的问题):
发现问题:
程序设计的架构: 表现层—业务层—持久层—数据库层,其中表现层和业务层是JVM来执行,应用程序会产生许多的对象,如果断电了,对象就消失了,也就是说在内存中的对象是不稳定的,状态不能持久
发现问题:
将一个对象从A电脑复制到B电脑,如何做到呢?
 
那么有三种方法解决上面的问题:
1.     序列化: 通过网络传递,或者硬盘共享
2.       存储到数据库中,谁想用,从数据库中拿
3.       EJB Entity Bean(实体Bean)
 
序列化的方法比较死板:如果当一个对象的结构比较复杂的时候,我们这时只需要一部分内容,没有办法,只能整个写入到文件,整个读取
序列化的缺点: 不能检索,不能分离一个对象,不方便共享
所以说第一种方法只能用于做临时的持久化,简单的传输,但不适合复杂的持久化工作
 
第二种方法(数据库持久化):检索方便,分布式共享,永久数据
 
总结:
什么是对象持久化: 对象持久化就是把内存中的对象永久的保存起来,保护对象的状态,方便使用
对象持久化有什么用: 1.解决掉电的问题 2.共享方便 3.保证对象安全检索方便
 
如何对象持久化:
1.     对象序列化
2.     数据库(JDBC,EJB,Hibernate)
 
如何用数据库的方法做对象持久化:
1.     JDBC
发现问题: 需要做大量的工作,难度大
2.     EJB
使用的是其中的一个功能来做持久化,解决了使用JDBC方法的的大量工作的问题
发现问题: EJB是重量级的组件,要使用它,有两个问题 1.成本 2.性能
 
发现问题: 以上两种方式还有个共同的问题,对象不是简单存储在数据库中的,比如多态的特点就不能处理 A b=new B(); B为A的子类
 
3.     Hibernate
解决了以上的所有问题,作用:1.不用做大量的工作 2.移植性能好 3.提高了代码的质量,简单 4.检索共享重用成本调试
 
ORM(对象关系映射)是什么?有什么作用?
发现问题:
java中的对象的属性类型和数据库中的字段类型是不一样的,那么如何来存储java中的对象呢?这就需要做对象关系的映射,也就是ORM
什么是ORM: 将内存中的对象和数据库做转化,这样就实现了java与数据库之间的访问等功能
 
ORM从对象到表所要考虑的问题:
Orm的复杂问题:
1.     数据库如何保证对象的唯一性:在内存中,两个对象属性值都一样,但是内存地址不一样,可以做区分,但是在数据库中如何分辨呢?
2.     继承关系如何转化
3.     集合如何映射呢?
 
什么是ORM框架?有什么用?
就是一个类库,通过这个类库完成持久化层的设计
 
使用hibernate的方法做对象持久化的工作,程序员应该怎么做?
1.     将ORM方案定下来,就是类到数据库的转化 2.利用hibernate生成代码
hibernate有什么用?
1.     完成jdbc的代码
2.     管理持久化对象的状态
3.     提供一个查询的API
 
程序员和hibernate的整体工作流程
程序员:
1.     设计ORM方案
2.     写配置文件
3.     调用Hibernate的API,向Hibernate发出命令
hibernate:
4.     读配置文件
5.     生成jdbc代码
6.     执行
 
Hibernate简单实例
Hibernate语法:
作用: 数据库的增删改查 HQL面向对象的查询语句
 
大致步骤:
1.     设置环境 类库
2.     定义映射
A 定义映射的实体po
B 建立数据库表
C 写XML配置文件(表,数据库)
3.     调用Hibernate API
A 管理po的状态(增删改,恢复po状态)
B 检索(查询)
 
Hibernate第一个简单的实例: 引例(frisHbn包)
1.     设置环境
hibernate配置环境需要的资源
Hibernate的jar包: lib.zip dtd.zip: dtd.zip可以不设置
2.     定义映射
建立项目:
bussiness包: entity包 Biz包业务
client包: 测试
util包: 工具
 
先写持久化类: 以花为实体,建立花类,并且建立数据库表
/**
 * 建表语句:
 * CREATE TABLE T_FRUIT(
   FID NUMBER(10) PRIMARY KEY,
   NAME VARCHAR(20) NOT NULL,
   COMMENTS VARCHAR(50),
   PRICE NUMBER(5) NOT NULL
);
 */
package Yuchen.fristHbn.business.entity;
//持久化类(花类),注意因为采用的是hilo的方式获得id,所以需要有setid的方法
public class Fruit {
     
      private Integer fid;//hibernate中的id不能识别int
      private String name;
      private String comments;
      private int price;
     
      public Fruit() {
            super();
      }
     
      public Fruit(String name, String comments, int price) {
            super();
            this.name = name;
            this.comments = comments;
            this.price = price;
      }
 
      public String getComments() {
            return comments;
      }
      public void setComments(String comments) {
            this.comments = comments;
      }
     
      public Integer getFid() {
            return fid;
      }
      public String getName() {
            return name;
      }
      public void setName(String name) {
            this.name = name;
      }
      public int getPrice() {
            return price;
      }
      public void setPrice(int price) {
            this.price = price;
      }
 
      public void setFid(Integer fid) {
            this.fid = fid;
      }
     
}
 
使用hilo的方式获得id:
建表语句:
CREATE TABLE T_HILO(HILO_ID NUMBER(10));
INSERT INTO T_HILO VALUES(1);
 
写hibernate的连接数据库的配置文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-configuration PUBLIC
      "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
      "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
      <session-factory>
            <property name="show_sql">true</property>
            <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
            <property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:name</property>
            <property name="connection.username">scott</property>
            <property name="connection.password">tiger</property>
            <property name="connection.isolation">2</property>
            <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
            <mapping resource="Yuchen/fristHbn/business/entity/Fruit.hbm.xml"/>
      </session-factory>
</hibernate-configuration>
 
写映射配置文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="Yuchen.fristHbn.business.entity">
      <class name="Fruit" table="T_FRUIT">
           <id name="fid" column="fid">
                 <generator class="hilo">
                       <param name="table">t_hilo</param>
                       <param name="column">hilo_id</param>
                 </generator>
            </id>
            <property name="name" column="name" />
            <property name="comments" column="comments"></property>
          <property name="price" column="price"></property>
      </class>
</hibernate-mapping>
A.    类名—表名
B.    id—id 获得id的方式 详细信息(如: hilo的表名和字段)
C.    属性—字段
 
使用hibernate API(FruitManager.java):
package Yuchen.fristHbn.business.Biz;
//业务逻辑类:负责增删改查通过使用hibernate API进行
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
 
import Yuchen.fristHbn.business.entity.Fruit;
 
public class FruitManager {
      public void insert(Fruit fruit){
            Configuration config=new Configuration();
            config.configure();//读配置文件
            SessionFactory sf=config.buildSessionFactory();//得到工厂
            Session session=sf.openSession();//得到session
            Transaction tt=session.beginTransaction();//检查事务开启
            session.save(fruit);//存储insert
            tt.commit();//提交
            session.close();//关闭资源
      }
}
 
 
 
写测试类: 插入一个对象到数据库中
/**
 * 知识点:
 * hibernate基础:练习语法部分API和简单的映射关系
 * 程序目标:
 * 使用hibernate方法将对象进行持久化
 * 实现数据库的增删改查
 * API:
 * 1.Configuration:这个类负责读取XML文档(映射配置文件)
 * configure():读xml
 * buildSessionFactory():创建一个生产session对象的工厂,其实是再次检查
 * 因为hibernate和jdbc不一样,jdbc是如果不手动设置开启事务,那它
 * 就是马上执行sql的,hibernate的不会马上执行,是事务提交后执行
 * 默认情况下就是打开事务的状态,这里只是再检查以下
 * 2.SessionFactory:负责生产session对象
 * openSession():创建一个session
 * 3.Session类:这个是主要的类,负责增删改查,开启事务等
 * beginTransaction():产生一个事务对象(Transaction)
 * save():增加相当于操作sql中的insert语句
 * 4.Transaction类:负责管理事务的
 * commit():提交一个事务
 *
 */
package Yuchen.fristHbn.client;
 
import Yuchen.fristHbn.business.Biz.FruitManager;
import Yuchen.fristHbn.business.entity.Fruit;
 
public class Test {
     
      public static void test1(){
           Fruit fruit=new Fruit("lisi","hello",100);
//       fruit.setName("zhangsan");
//       fruit.setComments("hello");
//       fruit.setPrice(100);
          
            FruitManager fm=new FruitManager();
            fm.insert(fruit);
      }
      public static void main(String[] args) {
           // TODO 自动生成方法存根
           Test t=new Test();
            t.test1();
      }
 
}
 
hibernate API(一):
Configuration: 读取配置文件信息用来初始化的
SessionFactory: 重量级对象,特点:消耗资源大,线程是安全,所以可以被共享
上面两个对象只实例化一个就行了,都是用于初始化的
Session: 线程是不安全的,所以要避免多个线程共享它,是轻量级的对象,使用后关闭
 
Session对象的状态:
顺态: 还没有被持久化,也就是说数据库中没有该对象的记录,并且Session中的缓冲区里没有这个对象的引用
持久态: 在数据库中有该对象的记录,并且在session中的缓冲区里有这个对象的引用,和顺态正好相反
游离态: 在数据库中有记录,但是不在session的缓冲区里
 
对象状态的转换:
做一个工具类,将hibernate中重复的代码包装起来:
package Yuchen.fristHbn.util;
//生产session对象的工具类
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
 
public class HbnUtil {
      private static SessionFactory sf;
      static{
            sf=new Configuration().configure().buildSessionFactory();
      }
     
      public static Session getSession(){
            return sf.openSession();
      }
}
 
完善FruitManager类:
package Yuchen.fristHbn.business.Biz;
//业务逻辑类:负责增删改查通过使用hibernate API进行
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
 
import Yuchen.fristHbn.business.entity.Fruit;
import Yuchen.fristHbn.util.HbnUtil;
 
public class FruitManager {
      public Integer insert(Fruit fruit){
            Session session=HbnUtil.getSession();//通过工具更方便了
            Integer id=null;
//       Configuration config=new Configuration();
//       config.configure();//读配置文件
//       SessionFactory sf=config.buildSessionFactory();//得到工厂
//       Session session=sf.openSession();//得到session
            Transaction tt=session.beginTransaction();//检查事务开启
            id=(Integer)session.save(fruit);//存储insert
            tt.commit();//提交
            session.close();//关闭资源
            return id;
      }
     
      public Fruit selectId(Integer id){
            Session session=HbnUtil.getSession();
            Transaction t=session.beginTransaction();
           Fruit fruit=(Fruit)session.get(Fruit.class, id);
            t.commit();
            session.close();
            return fruit;
      }
     
      public void remove(Fruit fruit){
            Session session=HbnUtil.getSession();
            Transaction t=session.beginTransaction();
            session.delete(fruit);
            t.commit();
            session.close();
      }
}
 
测试对象状态的转换:
/**
 * 知识点:
 * hibernate基础:练习语法部分API和简单的映射关系
 * 程序目标:
 * 使用hibernate方法将对象进行持久化
 * 实现数据库的增删改查
 * API:
 * 1.Configuration:这个类负责读取XML文档(映射配置文件)
 * configure():读xml
 * buildSessionFactory():创建一个生产session对象的工厂,其实是再次检查
 * 因为hibernate和jdbc不一样,jdbc是如果不手动设置开启事务,那它
 * 就是马上执行sql的,hibernate的不会马上执行,是事务提交后执行
 * 默认情况下就是打开事务的状态,这里只是再检查以下
 * 2.SessionFactory:负责生产session对象
 * openSession():创建一个session
 * 3.Session类:这个是主要的类,负责增删改查,开启事务等
 * beginTransaction():产生一个事务对象(Transaction)
 * save():增加相当于操作sql中的insert语句
 * 4.Transaction类:负责管理事务的
 * commit():提交一个事务
 * test1():测试插入的功能
 * test2():测试数据同步更新的功能
 * test3():测试saveOrUpdate()
 * test4():测试clear()和flush()
 */
package Yuchen.fristHbn.client;
 
import org.hibernate.Session;
import org.hibernate.Transaction;
 
import Yuchen.fristHbn.business.Biz.FruitManager;
import Yuchen.fristHbn.business.entity.Fruit;
import Yuchen.fristHbn.util.HbnUtil;
 
public class Test {
     
      public void test1(){
           Fruit fruit=new Fruit("lisi","hello",100);
//       fruit.setName("zhangsan");
//       fruit.setComments("hello");
//       fruit.setPrice(100);
          
            FruitManager fm=new FruitManager();
            fm.insert(fruit);
      }
     
      public void test2(){
           //测试同步更新的功能
           Fruit fruit=new Fruit("meigui","hongse",70);//顺态
            FruitManager fm=new FruitManager();
           Fruit fruit2=new Fruit();
          
            Integer id=fm.insert(fruit);
            fruit2=fm.selectId(id);
            System.out.println(fruit2.getFid());
            System.out.println(fruit2.getName());
          
            fruit.setName("ziluolan");//这里修改了对象
            fruit2=fm.selectId(id);
            System.out.println(fruit2.getFid());//但是结果没有更新
            System.out.println(fruit2.getName());
           //因为fruit在Integer id=fm.insert(fruit);后变成游离态了
           //也就是说只有持久态才能实现同步更新
            System.out.println(fruit.getFid());
            System.out.println(fruit.getName());
      }
     
      public void test3(){
            Session session=HbnUtil.getSession();
            Transaction t=session.beginTransaction();
           Fruit fruit=new Fruit("ziluolan","lanse",100);//顺态
           Fruit fruit2=new Fruit();
            FruitManager fm=new FruitManager();
            session.save(fruit);//fruit在运行完此句后变为游离态
            fruit2=(Fruit) session.get(Fruit.class, fruit.getFid());
           //从数据库读并打印出来
            System.out.println(fruit2.getFid()+":"+fruit2.getName());
          
            session.saveOrUpdate(fruit);//如果该对象为游历态就更新数据库update
           //否则就是顺态,增加insert
            fruit2=(Fruit) session.get(Fruit.class, fruit.getFid());
            //saveOrUpdate后再从数据库读并打印出来
            System.out.println(fruit2.getFid()+":"+fruit2.getName());
           //两个打印结果一样,saveOrUpdate方法判断如果id为null,就
           //顺态,否则就是游离态
            t.commit();
            session.close();
      }
     
      public void test4(){
            Session session=HbnUtil.getSession();
            Transaction t=session.beginTransaction();
           Fruit fruit=new Fruit("guihua","fense",300);//顺态
           Fruit fruit2=new Fruit();
            session.saveOrUpdate(fruit);//执行insert因为对象为顺态
//       session.flush();
            session.clear();//fruit变成游离态了,并且不会执行insert语句
           //因为hibernate不是马上执行sql,而是等t.commit()提交事务
           //后才执行,clear后,对象为游离态
          
            session.saveOrUpdate(fruit);//这里验证上面的话,执行update
           //做个select查看一下,可以证明,因为clear后,没有马上执行
            //sql语句,所以表里没有数据,这里update也没有用,所以表中
           //一个对象也没插入,但是如果加入flush()刷新就是马上执行sql了
          
            t.commit();
            session.close();
      }
      public static void main(String[] args) {
           // TODO 自动生成方法存根
           Test t=new Test();
      //      t.test1();
      //      t.test2();
      //      t.test3();
           t.test4();     
      }
 
}
 
hibernate API(二):
flush(): 从上面的例子可以看出,flush是刷新session的缓冲区,并执行里面的命令
flush()的事务管理模式: flushMode()里面有三个常量,可以用数字来表示
Load(): 另一种读取数据的方法,和get的区别是: 1.异常处理: load有异常处理,get没有,它返回null,2.get从数据库读数据,load可能去读缓冲区
 
事务的隔离级别:
在hibernate的数据库配置文件中设置
数字1为可以脏读,数字2为不能,这个是最常用的
 
锁机制:
避免并发冲突,在数据库中写数据是自动加锁的,读一般不加,有悲观锁和乐观锁
乐观锁是可以是hibernate程序自己加
实现乐观锁: 引例(hbn2包)
步骤:
1.     在表中加个version字段
2.     在持久类里加个version属性
3.     配置文件<version name=”versopm”> 每存一次值加1
 
引例:hbn2包
 
复杂的映射:
1.     基数关系映射
2.     继承关系映射
3.     组件关系映射
4.     集合映射
 
基数关系的映射—one to one:
基数关系的映射需要考虑的问题:
1.     数量问题
2.     方向问题
在one to one的关系中,我们有两种方法可以体现类与类之间的关系
1.     共享主键
2.     外键唯一
引例: Joto包-此包引用了fristHbn包
 
建立与Fruit类有一对一关系的类:
我们认为一个花有一个产地,一个产地生产一种花,所以要建立产地类
package Yuchen.Joto.business.entity;
//花的地址类
//问题:为什么不能在构造函数中写Fruit?因为生成对象后要持久化
//这个对象,但是数据库的表中不能插入另一个类的值,写上null又不
//大合适,所以就去掉它
public class Address {
      private Integer aid;
      private String nation;
      private String postcode;
      private Fruit fruit;
      public Address() {
          
      }
      public Address(String nation, String postcode) {
            super();
            this.nation = nation;
            this.postcode = postcode;
      }
      public Integer getAid() {
            return aid;
      }
      public void setAid(Integer aid) {
            this.aid = aid;
      }
      public Fruit getFruit() {
            return fruit;
      }
      public void setFruit(Fruit fruit) {
            this.fruit = fruit;
      //      fruit.setAddress(this);
      }
      public String getNation() {
            return nation;
      }
      public void setNation(String nation) {
            this.nation = nation;
      }
      public String getPostcode() {
            return postcode;
      }
      public void setPostcode(String postcode) {
            this.postcode = postcode;
      }
     
}
 
修改Fruit类:
package Yuchen.Joto.business.entity;
//持久化类(花类),注意因为采用的是hilo的方式获得id,所以需要有setid的方法
public class Fruit {
     
      private Integer fid;//hibernate中的id不能识别int
      private String name;
      private String comments;
      private int price;
      private Address address;//一朵花对应一个地址
     
      public Fruit() {
            super();
      }
     
      public Fruit(String name, String comments, int price) {
            super();
            this.name = name;
            this.comments = comments;
            this.price = price;
      }
 
      public Address getAddress() {
            return address;
      }
 
      public void setAddress(Address address) {
            this.address = address;
            address.setFruit(this);//因为当你给一个花设置产地的时候
           //该产地也有了花
      }
 
      public String getComments() {
            return comments;
      }
      public void setComments(String comments) {
            this.comments = comments;
      }
     
      public Integer getFid() {
            return fid;
      }
      public String getName() {
            return name;
      }
      public void setName(String name) {
            this.name = name;
      }
      public int getPrice() {
            return price;
      }
      public void setPrice(int price) {
            this.price = price;
      }
 
      public void setFid(Integer fid) {
            this.fid = fid;
      }
     
}
 
为地址实体类建表:
//oto共享主键方式
create table t_address(
      aid number(10) primary key,
      nation varchar2(30) not null,
      postcode varchar2(10) not null,
      constraint address_fruit foreign key(aid) references T_FRUIT(fid)
);
注意建表的方式不同,所对应的映射文件也有些区别
 
共享主键方式的映射文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="Yuchen.Joto.business.entity">
      <class name="Fruit" table="T_FRUIT">
           <id name="fid" column="fid">
                 <generator class="hilo">
                       <param name="table">t_hilo</param>
                       <param name="column">hilo_id</param>
                 </generator>
            </id>
            <property name="name" column="name" />
            <property name="comments" column="comments"></property>
            <property name="price" column="price"></property>
            <one-to-one name="address" cascade="all" />
      </class>
      <class name="Address" table="t_address">
           <id name="aid" column="aid">
                 <generator class="foreign">
                       <param name="property">fruit</param>
                 </generator>
            </id>
            <property name="nation" column="nation"></property>
            <property name="postcode" column="postcode"></property>
            <one-to-one name="fruit" constrained="true"></one-to-one>
      </class>
</hibernate-mapping>
 
思路:
写类—表,类中的属性—字段,类关系(从数据库的角度出发)
 
外键唯一的方式:建表:
create table t_address(
      aid number(10) primary key,
      nation varchar2(30) not null,
      postcode varchar2(10) not null,
      fid number(10) not null unique,
      constraint address_fruit foreign key(fid) references T_FRUIT(fid)
);
配置文件中修改<one-to-one name="fruit"
constrained="true"></one-to-one>为<many-to-one name="fruit" column="fid" unique="true" cascade="all" />
 
client程序:
/**
 * 知识点:
 * 基数关系映射:one to one
 * 程序目标:
 * 1.写持久类,建立持久类之间的关系
 * 2.定义映射关系,为po建表:两种建表方式
 * 第一种:共享主键
 * 第二种:外键唯一
 * 3.写映射文件
 * 共享主键情况下映射文件的写法:
 * A.主键方:<one-to-one name="引用类型变量名" cascade="all">
 * B.外键方:<one-to-one name="引用类型变量名" constrained="true">
 * 外键唯一情况下映射文件的写法:
 * A.主键方:<one-to-one name="引用类型变量名" cascade="all">
 * B.外键方:<many-to-one name="引用类型变量名" column="fid" unique="true" cascade="all" />
 */
package Yuchen.Joto.client;
 
import org.hibernate.Session;
import org.hibernate.Transaction;
 
import Yuchen.Joto.business.entity.Address;
import Yuchen.Joto.business.entity.Fruit;
import Yuchen.Joto.util.HbnUtil;
 
public class Test {
     
      public void test1(){
            Session session=HbnUtil.getSession();
            Transaction t=session.beginTransaction();
           Fruit fruit=new Fruit("掉蓝","绿色",260);
            Address arddess=new Address("中国","崛起");
            fruit.setAddress(arddess);
            session.save(fruit);
            t.commit();
            session.close();
      }
     
      public static void main(String[] args) {
           // TODO 自动生成方法存根
           Test t=new Test();
            t.test1();
      }
 
}
 
基数关系的映射(one to many):
引例:Jotm包
我们认为一种花有多个产地:
建立花类:
package Yuchen.Jotm.business.entity;
//花类
import java.util.HashSet;
import java.util.Set;
 
public class Fruit {
      private Integer fid;
      private String name;
    private String comments;
   private int price;
    private Set addresses = new HashSet();//一种花有多个产地
      public Fruit() {
            super();
      }
      public Fruit(String name, String comments, int price) {
            super();
            this.name = name;
            this.comments = comments;
            this.price = price;
      }
     
      public void setAddress(Address address) {
            addresses.add(address);
            address.setFruit(this);
      }
      public Set getAddresses() {
            return addresses;
      }
      public void setAddresses(Set addresses) {
            this.addresses = addresses;
      }
      public String getComments() {
            return comments;
      }
      public void setComments(String comments) {
            this.comments = comments;
      }
      public Integer getFid() {
            return fid;
      }
      public void setFid(Integer fid) {
            this.fid = fid;
      }
      public String getName() {
            return name;
      }
      public void setName(String name) {
            this.name = name;
      }
      public int getPrice() {
            return price;
      }
      public void setPrice(int price) {
            this.price = price;
      }
   
}
 
建立产地类:
package Yuchen.Jotm.business.entity;
 
//地址类
public class Address {
         private Integer aid;
         private String nation;
         private String postcode;
         private Fruit fruit;//一个地址对应一种花
      public Address() {
            super();
      }
      public Address(String nation, String postcode) {
            super();
            this.nation = nation;
            this.postcode = postcode;
      }
      public Integer getAid() {
            return aid;
      }
      public void setAid(Integer aid) {
            this.aid = aid;
      }
      public Fruit getFruit() {
            return fruit;
      }
      public void setFruit(Fruit fruit) {
            this.fruit = fruit;
      }
      public String getNation() {
            return nation;
      }
      public void setNation(String nation) {
            this.nation = nation;
      }
      public String getPostcode() {
            return postcode;
      }
      public void setPostcode(String postcode) {
            this.postcode = postcode;
      }
     
}
 
建立数据库表:
Fruit类:
create table T_FRUIT_many2one(
   FID number(10) PRIMARY KEY,
   NAME VARCHAR2(20) NOT NULL,
   COMMENTS VARCHAR2(50),
   PRICE number(5) NOT NULL
);
 
Address类:
这个是多的一方,所以他的外键的值要引用Fruit类的主键值
CREATE TABLE T_ADDRESS_many2one(
   AID number(10) PRIMARY KEY,
   NATION VARCHAR2(30) NOT NULL,
   POSTCODE VARCHAR2(10) NOT NULL,
   AFID number(10) NOT NULL,
   CONSTRAINT ADDRESS_FRUIT_many2one FOREIGN KEY(AFID)
   REFERENCES T_FRUIT_many2one(FID)
);
 
写映射配置文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="Yuchen.Jotm.business.entity">
      <class name="Fruit" table="T_FRUIT_many2one">
           <id name="fid" column="fid">
                 <generator class="hilo">
                       <param name="table">t_hilo</param>
                       <param name="column">hilo_id</param>
                 </generator>
            </id>
            <property name="name" column="name" />
            <property name="comments" column="comments"></property>
          <property name="price" column="price"></property>
          <set name="addresses" inverse="true" cascade="all">
                 <key column="afid"></key>
                 <one-to-many class="Address"></one-to-many>
            </set>
      </class>
      <class name="Address" table="t_address_many2one">
           <id name="aid" column="aid">
                 <generator class="hilo">
                     <param name="table">t_hilo</param>
                       <param name="column">hilo_id</param>
                 </generator>
            </id>
            <property name="nation" column="nation"></property>
          <property name="postcode" column="postcode"></property>
            <many-to-one name="fruit" column="afid" cascade="all"></many-to-one>
      </class>
</hibernate-mapping>
 
client类:
/**
 * 知识点:
 * 基数关系映射:one to many
 * 程序目标:
 * 映射文件的写法:
 * 1.主键方:
 * <set name="引用类型的变量" inverse="true" cascade="all">
 * <key column="外键名">
 * <one-to-many class="外键的类名"></one-to-many>
 * 2.外键方:
 * <many-to-one name="引用类型的变量" column="外键名" cascade="all">
 */
package Yuchen.Jotm.client;
 
import Yuchen.Jotm.business.Biz.FruitManager;
import Yuchen.Jotm.business.entity.Address;
import Yuchen.Jotm.business.entity.Fruit;
 
public class Test {
     
      public static void main(String[] args){
            FruitManager fm=new FruitManager();
            Address address1=new Address("北京","0000");
            Address address2=new Address("上海","000340");
           Fruit fruit=new Fruit("玫瑰","红色",2000);
            fruit.setAddress(address1);
            fruit.setAddress(address2);
            fm.insert(fruit);
      }
}
 
基数关系的映射(many to many):
我们把花和产地看为多对多的关系:
引例:Jmtn包
修改产地类:
package Yuchen.Jmtn.business.entity;
 
import java.util.HashSet;
import java.util.Set;
 
//产地类
public class Address {
         private Integer aid;
         private String nation;
         private String postcode;
         private Set fruits=new HashSet();//一个地址对应一种花
      public Address() {
            super();
      }
      public Address(String nation, String postcode) {
            super();
            this.nation = nation;
            this.postcode = postcode;
      }
     
      public Set getFruits() {
            return fruits;
      }
      public void setFruits(Set fruits) {
            this.fruits = fruits;
      }
      public Integer getAid() {
            return aid;
      }
      public void setAid(Integer aid) {
            this.aid = aid;
      }
      public void setFruit(Fruit fruit) {
            fruits.add(fruit);
      //      fruit.setAddress(this);
      }
      public String getNation() {
            return nation;
      }
      public void setNation(String nation) {
            this.nation = nation;
      }
      public String getPostcode() {
            return postcode;
      }
      public void setPostcode(String postcode) {
            this.postcode = postcode;
      }
     
}
 
 
 
建表:
Fruit类:
create table T_FRUIT_many2many(
   FID number(10) PRIMARY KEY,
   NAME VARCHAR2(20) NOT NULL,
   COMMENTS VARCHAR2(50),
   PRICE number(5) NOT NULL
);
 
Address类:
这个是多的一方,所以他的外键的值要引用Fruit类的主键值
CREATE TABLE T_ADDRESS_many2many(
   AID number(10) PRIMARY KEY,
   NATION VARCHAR2(30) NOT NULL,
   POSTCODE VARCHAR2(10) NOT NULL
);
 
中间表:
CREATE TABLE FRUIT_ADDRESS(
   FID number(10) NOT NULL REFERENCES T_FRUIT_MANY2MANY(FID),
   AID number(10) NOT NULL REFERENCES T_ADDRESS_MANY2MANY(AID),
   PRIMARY KEY(FID,AID)
);
 
映射配置文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="Yuchen.Jmtn.business.entity">
      <class name="Fruit" table="T_FRUIT_many2many">
           <id name="fid" column="fid">
                 <generator class="hilo">
                       <param name="table">t_hilo</param>
                       <param name="column">hilo_id</param>
                 </generator>
            </id>
            <property name="name" column="name" />
            <property name="comments" column="comments"></property>
          <property name="price" column="price"></property>
          <set name="addresses" table="fruit_address" inverse="true" cascade="save-update">
                 <key column="fid"></key>
                 <many-to-many class="Address" column="aid"></many-to-many>
            </set>
      </class>
      <class name="Address" table="t_address_many2many">
           <id name="aid" column="aid">
                 <generator class="hilo">
                     <param name="table">t_hilo</param>
                       <param name="column">hilo_id</param>
                 </generator>
            </id>
            <property name="nation" column="nation"></property>
          <property name="postcode" column="postcode"></property>
           <set name="fruits" table="fruit_address" cascade="save-update">
                 <key column="aid"></key>
                 <many-to-many class="Fruit" column="fid"></many-to-many>
            </set>
      </class>
</hibernate-mapping>
 
cline类:
/**
 * 知识点:
 * 基数关系映射:many to many
 */
package Yuchen.Jmtn.client;
 
import Yuchen.Jmtn.business.Biz.FruitManager;
import Yuchen.Jmtn.business.entity.Address;
import Yuchen.Jmtn.business.entity.Fruit;
 
public class Test {
     
      public static void main(String[] args){
            FruitManager fm=new FruitManager();
            Address address1=new Address("北京","0000");
            Address address2=new Address("上海","000340");
           Fruit fruit=new Fruit("玫瑰","红色",2000);
           Fruit fruit2=new Fruit("紫罗兰","紫色",1000);
            fruit.setAddress(address1);
            fruit.setAddress(address2);
            fruit2.setAddress(address1);
            fm.insert(fruit);
            fm.insert(fruit2);
      }
}
 
继承关系的映射:三个表
发现问题:如何体现继承关系呢?
两种方式:1.共享主键 2.外键唯一
继承中子类有一个supper,也就是有一个父类,但是父类中没有子类,所以是单向的一对一的关系,因此在继承中不考虑数量的问题
优点:和面向对象的概念相似,支持多态
缺点:子类的数据会存放很多,效率也不高,表也多,但是数据没有冗余
 
引例:Extends包
1.     建立工具包类(省略)
2.     建立实体类
付款方式: 现金 银行
package Yuchen.Extends.business.entity;
//父类:付款方式
public abstract class Payment {
      private Integer pid;
      private String reason;//付款原因
      private Double amount;//付款金额
     
      public Payment() {
            super();
      }
 
      public Payment(String reason, Double amount) {
            super();
            this.reason = reason;
            this.amount = amount;
      }
 
      public Double getAmount() {
            return amount;
      }
 
      public void setAmount(Double amount) {
            this.amount = amount;
      }
 
      public Integer getPid() {
            return pid;
      }
 
      public void setPid(Integer pid) {
            this.pid = pid;
      }
 
      public String getReason() {
            return reason;
      }
 
      public void setReason(String reason) {
            this.reason = reason;
      }
     
}
 
package Yuchen.Extends.business.entity;
//银行付款
public class CardPayment extends Payment{
      private Integer pid;
      private String bank;//银行卡
 
     
      public CardPayment() {
            super();
      }
     
 
      public CardPayment(String reason, Double omount, String bank) {
            super(reason,omount);
            this.bank = bank;
      }
 
 
      public Integer getPid() {
            return pid;
      }
 
 
      public void setPid(Integer pid) {
            this.pid = pid;
      }
 
 
      public String getBank() {
            return bank;
      }
 
      public void setBank(String bank) {
            this.bank = bank;
      }
     
     
}
 
package Yuchen.Extends.business.entity;
//现金
public class CashPayment extends Payment{
      private Integer pid;
      private String cash;//货币类型
      public CashPayment(){
          
      }
      public CashPayment(String reason,double amount, String cash) {
            super(reason,amount);
            this.cash = cash;
      }
      public String getCash() {
            return cash;
      }
      public void setCash(String cash) {
            this.cash = cash;
      }
      public Integer getPid() {
            return pid;
      }
      public void setPid(Integer pid) {
            this.pid = pid;
      }
     
}
 
建表:
1.Payment
create table t_payment (
      pid number(10) primary key,
      reason varchar2(30) not null,
      amount number(30) not null
);
 
2.CardPayment
//共享主键
create table t_cardpayment(
      pid number(10) primary key references t_payment(pid),
      bank varchar2(30) not null
);
 
3.CashPayment
//共享主键
create table t_cashpayment(
      pid number(10) primary key references t_payment(pid),
      cash varchar2(30) not null
);
 
写配置文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="Yuchen.Extends.business.entity">
<class name="Payment" table="t_payment">
      <id name="pid" column="pid">
            <generator class="hilo">
                 <param name="table">t_hilo</param>
                 <param name="column">hilo_id</param>
            </generator>
      </id>
      <property name="reason"></property>
      <property name="amount"></property>
      <joined-subclass name="CardPayment" table="t_cardpayment">
           <key column="pid"></key>
            <property name="bank"></property>
      </joined-subclass>
      <joined-subclass name="CashPayment" table="t_cashpayment">
           <key column="pid"></key>
            <property name="cash"></property>
      </joined-subclass>
</class>
</hibernate-mapping>
client:
/**
 * 知识点:
 * 继承关系映射
 * test1():三个表
 */
package Yuchen.Extends.client;
 
import org.hibernate.Session;
import org.hibernate.Transaction;
 
import Yuchen.Extends.business.entity.CardPayment;
import Yuchen.Extends.util.HbnUtil;
 
public class Test {
     
      public static void test1(){
            Session session=HbnUtil.getSession();
            Transaction t=session.beginTransaction();
            CardPayment card=new CardPayment("买杂志",100.0,"人民币");
            session.save(card);
            t.commit();
            session.close();
      }
      public static void main(String[] args) {
           // TODO 自动生成方法存根
            Test.test1();
      }
 
}
 
继承关系的映射:两个表
一个子类一个表,父类不建表,但是每个子类需要加入父类的属性
缺点:不支持多态的查询,特点不明显,用的很少
 
建表:
两个表:
1.CardPayment
create table t_cardpayment_concrete(
    pid integer(10) primary key,
    reason varchar(30) not null,
    amount double not null,
    bank varchar(10) not null
 
);
 
 
2.CashPayment
create table t_cashpayment_concrete(
    pid integer(10) primary key,
    reason varchar(30) not null,
    amount double not null,
    cash varchar(10) not null
);
修改配置文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="Yuchen.Extends.business.entity">
      <class name="Payment">
           <id name="pid" column="pid">
                 <generator class="hilo">
                       <param name="table">t_hilo</param>
                       <param name="column">hilo_id</param>
                 </generator>
         </id>
            <property name="reason"></property>
            <property name="amount"></property>
            <union-subclass name="CardPayment" table="t_cardpayment_concrete">
            <property name="bank"></property>
            </union-subclass>
            <union-subclass name="CashPayment" table="t_cashpayment_concrete">
            <property name="cash"></property>
      </union-subclass>
      </class>
</hibernate-mapping>
 
继承关系的映射:一个表
优点:1.生成报表快 2.易于实现 3.支持多态
缺点:修改和维护比较麻烦
如果类中的属性太多用这个方法就不大合适了
建表:
一个表:
create table t_payment_hierarchy(
 pid number(10) primary key,
 reason varchar2(30) not null,
 amount number not null,
 cash varchar2(10) not null,
 bank varchar2(10) not null,
 type varchar2(10) not null
);
 
修改配置文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="Yuchen.Extends.business.entity">
<class name="Payment" table="t_payment_hierarchy">
      <id name="pid" column="pid">
                 <generator class="hilo">
                       <param name="table">t_hilo</param>
                       <param name="column">hilo_id</param>
                 </generator>
   </id>
      <discriminator column="type"></discriminator>
      <property name="reason"></property>
      <property name="amount"></property>
      <subclass name="CardPayment" discriminator-value="card">
            <property name="bank"></property>
      </subclass>
      <subclass name="CashPayment" discriminator-value="cash">
            <property name="cash"></property>
      </subclass>
</class>
</hibernate-mapping>
 
组件映射 and Query:
什么是组件映射?
我们知道在类的关联关系中有一种关系叫组合关系,什么是组合关系呢?就是不能独立存在的类,我们以前在映射这种关系的时候在一对一的情况下使用的是one to one的映射方法,这种方法比较复杂,那么我们可以使用组件映射的方法使得映射更简单
语法:
1.     被包含的对象没有oid,组件类不能看做po
2.     组件类不映射一个表
作用:只有一个表,没有1to1的关系, 使得映射更简单
引例:
银行帐户,有两个类,一个是帐户基本信息类,另一个是帐户人详细地址类
建立实体类:
地址类属于值对象,帐户类属于实体对象,两者之间是组合关系
package Yuchen.component.business.entity;
//帐号信息类
public class Account{
      private Integer aid;
      private String name;
      private Address address;//地址
      public Account() {
            super();
      }
      public Account(String name, Address address) {
            super();
            this.name = name;
            this.address = address;
      }
      public Address getAddress() {
            return address;
      }
      public void setAddress(Address address) {
            this.address = address;
      }
      public Integer getAid() {
            return aid;
      }
      public void setAid(Integer aid) {
            this.aid = aid;
      }
      public String getName() {
            return name;
      }
      public void setName(String name) {
            this.name = name;
      }
     
}
 
package Yuchen.component.business.entity;
//详细地址类:注意不需要id,因为要和Account建一个表里
public class Address{
      private String street;//街道
      private String city;//城市
      private String zipcode;//邮编
      public Address() {
            super();
      }
      public Address(String street, String city, String zipcode) {
            super();
            this.street = street;
            this.city = city;
            this.zipcode = zipcode;
      }
      public String getCity() {
            return city;
      }
      public void setCity(String city) {
            this.city = city;
      }
      public String getStreet() {
            return street;
      }
      public void setStreet(String street) {
            this.street = street;
      }
      public String getZipcode() {
            return zipcode;
      }
      public void setZipcode(String zipcode) {
            this.zipcode = zipcode;
      }
     
}
 
建表:
create table t_component(
      aid number(10) primary key,
      name varchar2(30) not null,
      street varchar(30) not null,
      city varchar(30) not null,
      zipcode varchar(30) not null
);
 
映射文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="Yuchen.component.business.entity">
      <class name="Account" table="t_component">
           <id name="aid" column="aid">
                 <generator class="hilo">
                       <param name="table">t_hilo</param>
                       <param name="column">hilo_id</param>
                 </generator>
            </id>
            <property name="name" />
            <component name="address">
                 <property name="street" />
                 <property name="city" />
                 <property name="zipcode" />
            </component>
      </class>
</hibernate-mapping>
 
client:
/**
 * 知识点:
 * 组件映射
 */
package Yuchen.component.client;
 
import org.hibernate.Session;
import org.hibernate.Transaction;
 
import Yuchen.component.business.entity.Account;
import Yuchen.component.business.entity.Address;
import Yuchen.component.util.HbnUtil;
 
public class Test{
      public static void test(){
            Session session=HbnUtil.getSession();
            Transaction t=session.beginTransaction();
            Address address=new Address("湖南路","上海","010000");
            Account account=new Account("lisi",address);
            session.save(account);
            t.commit();
            session.close();
      }
      public static void main(String[] args){
            Test.test();
      }
}
 
Query:
/**
 * 知识点:
 * 组件映射,Query查询
 * test1():组件映射
 * test2():1.条件查询 2.from Object 3.uniqueResult()
 * test3():复杂的条件查询(支持like等)
 * test4():加参数的查询
 * test5():使用select:1.查询一个类中引用类型的属性值
 *                               2.查询一个类中引用类型的对象
 * test6(): 查看两个对象的属性(对象数组太麻烦)
 * test7(): 使用中间对象查看两个对象的属性
 *            1.建一个中间对象类
 *            2.写select HQL语句调用API
 * test8():命名查询
 *            1.修改配置文件
 *            2.执行API
 * API:
 * uniqueResult():返回唯一的对象
 * getNameQuery():得到变量名所指定的sql语句
 */
package Yuchen.component.client;
 
import java.util.Iterator;
import java.util.List;
 
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
 
import Yuchen.component.business.entity.Account;
import Yuchen.component.business.entity.AccountAddress;
import Yuchen.component.business.entity.Address;
import Yuchen.component.util.HbnUtil;
 
public class Test{
      public static void test(){
            Session session=HbnUtil.getSession();
            Transaction t=session.beginTransaction();
            Address address=new Address("湖南路","上海","010000");
            Account account=new Account("lisi",address);
            session.save(account);
            t.commit();
            session.close();
      }
      public static void test2()
      {
            Session session=HbnUtil.getSession();
            Transaction t=session.beginTransaction();
//       Query q=session.createQuery("from Account where name='lisi'");
            Query q=session.createQuery("from java.lang.Object");
           List list=q.list();
            Account account=(Account) list.get(1);
//       Account account=(Account) q.uniqueResult();
            System.out.println(account.getName());
            t.commit();
            session.close();
      }
     
      public static void test3(){
            Session session=HbnUtil.getSession();
            Transaction t=session.beginTransaction();
            Query q=session.createQuery("from Account a where a.name like '%si'");
            Account account=(Account) q.uniqueResult();
            System.out.println(account.getName());
            t.commit();
            session.close();
      }
      public static void test4(){
            Session session=HbnUtil.getSession();
            Transaction t=session.beginTransaction();
            Query q=session.createQuery("from Account a where a.name like :x");
            q.setString("x", "%si");
            Account account=(Account) q.uniqueResult();
            System.out.println(account.getName());
            t.commit();
            session.close();
      }
     
      public static void test5(){
            Session session=HbnUtil.getSession();
            Transaction t=session.beginTransaction();
//       Query q=session.createQuery("select a.address.city from Account a where a.name='lisi'");
            Query q=session.createQuery("select a.address from Account a where a.name='lisi'");
            Address address=(Address) q.uniqueResult();
            System.out.println(address.getCity());
//       String city=(String) q.uniqueResult();
//       System.out.println(city);
            t.commit();
            session.close();
      }
     
      public static void test6(){
            Session session=HbnUtil.getSession();
            Transaction t=session.beginTransaction();
            Query q=session.createQuery("select a.name,a.address from Account a");
           List list=q.list();
            Object[] obj=(Object[]) list.get(0);//第一条(name,address组成的对象数组)
//       Object[] obj2=(Object[]) list.get(1);//第二条
            System.out.println(obj[0]);
            System.out.println(((Address)obj[1]).getCity());
            t.commit();
            session.close();
      }
      public static void test7(){
            Session session=HbnUtil.getSession();
            Transaction t=session.beginTransaction();
            Query q=session.createQuery("select new Yuchen.component.business.entity.AccountAddress(a.name,a.address.zipcode) from Account a");
           List list=q.list();
            Iterator it=list.iterator();
            while(it.hasNext()){
                 AccountAddress aa=(AccountAddress) it.next();
                 System.out.println(aa.getName());
                 System.out.println(aa.getZipcode());
           }
            t.commit();
            session.close();
      }
      public static void test8(){
            Session session=HbnUtil.getSession();
            Transaction t=session.beginTransaction();
            Query query=session.getNamedQuery("mingming");
            query.setString("name","%si");
            Account aa=(Account) query.uniqueResult();
            System.out.println(aa.getName());
            t.commit();
            session.close();
      }
      public static void main(String[] args){
            Test.test8();
      }
}
 
修改配置文件:
在class后加入:
<query name="mingming"><![CDATA[from Account a where a.name like :name]]></query>
 


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yuchen2008/archive/2007/02/17/1511291.aspx

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 、5资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值