一、配置环境:
首先我们需要Maven环境;
源码:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>sanzhongfangfa24_7_23</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--MySQL框架--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!--日志框架--><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency><!--MyBatis的框架--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.5</version></dependency><!--Java 单元测试框架用来@Test--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><!--用来指定上面的依赖进行测试两个缺一不可--><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>RELEASE</version><scope>compile</scope></dependency></dependencies></project>
其次我们要配置核心配置文件;
这个文件是我们整个功能的基础;
源码:
<?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 >
<!-- 这是转Data类型的调用--><typeHandlers><typeHandler handler="org.handle.DateTypeHandler"></typeHandler></typeHandlers><environments default="develop"><environment id="develop"><transactionManager type="JDBC"></transactionManager><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/duobiaochaxun?characterEncoding=utf-8"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><mappers><mapper resource="mapper/duoduiduoMapper.xml"/>
<!-- <mapper resource="mapper/oneduiduoMapper.xml"/>-->
<!-- 必须配套写完不然报错 <mapper resource="mapper/UserMapper.xml"/>--></mappers>
</configuration>
第三我们要写日志的配置文件:
日志源码:
#日志
log4j.rootLogger=debug, stdout,R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's file name and line number.
Log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log
Log4j.appender.R.MaxFileSize=100KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=5
log4j.appender.R.layout=org.apache.log4j.PatternLayout
Log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
第四我们写数据库和Java对象类型的转化:
package org.handle;import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;public class DateTypeHandler extends BaseTypeHandler<Date> {// 将java类型转换成数据库需要的类型@Override//这段代码是 MyBatis 中的一个自定义类型处理器 (TypeHandler) 的一部分,它负责将Date对象转换为可以存储在数据库中的形式。//具体来说,这个方法将 Date 对象转换为长整型 (long) 值,代表从 1970 年 1 月 1 日 00:00:00 UTC 开始到给定日期的毫秒数。public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {//将日期赋值给long形的timelong time = date.getTime();// PreparedStatement 的 setLong 方法将 time 设置到预编译 SQL 语句的第 i 个参数位置//这意味着日期将作为长整型值被存储在数据库中。preparedStatement.setLong(i, time);}// 将数据库中的类型 转换为java类型// string 要转换的字符串
// resultSet 查询出的结果@Override// 将数据库查询结果中的长整型值转换为 java.util.Date 对象。public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {// 这一行代码调用了 ResultSet 的 getLong 方法,根据列名 s 获取长整型值。long along = resultSet.getLong(s);//这一行代码使用从 ResultSet 中获取的长整型值创建一个新的 java.util.Date 对象。Date date = new Date(along);return date;}// 将数据库中的类型 转换为java类型@Overridepublic Date getNullableResult(ResultSet resultSet, int i) throws SQLException {long along = resultSet.getLong(i);Date date = new Date(along);return date;}// 将数据库中的类型 转换为java类型@Override
//用于将从 CallableStatement 中获取的长整型值转换为 java.util.Date 对象//这是一个 CallableStatement 对象,用于执行 SQL 存储过程或函数,并获取其结果。public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {long aLong = callableStatement.getLong(i);Date date = new Date(aLong);return date;}
}
这样我们就能将数据库和Java类型的的数据互相转化,别忘了将 该完成的类添加到核心配置文件里;
做完上述的环境配置,我们就要开始写项目和功能 。
二、写数据:
我们要写我们需要的Javabean数据,这个按照数据库来写,这里只展示功能,下面是我的例子。
数据库的表:
orders(订单表):
user(用户表):
Javabean的数据:
订单表:
package org.Emp;import java.util.Date;
import java.util.List;public class order {private Integer id;private Date ordertime;private Double total;private Integer uuid;private user user;public order() {}public order(Integer id, Date ordertime, Double total, Integer uuid, user user) {this.id = id;this.ordertime = ordertime;this.total = total;this.uuid = uuid;this.user = user;}/*** 获取* @return id*/public Integer getId() {return id;}/*** 设置* @param id*/public void setId(Integer id) {this.id = id;}/*** 获取* @return ordertime*/public Date getOrdertime() {return ordertime;}/*** 设置* @param ordertime*/public void setOrdertime(Date ordertime) {this.ordertime = ordertime;}/*** 获取* @return total*/public Double getTotal() {return total;}/*** 设置* @param total*/public void setTotal(Double total) {this.total = total;}/*** 获取* @return uuid*/public Integer getUuid() {return uuid;}/*** 设置* @param uuid*/public void setUuid(Integer uuid) {this.uuid = uuid;}/*** 获取* @return user*/public user getUser() {return user;}/*** 设置* @param user*/public void setUser(user user) {this.user = user;}public String toString() {return "order{id = " + id + ", ordertime = " + ordertime + ", total = " + total + ", uuid = " + uuid + ", user = " + user + "}";}
}
用户表:
package org.Emp;import java.util.Date;
import java.util.List;
public class user {
private Integer id;
private String username;
private String password;
private Date birthday;public user() {}public user(Integer id, String username, String password, Date birthday) {this.id = id;this.username = username;this.password = password;this.birthday = birthday;}/*** 获取* @return id*/public Integer getId() {return id;}/*** 设置* @param id*/public void setId(Integer id) {this.id = id;}/*** 获取* @return username*/public String getUsername() {return username;}/*** 设置* @param username*/public void setUsername(String username) {this.username = username;}/*** 获取* @return password*/public String getPassword() {return password;}/*** 设置* @param password*/public void setPassword(String password) {this.password = password;}/*** 获取* @return birthday*/public Date getBirthday() {return birthday;}/*** 设置* @param birthday*/public void setBirthday(Date birthday) {this.birthday = birthday;}public String toString() {return "user{id = " + id + ", username = " + username + ", password = " + password + ", birthday = " + birthday + "}";}// private List<role> role;//private List<order> order;}
底层数据建成完毕,我们就要开始着手写功能;
三、写功能:
1、一对一查询
修改底层Javabean:
因为我们有两张表要查,要输出,但是Java输出形式只能是一张表,所以我们要用注入的方式,将用户表注入到订单表里,这样只用输出订单格式就可以了。
写Mapper映射(核心):
我们要创建一个.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">
<!--这一行定义了这个映射文件的命名空间,org.dao.oneselMapper 是一个唯一的标识符,用来区分不同的映射文件-->
<mapper namespace="org.dao.oneselMapper">
<!--这个 <resultMap> 元素定义了一个名为 orderMap 的映射规则,它会把查询结果映射到 org.Emp.order类型的对象上。-->
<!--也就是将数据库的值映射到Javabean中--><resultMap id="orderMap" type="org.Emp.order">
<!--id映射-->
<!--这一行指定了数据库中的 id 列与 JavaBean 中的 id 属性相对应。--><id column="id" property="id"></id>
<!--普通属性映射,这些 <result> 标签分别指定了数据库中的 ordertime, total, 和 uuid 列与 JavaBean 中对应的属性相对应。--><result column="ordertime" property="ordertime"></result><result column="total" property="total"></result><result column="uuid" property="uuid"></result>
<!--关联映射 (Association):-->
<!--这部分定义了一个一对一关联映射,表示 org.Emp.order 类中的 user 属性应该如何从数据库结果中获取其属性值。
这里,<association> 标签内的 <id> 和 <result> 标签指定了 user 表中的列名与 org.Emp.user 类中的属性名之间的对应关系。--><association property="user" javaType="org.Emp.user"><id column="uuid" property="id"></id><result column="username" property="username"></result><result column="password" property="password"></result><result column="birthday" property="birthday"></result></association></resultMap><!--数据库的一对一查询-->
<!--SQL 查询定义:-->
<!--这个 <select> 标签定义了一个 SQL 查询,使用前面定义的 orderMap 映射规则来映射查询结果。
这里的 SQL 语句选取了所有列 (select *) 并通过 o.uuid = u.id 条件进行表连接。--><select id="findall" resultMap="orderMap">select * from orders o, user u where o.uuid = u.id</select></mapper>
将映射文件配置到核心文件里:
最后,我们需要一个接口将写好的映射文件调用出来:
在映射文件中:
在接口中:
这样我们的整个功能写完了,现在需要写一个测试方法来调用:
测试类:
首先要配置日志文件:
其次要加载MyBatis配置文件
代码:
public class testuser {private InputStream in;private SqlSessionFactory factory;private SqlSession session;@Testpublic void star1() throws IOException {//配置日志信息Properties properties = new Properties();FileInputStream fileInputStream = new FileInputStream("src/main/resources/config/log4j.properties");properties.load(fileInputStream);PropertyConfigurator.configure(properties);// 加载 MyBatis 配置文件//从类路径中获取 MyBatis 配置文件 mybatis-config.xml 的输入流。in = Resources.getResourceAsStream("config/mybatis-config.xml");//创建 SqlSessionFactory 对象,它是 MyBatis 的工厂类,用于创建 SqlSession。factory = new SqlSessionFactoryBuilder().build(in);//创建一个新的 SqlSession 实例,用于执行 SQL 语句。session = factory.openSession();//通过 SqlSession 获取 oneselMapper 接口的代理实现。oneselMapper mapper = session.getMapper(oneselMapper.class);//接口中定义了一个名为 sanbiaoall 的方法,该方法返回一个 List<students> 类型的列表。List<order> findall = mapper.findall();for (order a : findall) {System.out.println(a);}}
}
结果:
Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 2101636817.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@7d446ed1]
==> Preparing: select * from orders o, user u where o.uuid = u.id
==> Parameters:
<== Total: 5
order{id = 1, ordertime = Thu Jan 01 13:36:51 CST 1970, total = 12.5, uuid = 1, user = user{id = 1, username = aa, password = 1233, birthday = Thu Jan 01 13:37:01 CST 1970}}
order{id = 2, ordertime = Thu Jan 01 13:36:51 CST 1970, total = 12.5, uuid = 3, user = user{id = 3, username = cc, password = 2133, birthday = Thu Jan 01 10:50:11 CST 1970}}
order{id = 3, ordertime = Thu Jan 01 13:38:31 CST 1970, total = 12.5, uuid = 2, user = user{id = 2, username = bb, password = 2133, birthday = Thu Jan 01 13:36:51 CST 1970}}
order{id = 4, ordertime = Thu Jan 01 13:37:01 CST 1970, total = 15.0, uuid = 2, user = user{id = 2, username = bb, password = 2133, birthday = Thu Jan 01 13:36:51 CST 1970}}
order{id = 5, ordertime = Thu Jan 01 13:37:01 CST 1970, total = 15.0, uuid = 1, user = user{id = 1, username = aa, password = 1233, birthday = Thu Jan 01 13:37:01 CST 1970}}
2、一对多查询(结构和上面一样下面只展示代码):
修改底层Javabean:
订单表:
package org.Emp;import java.util.Date;
import java.util.List;public class order {private Integer id;private Date ordertime;private Double total;private Integer uuid;public order() {}public order(Integer id, Date ordertime, Double total, Integer uuid) {this.id = id;this.ordertime = ordertime;this.total = total;this.uuid = uuid;}/*** 获取* @return id*/public Integer getId() {return id;}/*** 设置* @param id*/public void setId(Integer id) {this.id = id;}/*** 获取* @return ordertime*/public Date getOrdertime() {return ordertime;}/*** 设置* @param ordertime*/public void setOrdertime(Date ordertime) {this.ordertime = ordertime;}/*** 获取* @return total*/public Double getTotal() {return total;}/*** 设置* @param total*/public void setTotal(Double total) {this.total = total;}/*** 获取* @return uuid*/public Integer getUuid() {return uuid;}/*** 设置* @param uuid*/public void setUuid(Integer uuid) {this.uuid = uuid;}public String toString() {return "order{id = " + id + ", ordertime = " + ordertime + ", total = " + total + ", uuid = " + uuid + "}";}// private user user;}
用户表:
package org.Emp;import java.util.Date;
import java.util.List;
public class user {
private Integer id;
private String username;
private String password;
private Date birthday;private List<order> order;public user() {}public user(Integer id, String username, String password, Date birthday, List<order> order) {this.id = id;this.username = username;this.password = password;this.birthday = birthday;this.order = order;}/*** 获取* @return id*/public Integer getId() {return id;}/*** 设置* @param id*/public void setId(Integer id) {this.id = id;}/*** 获取* @return username*/public String getUsername() {return username;}/*** 设置* @param username*/public void setUsername(String username) {this.username = username;}/*** 获取* @return password*/public String getPassword() {return password;}/*** 设置* @param password*/public void setPassword(String password) {this.password = password;}/*** 获取* @return birthday*/public Date getBirthday() {return birthday;}/*** 设置* @param birthday*/public void setBirthday(Date birthday) {this.birthday = birthday;}/*** 获取* @return order*/public List<order> getOrder() {return order;}/*** 设置* @param order*/public void setOrder(List<order> order) {this.order = order;}public String toString() {return "user{id = " + id + ", username = " + username + ", password = " + password + ", birthday = " + birthday + ", order = " + order + "}";}
}
// private List<role> role;
写Mapper映射(核心):
<?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="org.dao.oneselMapper"><resultMap id="userMap" type="org.Emp.user"><id column="uuid" property="id"></id><result column="username" property="username"></result><result column="password" property="password"></result><result column="birthday" property="birthday"></result>
<!--集合映射 (Collection)--><collection property="order" ofType="org.Emp.order"><id column="oid" property="id"></id><result column="ordertime" property="ordertime"></result><result column="total" property="total"></result></collection></resultMap><!--数据库的一对多查询--><select id="onefindallduo" resultMap="userMap">select *,o.id oid from user u,orders o where o.uuid = u.id</select></mapper>
接口:
3、多对多查询:
修改底层Javabean;
role(角色表):
package org.Emp;import java.util.List;public class role {private Integer id;private String roleName;private String roleDesc;public role() {}public role(Integer id, String roleName, String roleDesc) {this.id = id;this.roleName = roleName;this.roleDesc = roleDesc;}/*** 获取* @return id*/public Integer getId() {return id;}/*** 设置* @param id*/public void setId(Integer id) {this.id = id;}/*** 获取* @return roleName*/public String getRoleName() {return roleName;}/*** 设置* @param roleName*/public void setRoleName(String roleName) {this.roleName = roleName;}/*** 获取* @return roleDesc*/public String getRoleDesc() {return roleDesc;}/*** 设置* @param roleDesc*/public void setRoleDesc(String roleDesc) {this.roleDesc = roleDesc;}public String toString() {return "role{id = " + id + ", roleName = " + roleName + ", roleDesc = " + roleDesc + "}";}
}
user(用户表):
package org.Emp;import java.util.Date;
import java.util.List;
public class user {
private Integer id;
private String username;
private String password;
private Date birthday;private List<role> role;public user() {}public user(Integer id, String username, String password, Date birthday, List<role> role) {this.id = id;this.username = username;this.password = password;this.birthday = birthday;this.role = role;}/*** 获取* @return id*/public Integer getId() {return id;}/*** 设置* @param id*/public void setId(Integer id) {this.id = id;}/*** 获取* @return username*/public String getUsername() {return username;}/*** 设置* @param username*/public void setUsername(String username) {this.username = username;}/*** 获取* @return password*/public String getPassword() {return password;}/*** 设置* @param password*/public void setPassword(String password) {this.password = password;}/*** 获取* @return birthday*/public Date getBirthday() {return birthday;}/*** 设置* @param birthday*/public void setBirthday(Date birthday) {this.birthday = birthday;}/*** 获取* @return role*/public List<role> getRole() {return role;}/*** 设置* @param role*/public void setRole(List<role> role) {this.role = role;}public String toString() {return "user{id = " + id + ", username = " + username + ", password = " + password + ", birthday = " + birthday + ", role = " + role + "}";}
}
写Mapper映射(核心):
<?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="org.dao.oneselMapper"><resultMap id="duoduoMapper" type="org.Emp.user"><id column="id" property="id"></id><result column="username" property="username"></result><result column="password" property="password"></result><result column="birthday" property="birthday"></result><collection property="role" ofType="org.Emp.role"><id column="roleid" property="id"></id><result column="roleName" property="roleName"></result><result column="roleDesc" property="roleDesc"></result></collection></resultMap><!--数据库的多对多查询--><select id="duoduoall" resultMap="duoduoMapper">select * from user u,user_role ur,role r where u.id=ur.userid and r.id=ur.roleid</select></mapper>
接口:
这样我们的两表查询就写完了。
注意:一定要配置核心文件,添加映射文件和数据库和Java互转的方法。