java项目单独使用mybatis的小例子

本文通过创建数据库配置文件、实体对象、Mapper XML和接口,详细介绍了如何在Java项目中单独使用MyBatis。配合MySQL数据库和jdbc,实现了数据的增删改查操作。通过servlet接口和测试类,确保了整个流程的顺利运行。

朋友让我帮他写几个接口,因为比较简单,使用jdbc编程,后来发现数据库字段和实体类中对象属性不能实现映射,我使用mybatis框架。我使用httpClient的post方式来测试接口,项目所需包如下:


目录结构:


在src创建数据库配置文件mysql.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456


创建实体对象Goods

package pojo;
import java.math.BigDecimal;
public class Goods {
	private String goodCode;
	private String barCode;
	private String nsUrl;
	private String categoryTitle;
	private String title;
	private String remark;
	private Integer reserve;
	private Integer packge;
	private BigDecimal price;
	private String dicount;
	private BigDecimal discountPrice;
	private Integer carCount;
	public String getGoodCode() {
		return goodCode;
	}
	public void setGoodCode(String goodCode) {
		this.goodCode = goodCode;
	}
	public String getBarCode() {
		return barCode;
	}
	public void setBarCode(String barCode) {
		this.barCode = barCode;
	}
	public String getNsUrl() {
		return nsUrl;
	}
	public void setNsUrl(String nsUrl) {
		this.nsUrl = nsUrl;
	}
	public String getCategoryTitle() {
		return categoryTitle;
	}
	public void setCategoryTitle(String categoryTitle) {
		this.categoryTitle = categoryTitle;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getRemark() {
		return remark;
	}
	public void setRemark(String remark) {
		this.remark = remark;
	}
	public Integer getReserve() {
		return reserve;
	}
	public void setReserve(Integer reserve) {
		this.reserve = reserve;
	}
	public Integer getPackge() {
		return packge;
	}
	public void setPackge(Integer packge) {
		this.packge = packge;
	}
	public BigDecimal getPrice() {
		return price;
	}
	public void setPrice(BigDecimal price) {
		this.price = price;
	}
	public String getDicount() {
		return dicount;
	}
	public void setDicount(String dicount) {
		this.dicount = dicount;
	}
	public BigDecimal getDiscountPrice() {
		return discountPrice;
	}
	public void setDiscountPrice(BigDecimal discountPrice) {
		this.discountPrice = discountPrice;
	}
	public Integer getCarCount() {
		return carCount;
	}
	public void setCarCount(Integer carCount) {
		this.carCount = carCount;
	}
	
}


创建GoodsMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.GoodsMapper">
	<!-- 自定义返回结果集 -->
	<resultMap id="goodsMap" type="Goods">
		<id property="goodCode" column="goodCode" javaType="java.lang.String"></id>
		<result property="barCode" column="barCode" javaType="java.lang.String"></result>
		<result property="nsUrl" column="nsUrl" javaType="java.lang.String"></result>
		<result property="categoryTitle" column="categoryTitle" javaType="java.lang.String"></result>
		<result property="title" column="title" javaType="java.lang.String"></result>
		<result property="remark" column="remark" javaType="java.lang.String"></result>
		<result property="reserve" column="reserve" javaType="java.lang.Integer"></result>
		<result property="packge" column="packge" javaType="java.lang.Integer"></result>
		<result property="price" column="price" javaType="java.math.BigDecimal"></result>
		<result property="dicount" column="dicount" javaType="java.lang.String"></result>
		<result property="discountPrice" column="discountPrice" javaType="java.math.BigDecimal"></result>
		<result property="carCount" column="carCount" javaType="java.lang.Integer"></result>
	</resultMap>
	<select id="selectAllGoods" resultMap="goodsMap">
		select * from goods
	</select>
	
