本实例使用用户和订单的例子做说明: 一个用户可以有多个订单, 一个订单只对应一个用户。(其中应用到注释)
1.代码的结构
2. 建表语句:
CREATE DATABASE test; USE test; CREATE TABLE person( personId VARCHAR(36) PRIMARY KEY, personName VARCHAR(64), personAddress VARCHAR(128), personTel VARCHAR(11) ); CREATE TABLE orders( orderId VARCHAR(36) PRIMARY KEY, orderNumber VARCHAR(20), orderPrice INT, pid VARCHAR(36) ); INSERT INTO person VALUES('1', '木子', '湖北', '110'); INSERT INTO person VALUES('2', '木子大大', '武汉', '120'); INSERT INTO person VALUES('1', '木子苗苗', '天门', '119'); INSERT INTO orders VALUES('1', '001', 100, '1'); INSERT INTO orders VALUES('2', '002', 200, '1'); INSERT INTO orders VALUES('3', '003', 300, '2'); INSERT INTO orders VALUES('4', '004', 400, '2'); INSERT INTO orders VALUES('5', '005', 500, '3'); SELECT p.*, o.* FROM person p JOIN orders o ON (p.personId=o.pid) WHERE p.personId = '1' ; *指显示所有字段
3. 用户实体:
package com.mybatis.domain; import java.util.List; import lombok.Data; @Data//注释(Person为单方) public class Person { private String personid; private String personname; private String personaddress; private String persontel; //这个代表多方里面的内容(Orders) private List<Orders> orders; @Override public String toString() { return "Person [personid=" + personid + ", personname=" + personname + ", personaddress=" + personaddress + ", persontel=" + persontel + ", orders=" + orders + "]"; } }
4. 订单实体:
package com.mybatis.domain; import lombok.Data; @Data//(Orders为多方) public class Orders { private String orderid; private String ordernumber; private Integer orderprice; //对象(单方Person)与外键进行关联 private Person person; }
5.写PersonMapper.java的接口
package com.mybatis.dao.mapper; import com.mybatis.domain.Orders; import com.mybatis.domain.Person; import java.util.List; public interface PersonMapper { int deleteByPrimaryKey(String personid); int insert(Person record); Person selectByPrimaryKey(String personid); List<Person> selectAll(); int updateByPrimaryKey(Person record); //一对多查询(根据id查询) public List<Orders> findPersonAndOrders(String pid); //一对多查询返回一个对象 public Person selectPersonById(String id); }
6. 一对多实体配置: PersonMapper.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.mybatis.dao.mapper.PersonMapper" > <resultMap id="PersonResultMap" type="com.mybatis.domain.Person" > <id column="personId" property="personid" jdbcType="VARCHAR" /> <result column="personName" property="personname" jdbcType="VARCHAR" /> <result column="personAddress" property="personaddress" jdbcType="VARCHAR" /> <result column="personTel" property="persontel" jdbcType="VARCHAR" /> <!-- 一对多的关系(这个是关联集合)这个是Orders里面的多方 --> <!-- property: 指的是集合属性的名, ofType:指的是集合中元素的类型的路径 (实现类)--> <collection property="orders" ofType="com.mybatis.domain.Orders"> <!-- id有一个单独标签 --> <id column="orderId" property="orderid"/> <!--column指sql中字段的名字 property指java中对应sql中属性的名 --> <result column="orderNumber" property="ordernumber"/> <result column="orderPrice" property="orderprice"/> </collection> </resultMap> <!-- 根据id查询Person, 关联将Orders查询出来(注意放置的位置) --> <select id="findPersonAndOrders" parameterType="String" resultMap="PersonResultMap"> SELECT p.*,o.* FROM person o,orders b WHERE o.personid=#{pid}; </select> <select id="selectPersonById" parameterType="string" resultMap="PersonResultMap"> select p.*, o.* from person p, orders o where p.personId = o.pid and p.personId = #{id} </select> </mapper>
7.写OrdersMapper.java的接口
package com.mybatis.dao.mapper; import com.mybatis.domain.Orders; import java.util.List; public interface OrdersMapper { int deleteByPrimaryKey(String orderid); int insert(Orders record); Orders selectByPrimaryKey(String orderid); List<Orders> selectAll(); int updateByPrimaryKey(Orders record); //多查一 根据id public Orders selectOrderById(String oid); //多查一 根据orderNumber public Orders selectOrderNumber(String number); }
8.多对一实体配置:OrdersMapper.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.mybatis.dao.mapper.OrdersMapper" > <resultMap id="OrdersResultMap" type="com.mybatis.domain.Orders" > <id column="orderId" property="orderid" jdbcType="VARCHAR" /> <result column="orderNumber" property="ordernumber" jdbcType="VARCHAR" /> <result column="orderPrice" property="orderprice" jdbcType="INTEGER" /> <!-- <result column="pid" property="pid" jdbcType="VARCHAR" /> --> <!-- 多对一的关系 这个是Person里面的单方 --> <!-- property: 指的是属性的值, javaType:指的是属性的类型的路径 (实现类)--> <association property="person" javaType="com.mybatis.domain.Person"> <!--注意:在此column和property的值要一样都为Person的属性 --> <id column="personid" property="personid"/> <result column="personname" property="personname"/> <result column="personaddress" property="personaddress"/> <result column="persontel" property="persontel"/> </association> </resultMap> <!-- 根据id查询Order, 关联将Person查询出来 --> <select id="selectOrderById" parameterType="string" resultMap="OrdersResultMap"> select p.*, o.* from person p, orders o where p.personId = o.pid and o.orderId = #{oid} </select> <!-- 根据orderNumber查询Order, 关联将Person查询出来 --> <select id="selectOrderNumber" parameterType="string" resultMap="OrdersResultMap"> select p.*, o.* from person p, orders o where p.personId = o.pid and o.orderId = #{number} </select> </mapper>
9.其他配置
db.properties配置(sql语句的基本链接) db.driver=com.mysql.jdbc.Driver db.url=jdbc:mysql://localhost:3306/wang1?useUnicode=true&characterEncoding=utf8 db.username=root db.password=123456 log4j.properties配置(注释) # Global logging configuration log4j.rootLogger=DEBUG, stdout # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n mybatis.xml(逆向生成domain、dao层) <?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> <!-- mybatis核心配置文件 --> <!-- 加载java的配置文件或者声明属性信息 --> <properties resource="db.properties"> </properties> <!-- alias别名 --> <typeAliases> <!--这里需要修改 domain层的路径--> <typeAlias type="com.mybatis.domain.Person" alias="person" /> <typeAlias type="com.mybatis.domain.Orders" alias="orders" /> </typeAliases> <!-- 配置mybatis的环境信息,与spring整合,该信息由spring来管理 如果说我们需要连接数据库,那么必须在mybatis中配置环境 运行环境 --> <environments default="development"> <environment id="development"> <!-- 配置JDBC事务控制,由mybatis进行管理 --> <transactionManager type="JDBC"></transactionManager> <!-- 配置数据源,采用mybatis连接池 --> <dataSource type="POOLED"> <property name="driver" value="${db.driver}" /> <property name="url" value="${db.url}" /> <property name="username" value="${db.username}" /> <property name="password" value="${db.password}" /> </dataSource> </environment> </environments> <!-- 加载映射文件(注意反\)--> <mappers> <!--这里需要修改 dao层的路径--> <mapper resource="com\mybatis\dao\mapper\PersonMapper.xml"/> <mapper resource="com\mybatis\dao\mapper\OrdersMapper.xml"/> </mappers> </configuration> generatorConfig.xml配置(对MySQL进行操作)下面标红部分根据自己建立的进行修改 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <!-- 配置生成器 --> <generatorConfiguration> D盘中要有此包mysql-connector-java-5.1.7-bin.jar <classPathEntry location="D:\mysql-connector-java-5.1.7-bin.jar" /> <context id="mysql" defaultModelType="hierarchical" targetRuntime="MyBatis3Simple"> <!-- 自动识别数据库关键字,默认false,如果设置为true,根据SqlReservedWords中定义的关键字列表; 一般保留默认值,遇到数据库关键字(Java关键字),使用columnOverride覆盖 --> <property name="autoDelimitKeywords" value="false" /> <!-- 生成的Java文件的编码 --> <property name="javaFileEncoding" value="UTF-8" /> <!-- beginningDelimiter和endingDelimiter:指明数据库的用于标记数据库对象名的符号,比如ORACLE就是双引号,MYSQL默认是`反引号; --> <property name="beginningDelimiter" value="`" /> <property name="endingDelimiter" value="`" /> <!-- 注释生成器 --> <commentGenerator> <property name="suppressDate" value="true"/> <property name="suppressAllComments" value="true" /> </commentGenerator> <!-- 必须要有的,使用这个配置链接数据库 @TODO:是否可以扩展 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/wang1" userId="root" password="123456"> <!-- 这里面可以设置property属性,每一个property属性都设置到配置的Driver上 --> </jdbcConnection> <!-- java模型创建器,是必须要的元素 负责:1,key类(见context的defaultModelType);2,java类;3,查询类 targetPackage:生成的类要放的包,真实的包受enableSubPackages属性控制; targetProject:目标项目,指定一个存在的目录下,生成的内容会放到指定目录中,如果目录不存在,MBG不会自动建目录 --> <javaModelGenerator targetPackage="com.mybatis.domain" targetProject="mybatis03/src"> <!-- for MyBatis3/MyBatis3Simple 自动为每一个生成的类创建一个构造方法,构造方法包含了所有的field;而不是使用setter; --> <property name="constructorBased" value="false" /> <!-- for MyBatis3 / MyBatis3Simple 是否创建一个不可变的类,如果为true, 那么MBG会创建一个没有setter方法的类, 取而代之的是类似constructorBased的类 --> <property name="immutable" value="false" /> </javaModelGenerator> <!-- 生成SQL map的XML文件生成器, 注意,在Mybatis3之后,我们可以使用mapper.xml文件+Mapper接口(或者不用mapper接口), 或者只使用Mapper接口+Annotation,所以,如果 javaClientGenerator配置中配置了需要生成XML的话,这个元素就必须配置 targetPackage/targetProject:同javaModelGenerator --> <sqlMapGenerator targetPackage="com.mybatis.dao.mapper" targetProject="mybatis03/src"> <!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false --> <property name="enableSubPackages" value="true" /> </sqlMapGenerator> <!-- 对于mybatis来说,即生成Mapper接口,注意,如果没有配置该元素,那么默认不会生成Mapper接口 targetPackage/targetProject:同javaModelGenerator type:选择怎么生成mapper接口(在MyBatis3/MyBatis3Simple下): 1,ANNOTATEDMAPPER:会生成使用Mapper接口+Annotation的方式创建(SQL生成在annotation中),不会生成对应的XML; 2,MIXEDMAPPER:使用混合配置,会生成Mapper接口,并适当添加合适的Annotation,但是XML会生成在XML中; 3,XMLMAPPER:会生成Mapper接口,接口完全依赖XML; 注意,如果context是MyBatis3Simple:只支持ANNOTATEDMAPPER和XMLMAPPER --> <javaClientGenerator targetPackage="com.mybatis.dao.mapper" type="XMLMAPPER" targetProject="mybatis03/src"> <!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false --> <property name="enableSubPackages" value="true" /> <!-- 可以为所有生成的接口添加一个父接口,但是MBG只负责生成,不负责检查 <property name="rootInterface" value=""/> --> </javaClientGenerator> <!--逆向生成的文件--> <table tableName="person" delimitIdentifiers="true"> <!-- 参考 javaModelGenerator 的 constructorBased属性 --> <property name="constructorBased" value="false" /> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="orders" delimitIdentifiers="true"> <!-- 参考 javaModelGenerator 的 constructorBased属性 --> <property name="constructorBased" value="false" /> <generatedKey column="id" sqlStatement="JDBC"/> </table> </context> </generatorConfiguration>
10.测试文件
package com.mybatis.test; import java.io.InputStream; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.List; import lombok.Data; 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 org.junit.Before; import org.junit.Test; import com.mybatis.dao.mapper.OrdersMapper; import com.mybatis.dao.mapper.PersonMapper; import com.mybatis.domain.Orders; import com.mybatis.domain.Person; public class TestStudentMapper { SqlSessionFactory sessionFactory = null; // 这方法之前 @Before public void setup() throws Exception { String resource = "mybatis.xml"; // 这个是加载配置文件 InputStream inputStream = Resources.getResourceAsStream(resource); // 得到会话工厂 sessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } //查询一对多 根据这个person里面的id号就能查询出这个用户有多少个订单记录 // @Test public void testSelectPersonById(){ SqlSession sq = sessionFactory.openSession(); // 得到dao层的实现类 PersonMapper u = sq.getMapper(PersonMapper.class); Person person = u.selectPersonById("2"); System.out.println(person); } //多对一 根据多对一id进行查询 // @Test//多对一关联查询 public void testSelectOrderById(){ SqlSession sq = sessionFactory.openSession(); // 得到dao层的实现类 OrdersMapper u = sq.getMapper(OrdersMapper.class); Orders od = u.selectOrderById( "2"); System.out.println(od.getPerson().getPersonname()); System.out.println(od.getPerson().getPersonaddress()); } @Test//多对一关联查询 public void testSelectOrderNumber(){ SqlSession sq = sessionFactory.openSession(); // 得到dao层的实现类 OrdersMapper u = sq.getMapper(OrdersMapper.class); Orders od = u.selectOrderNumber("001"); System.out.println(od.getPerson().getPersonname()); System.out.println(od.getPerson().getPersonaddress()); } }
如有问题请多多指教!希望给您带来帮助!祝您生活愉快。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对小牛知识库的支持。如果你想了解更多相关内容请查看下面相关链接
本文向大家介绍MyBatis中多对多关系的映射和查询,包括了MyBatis中多对多关系的映射和查询的使用技巧和注意事项,需要的朋友参考一下 先说一下需求: 在页面上显示数据库中的所有图书,显示图书的同时,显示出该图书所属的类别(这里一本书可能同时属于多个类别) 创建表: 笔者这里使用中间表连接图书表和图书类别表,图书表中没有使用外键关联图书类别表 而是在中间表中引用了图书主键和类别主键 通
问题内容: 在我的elasticsearch服务器中,我只有一个索引。 (博客)索引包含多种类型。 如:,。 在标签类型中,我创建了1000多个标签,并在帖子类型中创建了10个帖子。 例如:帖子 例如:标签 我想将现有标签分配给博客帖子(即,关系=>映射)。 如何将标签分配给帖子映射? 问题答案: 您可以在Elasticsearch中使用4种方法来管理关系。在Elasticsearch博客文章-E
这是项目迁移 这是时间表 这样用户就可以迁移了 这是我的项目模型 这是我的时间表模型: 这是我的用户模型 现在,我从项目返回我的查询 这是可以的,但user_id用户在timesheets.user_id我不能得到它的时间表,并得到它 此控制器按时间表中的项目id返回项目和时间表,但时间表中的用户id我不知道如何将其输入系统
如果在中只有一组,这将非常好地工作。ASSESSMENT_COMMENT只有两列: 它将完美地代表一对多的关系。 现在问题来了: 那么,1)这是Hibernate中已知的bug吗?2)有办法解决这个问题吗?我可以强制Hibernate创建两个映射表,每个映射表一个吗?请记住,我不能更改类来引用(业务逻辑需求)
问题内容: 一对多和多对一关系的真正区别是什么?它只是颠倒的,是什么样的? 除了本主题之外,我找不到关于此主题的任何“易懂”教程:初学者使用的SQL:第3部分- 数据库关系 问题答案: 是的,反之亦然。它取决于实体存在于关系的哪一侧。 例如,如果一个部门可以雇用多名员工,则部门与员工之间是一对多的关系(1个部门雇用许多员工),而员工与部门之间的关系则是多对一的关系(许多员工在一个部门中工作)。 有
有两张数据表,其中A表的某个字段的值指向B表的主键。因为B表的任何一条记录理论上可以对应A表的多条记录,所以称这种 映射为B表对A表数据的一对多映射。 上述结构,如果用 POJO 来表示的话,可以参看下图: 如上图,一个 Master 自然就能对应多个 Pet ,所以, Master.pets (一个 List<Pet>) 就可以指向多个 Pet 对象, 那么我们说 Master.pets 就是