MyBatis之实体类属性与表字段不一致的处理

前篇的表字段userName与实体类属性一致,本篇的字段为user_name与实体类属性userName不一致;

1. 用户表sys_user2:

CREATE TABLE `sys_user2` (
  `id` INT(11) PRIMARY KEY AUTO_INCREMENT,
  `user_name` VARCHAR(50),
  `birthday` DATE,
  `salary` DECIMAL(8,2),
  `address` VARCHAR(200)
) ENGINE=INNODB CHARSET=utf8;
INSERT INTO `sys_user2` VALUES(1, '陈三', '1992-02-29', 123456.78, '深圳市南山区');
INSERT INTO `sys_user2` VALUES(2, '张三', '1990-03-05', 8500, '深圳市宝安区');
INSERT INTO `sys_user2` VALUES(3, '李三', '1991-05-23', 123326.1, '深圳市福田区');
INSERT INTO `sys_user2` VALUES(4, '赵四', '1988-09-15', 8000, '深圳市龙华新区');

2. 实体类SysUser2:

public class SysUser2 {
	private int id;
	private String userName;
	private Date birthday;
	private Double salary;
	private String address;
	
	public String toString(){
		return "SysUser2 : {id = " + id + ", userName = " + userName + ", birthday = " + birthday + ", salary = " + salary + ", address = " + address + "}";
	}
	
	//省略属性的setter、getter方法
}
3. 实体类SysUser2映射文件SysUser2.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">