	<select id="selectRecommendGoods" resultMap="goodsMap">
		select * from goods limit 0,4;
	</select>
</mapper>  

创建接口GoodsMapper.java

package mapper;
import java.util.List;
import pojo.Goods;

public interface GoodsMapper {
	public List<Goods> selectAllGoods() throws Exception;
	public List<Goods> selectRecommendGoods() throws Exception;
}


mybatis.cfg.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 引入外部配置文件 -->
    <properties resource="mysql.properties"></properties>
     <!-- 为JAVA Bean起类别名 -->
    <typeAliases >
         <!-- 别名方式1,一个一个的配置 type中放置的是类的全路径,alias中放置的是类别名
         <typeAliase type="com.cy.mybatis.beans.UserBean" alias="UserBean"/>-->
         <!-- 别名方式2,自动扫描,将JAVA类的类名作为类的类别名 -->
         <package name="pojo"/>
    </typeAliases>
   
     <!-- 配置mybatis运行环境 -->
       <environments default="cybatis">
         <environment id="cybatis">
             <!-- type="JDBC" 代表使用JDBC的提交和回滚来管理事务 -->
             <transactionManager type="JDBC" />
             <!-- mybatis提供了3种数据源类型,分别是:POOLED,UNPOOLED,JNDI -->
             <!-- POOLED 表示支持JDBC数据源连接池 -->
             <!-- UNPOOLED 表示不支持数据源连接池 -->
             <!-- JNDI 表示支持外部数据源连接池 -->
             <dataSource type="POOLED">
                 <property name="driver" value="${jdbc.driver}" />
                 <property name="url" value="${jdbc.url}" />
                 <property name="username" value="${jdbc.username}" />
                 <property name="password" value="${jdbc.password}" />
             </dataSource>
         </environment>
     </environments> 
     <mappers>
         <!-- 告知映射文件方式1,一个一个的配置
         <mapper resource="com/cy/mybatis/mapper/UserMapper.xml"/>-->
         <!-- 告知映射文件方式2,自动扫描包内的Mapper接口与配置文件 -->
         <package name="mapper"/>
     </mappers>
</configuration>


数据库连接工具类DBTools

package until;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class DBTools {
public static SqlSessionFactory sessionFactory;
static {
try {
// 使用MyBatis提供的Resources类加载mybatis的配置文件
Reader reader = Resources.getResourceAsReader("mybatis.cfg.xml");
// 构建sqlSession的工厂
sessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (Exception e) {
e.printStackTrace();
}
}
// 创建能执行映射文件中sql的sqlSession
public static SqlSession getSession() {
return sessionFactory.openSession();
}
}


selectGoods.java 代码(servlet接口)

package test;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.ibatis.session.SqlSession;
import mapper.GoodsMapper;
import net.sf.json.JSONArray;
import pojo.Goods;
import until.DBTools;


/**
 * Servlet implementation class TestSvrvlet
 */
@WebServlet("/getAllGoods")
public class selectGoods extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
*      response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
try {
out.println(selectAllGoods());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
*      response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
try {
out.println(selectAllGoods());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

/**
* 整合mybatis后查询商品方法
* 
* @return
*/
private String selectAllGoods() {
JSONArray jr = new JSONArray();
SqlSession session = DBTools.getSession();
GoodsMapper mapper = session.getMapper(GoodsMapper.class);
try {
List<Goods> goodsList = mapper.selectAllGoods();
System.out.println(goodsList.toString());
jr = JSONArray.fromObject(goodsList);
session.commit();
} catch (Exception e) {
e.printStackTrace();
session.rollback();
}
System.out.println("jr" + jr);
return jr.toString();
}
}

TestHttpClient.java

package test;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;


import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;


public class TestHttpClient {
public void postGoods() {
// 创建默认的httpClient实例.
CloseableHttpClient httpclient = HttpClients.createDefault();
// 创建httppost
HttpPost httppost = new HttpPost("http://localhost:8080/test/getAllGoods");
UrlEncodedFormEntity uefEntity = null;
try {
httppost.setEntity(uefEntity);
CloseableHttpResponse response = httpclient.execute(httppost);
try {
HttpEntity entity = response.getEntity();
if (entity != null) {
System.out.println("--------------------------------------");
System.out.println("Response content: " + EntityUtils.toString(entity, "UTF-8"));
System.out.println("--------------------------------------");
}
} finally {
response.close();
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭连接,释放资源
try {
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

//测试方法
public static void main(String[] args) {
TestHttpClient httpte = new TestHttpClient();
httpte.postGoods();
}
}


控制台输出内容

--------------------------------------
Response content: [{"carCount":0,"dicount":"","categoryTitle":"","remark":"很好","goodCode":"10000","packge":0,"discountPrice":0,"title":"笔记本","price":3000,"nsUrl":"","barCode":"1111","reserve":0},{"carCount":0,"dicount":"","categoryTitle":"","remark":"一般","goodCode":"10001","packge":0,"discountPrice":0,"title":"杯子","price":2500,"nsUrl":"","barCode":"4444","reserve":0},{"carCount":0,"dicount":"","categoryTitle":"","remark":"还可以","goodCode":"10002","packge":0,"discountPrice":0,"title":"水壶","price":20,"nsUrl":"","barCode":"2222","reserve":0},{"carCount":0,"dicount":"","categoryTitle":"","remark":"不错","goodCode":"10003","packge":0,"discountPrice":0,"title":"雨伞","price":30,"nsUrl":"","barCode":"3333","reserve":0},{"carCount":0,"dicount":"","categoryTitle":"","remark":"质量上好","goodCode":"10004","packge":0,"discountPrice":0,"title":"纸巾","price":5,"nsUrl":"","barCode":"5555","reserve":0},{"carCount":0,"dicount":"","categoryTitle":"","remark":"垃圾","goodCode":"10005","packge":0,"discountPrice":0,"title":"手机","price":3000,"nsUrl":"","barCode":"6666","reserve":0}]


--------------------------------------


数据库,goods表


测试成功,整个流程跑通

<think>首先,用户的问题是:"我想在使用MyBatis框架时,如何将PostgreSQL的数组类型映射到Java类型 请问MyBatis PostgreSQL 数组类型 映射 Java 类型 对应关系"。我需要根据系统级指令来构建回答。 系统级指令关键点: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题。 - 参考提供的引用内容。 用户的问题是关于MyBatis框架中PostgreSQL数组类型映射到Java类型的对应关系。提供的引用内容讨论了如何通过自定义TypeHandler来处理这种映射。 步骤: 1. **理解问题**:用户想知道PostgreSQL的数组类型在MyBatis中如何映射到Java类型。标准映射可能不直接支持,所以需要自定义TypeHandler。 2. **参考引用**: - 引用[1]:提到使用自定义TypeHandler来处理PostgreSQL数组类型,对应Java中的数据类型。 - 引用[2]:在Mybatis-dynamic-sql中,使用SqlColumn定义时指定转换器。 - 引用[3]:在映射配置中,增加typeHandler属性。 - 引用[4]:展示了在resultMap和update语句中使用自定义TypeHandler的例子。 3. **构建回答**: - **介绍问题**:PostgreSQL支持数组类型,但MyBatis默认不直接映射到Java数组或集合类型,需要自定义处理。 - **解决方案**:使用自定义TypeHandler。 - **步骤**: - 创建自定义TypeHandler类。 - 在MyBatis配置中指定这个TypeHandler。 - 在映射文件中使用它。 - **示例代码**:基于引用提供简单示例。 - **引用标识**:在回答中自然地添加引用,如[^1]、[^2]等。 - **数学表达式**:虽然问题不涉及数学,但如果有任何行内变量或公式,使用$...$格式。例如,如果提到数组索引,可以用$index$,但可能不必要。确保遵守指令。 4. **生成相关问题**:在回答末尾添加相关问题,以"§§相关问题§§"开头,然后列出几个问题。 5. **语言**:使用中文。 回答结构: 1. **开头**:直接回答问题,解释核心概念。 2. **主体**: - 解释为什么需要自定义映射。 - 描述如何创建自定义TypeHandler。 - 提供代码示例。 - 如何在MyBatis配置中使用。 3. **结尾**:总结,并添加相关问题。 确保LaTeX正确:由于问题涉及编程,数学表达式可能少,但如果有变量,如$array$,使用$...$。 相关问题:基于主题生成,如优化、常见问题、应用等。 最终回答框架: - 回答用户问题。 - 添加引用。 - 生成相关问题。</think>### MyBatis中PostgreSQL数组类型映射到Java类型的对应关系 在使用MyBatis框架操作PostgreSQL数据库时,PostgreSQL的数组类型(如`integer[]`、`text[]`)无法直接映射到Java的标准类型(如`int[]`或`List<String>`),因为MyBatis默认不支持这种复杂类型映射。这会导致查询或更新时出现类型转换错误[^1]。解决方法是**通过自定义`TypeHandler`来实现映射**。以下是详细步骤和对应关系: #### 1. **理解PostgreSQL数组与Java类型的对应关系** - PostgreSQL数组类型(例如`integer[]`)在Java中通常映射为: - 基本类型数组:如`int[]`(对应`integer[]`)。 - 对象类型数组:如`String[]`(对应`text[]`)。 - 集合类型:如`List<Integer>`(更常用,但需通过`TypeHandler`转换)[^1][^4]。 - 关键点:MyBatis默认不处理数组映射,必须自定义`TypeHandler`。 #### 2. **创建自定义TypeHandler** - 实现`org.apache.ibatis.type.TypeHandler`接口,处理数组的JDBCJava类型转换。 - 示例:创建一个处理`integer[]`到`List<Integer>`的`TypeHandler`(以Java代码为例): ```java import org.apache.ibatis.type.*; import java.sql.*; import java.util.*; @MappedTypes(List.class) // 指定Java类型 @MappedJdbcTypes(JdbcType.ARRAY) // 指定JDBC类型 public class ArrayTypeHandler implements TypeHandler<List<Integer>> { @Override public void setParameter(PreparedStatement ps, int i, List<Integer> parameter, JdbcType jdbcType) throws SQLException { // Java List转PostgreSQL数组 Integer[] array = parameter.toArray(new Integer[0]); ps.setArray(i, ps.getConnection().createArrayOf("integer", array)); } @Override public List<Integer> getResult(ResultSet rs, String columnName) throws SQLException { // PostgreSQL数组转Java List Array array = rs.getArray(columnName); return array != null ? Arrays.asList((Integer[]) array.getArray()) : Collections.emptyList(); } @Override public List<Integer> getResult(ResultSet rs, int columnIndex) throws SQLException { // 省略实现(类似getResult) } @Override public List<Integer> getResult(CallableStatement cs, int columnIndex) throws SQLException { // 省略实现(类似getResult) } } ``` - 说明: - `@MappedTypes`定义Java目标类型(如`List<Integer>`)。 - `@MappedJdbcTypes`指定JDBC类型为`ARRAY`。 - 核心方法:`setParameter`(Java→PG)和`getResult`(PG→Java)[^1][^3][^4]。 #### 3. **在MyBatis配置中使用TypeHandler** - **映射文件(XML)中配置**: - 在`<resultMap>`或`<parameter>`中指定`typeHandler`属性。 - 示例(查询操作): ```xml <resultMap id="studentMap" type="com.example.Student"> <result column="student_names" property="names" typeHandler="com.example.ArrayTypeHandler" jdbcType="ARRAY"/> </resultMap> <select id="getStudent" resultMap="studentMap"> SELECT * FROM student </select> ``` - 示例(更新操作): ```xml <update id="updateNames"> UPDATE student SET student_names = #{names, typeHandler=com.example.ArrayTypeHandler} WHERE id = #{id} </update> ``` - 这里`#{names}`是Java方法的参数(如`List<Integer>`),通过`TypeHandler`自动转换为PG数组[^3][^4]。 - **动态SQL配置(如MyBatis Dynamic SQL)**: - 在`SqlColumn`定义中直接指定`TypeHandler`: ```java public final SqlColumn<List<Integer>> names = column( "student_names", JDBCType.ARRAY, "com.example.ArrayTypeHandler" // TypeHandler全路径 ); ``` [^2] #### 4. **常见问题与优化建议** - **类型匹配**:确保PostgreSQL数组元素类型与Java类型一致(例如PG `text[]` 对应 Java `String[]` 或 `List<String>`)。 - **性能**:自定义`TypeHandler`可能影响性能,建议测试大数据量场景[^1]。 - **错误处理**:如果映射失败,检查`jdbcType="ARRAY"`是否在配置中正确声明。 - **简化方案**:使用第三方库(如`mybatis-types`),但自定义`TypeHandler`更灵活[^4]。 通过以上步骤,您可以将PostgreSQL数组无缝映射到Java类型,避免类型转换错误。核心是自定义`TypeHandler`,并在MyBatis配置中显式引用它[^1][^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值