<!-- namespace用于区分对应哪个实体类对应的配置文件,须对应typeAlias的alias -->
<mapper namespace="sysUser2">
  <!-- 新增用户 -->
  <insert id="insert" parameterType="sys_user2" useGeneratedKeys="true" keyProperty="id">
    insert into `sys_user2`(user_name, birthday, salary, address) 
    values(#{userName}, #{birthday}, #{salary}, #{address})
  </insert>

  <!-- 删除用户 -->
  <delete id="delete" parameterType="int">
    delete from `sys_user2` where id=#{id}
  </delete>
  
  <!-- 根据id修改用户信息 -->
  <update id="update" parameterType="sys_user2">
    update `sys_user2` set user_name=#{userName}
    where id=#{id}
  </update>
  
  <!-- 根据id查询单条用户记录 -->
  <select id="getById" parameterType="int" resultType="sys_user2">
    select * from `sys_user2` where id = #{id}
  </select>
  
  <!-- 根据其它字段查询用户列表 -->
  <select id="getByName" parameterType="java.lang.String" resultType="sys_user2">
    select * from `sys_user2` where user_name like '%${value}%'
  </select>
  
  <!-- 查询所有用户记录 -->
  <select id="getAll" resultType="sys_user2">
    select * from `sys_user2`
  </select>
</mapper>

myBatisConfig.xml中的mappers加了实体类映射

<?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>
  <!-- 为实体类配置别名,方便在类的配置文件里直接取用 -->
  <typeAliases>
    <typeAlias alias="sys_user2" type="com.chensan.sys.entity.SysUser2"/>
  </typeAliases>
  
  <!-- 和spring整合后 environments配置将废除-->
  <environments default="development">
	<environment id="development">
	  <!-- 使用jdbc事务管理  或者JTA事务管理-->
	  <transactionManager type="JDBC" />
	  <!-- 数据库连接池  第三方组件:c3p0-->
	  <dataSource type="POOLED">
		<property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test1"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
	  </dataSource>
	</environment>
  </environments>

  <!-- 加载实体类的映射文件 -->
  <mappers>
    <mapper resource="com/chensan/sys/mapper/SysUser2.xml"/>
  </mappers>
</configuration>
4. 测试类MyBatisSysUser2Test:

public class MyBatisSysUser2Test {
	private static SqlSessionFactory sqlSessionFactory;
    private static Reader resource;
    
    //创建会话工厂
    static{
        try{
        	//读取MyBatis配置文件
        	resource = Resources.getResourceAsReader("myBatisConfig.xml");
        	//创建SqlSessionFactory会话工厂
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(resource);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    public static SqlSessionFactory getSession(){
        return sqlSessionFactory;
    }
    
    //插入一条数据
    public void insert(){
    	SqlSession sqlSession = sqlSessionFactory.openSession();
    	SysUser2 sysUser2 = new SysUser2();
    	sysUser2.setUserName("王二");
    	DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    	try {
    		sysUser2.setBirthday(df.parse("1988-08-23"));
    	} catch (ParseException e) {
    	    e.printStackTrace();
    	}
    	sysUser2.setSalary(7800.00);
    	sysUser2.setAddress("深圳市罗湖区");
    	sqlSession.insert("sysUser2.insert", sysUser2);
    	sqlSession.commit();//新增、修改、删除需要提交
    	sqlSession.close();
    	System.out.println(sysUser2);
    }
    
    //删除一条记录
    public void delete(){
    	SqlSession sqlSession = sqlSessionFactory.openSession();
    	sqlSession.delete("sysUser2.delete", 4);
    	sqlSession.commit();
    	sqlSession.close();
    }
    
    //更新用户记录
    public void update(){
    	SqlSession sqlSession = sqlSessionFactory.openSession();
    	SysUser2 sysUser2 = new SysUser2();
    	sysUser2.setId(5);
    	sysUser2.setUserName("王二小");
    	sqlSession.update("sysUser2.update", sysUser2);
    	sqlSession.commit();
    	sqlSession.close();
    	System.out.println(sysUser2);
    }
    
    public void getById(){
    	//开启会话实例sqlSession
    	SqlSession sqlSession = sqlSessionFactory.openSession();
    	SysUser2 sysUser2 = sqlSession.selectOne("sysUser2.getById",1);
    	sqlSession.close();//关闭会话
    	System.out.println(sysUser2);
    }
    
    //根据其它字段查询记录
    public void getByName(){
    	SqlSession sqlSession = sqlSessionFactory.openSession();
    	List<SysUser2> sysUser2 = sqlSession.selectList("sysUser2.getByName","三");
    	sqlSession.close();
    	for(SysUser2 user : sysUser2){
    		System.out.println(user);
    	}
    }
    
    //查询所有用户记录
    public void getAll(){
    	SqlSession sqlSession = sqlSessionFactory.openSession();
    	List<SysUser2> sysUser2 = sqlSession.selectList("sysUser2.getAll");
    	sqlSession.close();
    	for(SysUser2 user : sysUser2){
    		System.out.println(user);
    	}
    }
    
    public static void main(String[] args) {
    	MyBatisSysUser2Test myBatisSysUser2Test = new MyBatisSysUser2Test();
    	//myBatisSysUser2Test.insert();
    	//myBatisSysUser2Test.delete();
    	//myBatisSysUser2Test.update();
    	//myBatisSysUser2Test.getById();
    	//myBatisSysUser2Test.getByName();
    	myBatisSysUser2Test.getAll();
    } 
}
注意:

1)实体类属性和数据表列名不对应时,增删改的表字段和占位符位置一一对应,对数据库操作不影响;但在查询时,select * from `sys_user2`,表列名与实体属性不一致且没有指明表列与实体类属性间的对应关系,则无法对应的字段值为null(如本例中的userName属性)。

第一种方式:给列名与属性不对应的列取别名

<!-- 根据id查询单条用户记录 -->
  <select id="getById" parameterType="int" resultType="sys_user2">
    select id, user_name userName, birthday, salary, address 
    from `sys_user2` where id = #{id}
  </select>

第二种方式:在resultMap中指定表列名与实体类属性间的对应关系;

<?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">

<!-- namespace用于区分对应哪个实体类对应的配置文件,须对应typeAlias的alias -->
<mapper namespace="sysUser2">
  <resultMap type="com.chensan.sys.entity.SysUser2" id="sys_user2">
    <id property="id" column="id"/>
    <result property="userName" column="user_name"/>
    <result property="birthday" column="birthday"/>
    <result property="salary" column="salary"/>
    <result property="address" column="address"/>
    
  </resultMap>

  <!-- 新增用户 -->
  <insert id="insert" parameterType="com.chensan.sys.entity.SysUser2" useGeneratedKeys="true" keyProperty="id">
    insert into `sys_user2`(user_name, birthday, salary, address) 
    values(#{userName}, #{birthday}, #{salary}, #{address})
  </insert>

  <!-- 删除用户 -->
  <delete id="delete" parameterType="int">
    delete from `sys_user2` where id=#{id}
  </delete>
  
  <!-- 根据id修改用户信息 -->
  <update id="update" parameterType="com.chensan.sys.entity.SysUser2">
    update `sys_user2` set user_name=#{userName}
    where id=#{id}
  </update>
  
  <!-- 根据id查询单条用户记录 -->
  <select id="getById" parameterType="int" resultMap="sys_user2">
    select * from `sys_user2` where id=#{id}
  </select>
  
  <!-- 根据其它字段查询用户列表 -->
  <select id="getByName" parameterType="java.lang.String" resultMap="sys_user2">
    select * from `sys_user2` where user_name like '%${value}%'
  </select>
  
  <!-- 查询所有用户记录 -->
  <select id="getAll" resultMap="sys_user2">
    select * from `sys_user2`
  </select>
</mapper>

加了resultMap则不必再依靠myBatis配置文件里的typeAlias别名,增删改的返回类型内容可直接为resultMap中指定的id属性值;

查询的返回结果类型原为resultType,使用resultMap后,resultType也要改为resultMap,否则报错如下:

Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. 
Cause: org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. 
Cause: org.apache.ibatis.builder.BuilderException: Error resolving class. 
Cause: org.apache.ibatis.type.TypeException: Could not resolve type alias 'sys_user2'.  
Cause: java.lang.ClassNotFoundException: Cannot find class: sys_user2

同时应注意insert和update时,parameterType不能用resultMap的id,只能用类的全限定名,否则也会报上面的错误;

resultMap的type属性:

    type:指定该映射对应的实体类,为全路径名;

    id:为实体类对应的标识,作用域为本映射文件;查询的resultMap可直接用该id属性的值,新增和修改传递的parameterType不能使用该属性,只能用类的全限定名;

    autoMapping:自动映射功能就是自动查找与字段名小写同名的属性名,并调用setter方法。默认为true,当设置为false时,需要注明映射关系才会调用setter方法。由于autoMapping默认为true,实体类属性与数据表列同名的不须列出可自动匹配。但经测试,在表关联时,即便是数据表列和实体类属性同名,也要显式注明autoMapping=“true"或者把实体类属性和数据表列一一列举,否则主表对应的未列举属性为null;可用MyBatis一对一关联的实例进行测试。

    extends:继承父类的属性和方法;当父类不是抽象方法时可继承。

result属性:

   property:实体类对应的属性;

    column:实体类属性对应的数据表列;

    jdbcType和javaType的对应关系:

JDBC Type           Java Type  
CHAR                String  
VARCHAR             String  
LONGVARCHAR         String  
NUMERIC             java.math.BigDecimal  
DECIMAL             java.math.BigDecimal  
BIT             boolean  
BOOLEAN             boolean  
TINYINT             byte  
SMALLINT            short  
INTEGER             int  
BIGINT              long  
REAL                float  
FLOAT               double  
DOUBLE              double  
BINARY              byte[]  
VARBINARY           byte[]  
LONGVARBINARY               byte[]  
DATE                java.sql.Date  
TIME                java.sql.Time  
TIMESTAMP           java.sql.Timestamp  
CLOB                Clob  
BLOB                Blob  
ARRAY               Array  
DISTINCT            mapping of underlying type  
STRUCT              Struct  
REF                         Ref  
DATALINK            java.net.URL[color=red][/color]

    typeHandler:




评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值