复习电商笔记-7

后台首页+EasyUI+分类树+商品列表

思考:

序号

知识点

类型

难度系数

掌握程度

  1.  

EasyUI富客户端

技术

3

了解

  1.  

重复扫描问题: Spring注解方式读取属性文件中的属性为何不能在只能在service层注入,不能在controller层注入?

论述

1

了解

  1.  

MyBatis假接口

论述

1

理解

知识点:

序号

知识点

类型

难度系数

掌握程度

  1.  

EasyUI.tree组件,异步加载树

设计

3

熟练

  1.  

EasyUI.datagrid组件

设计

1

熟练

 

 

数据库表设计

先创建下面三张表,后续根据业务再创建其所需要的数据库表。

 

 

商品分类表

create table tb_item_cat
(
   id                   bigint not null auto_increment,
   parent_id            bigint comment '父分类ID=0时,代表一级分类',
   name                 varchar(150),
   status               int(1) default 1 comment '默认值为1,可选值:1正常,2删除',
   sort_order           int(4) not null,
   is_parent            tinyint(1),
   created              datetime,
   updated              datetime,
   primary key (id)
);

create index parent_id on tb_item_cat
(
   parent_id,
   status
);

create index sort_order on tb_item_cat
(
   sort_order
);

典型树形结构,创建索引。

注意表设计的不同:

  1. 表的主键采用长整形
  2. 对parent_id和sort_order常用查询条件字段设置索引

 

 

商品分类的显示

要求:点击“选择分类”,弹出窗口esayUI.window,esayUI.tree树形展现分类表tb_item_cat中的数据。只能选最后的分类(叶子节点)。

easyUI 官网:    http://www.jeasyui.net/       

 

通用Mapper的插件介绍

注:Selective代表不是所有字段拼入SQL。例如insert是所有字段都拼入SQL语句,而insertSelective代表非空字段才拼入SQL语句。这样insertSelectiveinsert语句执行效率高。

问题:

传统的mybatis需要在映射文件中写sql,由于业务的不同造成sql语句不同,而无法造成通用,开发人员工作量巨大,也不易维护。

解决:

  1. 把表名作为参数传入,不能解决字段不同的问题。
  2. 动态生成SQL,如何实现?可以使用插件(拦截器实现)。
  3. 这样映射文件中只需写表和实体的映射关系

 

 

依赖

官网地址:http://git.oschina.net/free/Mapper

提示,3.1.0及以后版本的groupId修改为tk.mybatis,   artifactId为mapper

<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper</artifactId>
    <version>3.2.2</version>
</dependency>

 

 

JPA注解   

JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。Sun引入新的JPA ORM规范出于两个原因:其一,简化现有Java EE和Java SE应用开发工作;其二,Sun希望整合ORM技术,实现天下归一。 JPA由EJB 3.0软件专家组开发。

POJO实体对象上加JPAJava Persistence API)注解,实现类和数据库表之间的映射。

 

序号

javax.persistence注解

说明

  1.  

@Table(name="tb_item_cat")

标识类对应的表

  1.  

@Id

主键

  1.  

@GeneratedValue

(strategy=GenerationType.IDENTITY)

自增

  1.  

@Column(name="parent_id")

当属性和字段不一致,设置映射关系

未指定的驼峰规则,在mybatis-config.xml中配置

<setting name="mapUnderscoreToCamelCase" value="true"/>。

1)表名默认使用类名,按驼峰规则,下划线后字母自动大写,如UserInfo对应表名user_info。

2)当表名和类名不对应时,使用@Table(name="tableName")进行指定。

3)属性和字段名不对应时,使用@Column(name="fieldName")进行指定。

4)当非表的属性时,使用@Transient可以忽略此属性。

5)必须设置主键@Id,可以有多个属性设置@Id,作为联合主键。默认情况下,如果没有设置主键,所有字段作为一个联合主键,这种效率极低。

6)实体类可以继承使用,注解也将继承。

7)基于基本类型,如int作为实体字段时会有默认值0,而且无法消除,所以实体类中建议不要使用基本类型。

 

8)主键策略,支持序列、UUID、主键自增三种方式,其中序列和UUID可以配置多个,主键自增只能配置一个。

@GeneratedValue(strategy = GenerationType.IDENTITY) //主键自增长策略

@GeneratedValue(strategy=GenerationType.AUTO) 也是默认策略, 即写成@GeneratedValue也可。类似于hibernate的native策略,生成方式取决于底层的数据库。

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_u")指定“序列”策略,使用于Oracle。其中generator表示序列的名字。

@GeneratedValue(generator = "UUID")可以用于任意字符串类型长度超过32位的字段。

通用Mapper Demo示例

 

 

第一步:创建ManvenWeb工程demo-supermapper

依赖通用mapper jar包,采用2.3.2版本。加入其它的jar包依赖。

pom.xml文件代码如下:

<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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.supermapper</groupId>
	<artifactId>demo-supermapper</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo-supermapper Maven Webapp</name>
	<url>http://maven.apache.org</url>

	<dependencies>
		<dependency>
			<groupId>com.github.abel533</groupId>
			<artifactId>mapper</artifactId>
			<version>2.3.2</version>
	</dependency>
		<!-- 单元测试 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.10</version>
			<scope>test</scope>
		</dependency>
		<!-- Mybatis -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.2.8</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>1.2.2</version>
		</dependency>
		<!-- MySql -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.32</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.6.4</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>demo-supermapper</finalName>
	</build>
</project>

 

 

第二步:配置mybatis核心配置文件mybatis-config.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="jdbc.properties"/>
	<settings>
		<!-- 开启驼峰自动映射 -->
		<setting name="mapUnderscoreToCamelCase" value="true"/>
	</settings>
	<typeAliases>
		<!-- 设置别名 -->
		<package name="com.supermapper.pojo"/>
	</typeAliases>
	<!-- 指定环境 -->
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<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>
		<package name="com.supermapper.mapper"/>
	</mappers>
</configuration>

 

 

第三步:数据库链接参数配置jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/jtdb?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
jdbc.username=root
jdbc.password=root

 

 

第四步:日志配置log4j.properties

log4j.rootLogger=DEBUG,A1
log4j.logger.org.mybatis = DEBUG
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n

 

 

第五步:创建测试表tb_user

create table t_user
(
   id                   bigint not null auto_increment,
   user_name            varchar(30),
   password             varchar(30),
   name                 varchar(50),
   age                  tinyint,
   sex                  tinyint,
   birthday             datetime,
   created              datetime,
   updated              datetime,
   primary key (id)
);

 

 

第六步:创建实体对象User.java

POJO实现代码如下:

package com.jt.test.pojo;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Table(name = "t_user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) //主键自增长策略
    private Long id;

    @Column(name = "user_name")
    private String userName;

    private String password;

    //@Column
    private String name;

    private Integer age;

    private Boolean sex;

    private Date birthday;

    private Date created;

    //@Transient 不是数据库表字段,忽略
    private Date updated;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
 this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Boolean getSex() {
        return sex;
    }

    public void setSex(Boolean sex) {
        this.sex = sex;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    public Date getUpdated() {
        return updated;
    }

    public void setUpdated(Date updated) {
   this.updated = updated;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", userName=" + userName + ", password=" + password + ", name=" + name
                + ", age=" + age + ", sex=" + sex + ", birthday=" + birthday + ", created=" + created
                + ", updated=" + updated + "]";
    }

}

 

 

第七步:引入对通用接口封装类和接口SysMapper

SysMapperPrivider.java

package com.supermapper.base.mapper;

import static org.apache.ibatis.jdbc.SqlBuilder.BEGIN;
import static org.apache.ibatis.jdbc.SqlBuilder.DELETE_FROM;
import static org.apache.ibatis.jdbc.SqlBuilder.SQL;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.scripting.xmltags.ForEachSqlNode;
import org.apache.ibatis.scripting.xmltags.MixedSqlNode;
import org.apache.ibatis.scripting.xmltags.SqlNode;
import org.apache.ibatis.scripting.xmltags.StaticTextSqlNode;

import com.github.abel533.mapper.MapperProvider;
import com.github.abel533.mapperhelper.EntityHelper;
import com.github.abel533.mapperhelper.MapperHelper;

public class SysMapperProvider extends MapperProvider {

    public SysMapperProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
        super(mapperClass, mapperHelper);
    }

    public SqlNode deleteByIDS(MappedStatement ms) {
        Class<?> entityClass = getSelectReturnType(ms);
        Set<EntityHelper.EntityColumn> entityColumns = EntityHelper.getPKColumns(entityClass);
        EntityHelper.EntityColumn column = null;
        for (EntityHelper.EntityColumn entityColumn : entityColumns) {
            column = entityColumn;
            break;
        }
        
        List<SqlNode> sqlNodes = new ArrayList<SqlNode>();
 // 开始拼sql
        BEGIN();
        // delete from table
        DELETE_FROM(tableName(entityClass));
        // 得到sql
        String sql = SQL();
        // 静态SQL部分
        sqlNodes.add(new StaticTextSqlNode(sql + " WHERE " + column.getColumn() + " IN "));
        // 构造foreach sql
        SqlNode foreach = new ForEachSqlNode(ms.getConfiguration(), new StaticTextSqlNode("#{"
                + column.getProperty() + "}"), "ids", "index", column.getProperty(), "(", ")", ",");
        sqlNodes.add(foreach);
        return new MixedSqlNode(sqlNodes);
    }

}

SySMapper.java

package com.supermapper.base.mapper;

import java.util.List;

import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider;

public interface SysMapper<T> {

    /**
     * 根据主键ID批量删除
     * 
     * @param key
     * @return
     */
    @DeleteProvider(type = SysMapperProvider.class, method = "dynamicSQL")
    int deleteByIDS(@Param("ids") Object[] key);

    /**
     * 根据实体类不为null的字段进行查询,条件全部使用=号and条件
     * 
     * @param record
     * @return
     */
    @SelectProvider(type = SysMapperProvider.class, method = "dynamicSQL")
    List<T> select(T record);

    /**
 * 根据实体类不为null的字段查询总数,条件全部使用=号and条件
     * 
     * @param record
     * @return
     */
    @SelectProvider(type = SysMapperProvider.class, method = "dynamicSQL")
    int selectCount(T record);

    /**
     * 根据主键进行查询,必须保证结果唯一 单个字段做主键时,可以直接写主键的值 联合主键时,key可以是实体类,也可以是Map
     * 
     * @param key
     * @return
     */
    @SelectProvider(type = SysMapperProvider.class, method = "dynamicSQL")
    T selectByPrimaryKey(Object key);

    /**
     * 插入一条数据 支持Oracle序列,UUID,类似Mysql的INDENTITY自动增长(自动回写) 优先使用传入的参数值,参数值空时,才会使用序列、UUID,自动增长
     * 
     * @param record
     * @return
     */
    @InsertProvider(type = SysMapperProvider.class, method = "dynamicSQL")
    int insert(T record);

    /**
     * 插入一条数据,只插入不为null的字段,不会影响有默认值的字段 支持Oracle序列,UUID,类似Mysql的INDENTITY自动增长(自动回写)
     * 优先使用传入的参数值,参数值空时,才会使用序列、UUID,自动增长
     * 
     * @param record
     * @return
     */
    @InsertProvider(type = SysMapperProvider.class, method = "dynamicSQL")
    int insertSelective(T record);

    /**
     * 根据实体类中字段不为null的条件进行删除,条件全部使用=号and条件
     * 
     * @param key
     * @return
     */
    @DeleteProvider(type = SysMapperProvider.class, method = "dynamicSQL")
    int delete(T key);
  /**
     * 通过主键进行删除,这里最多只会删除一条数据 单个字段做主键时,可以直接写主键的值 联合主键时,key可以是实体类,也可以是Map
     * 
     * @param key
     * @return
     */
    @DeleteProvider(type = SysMapperProvider.class, method = "dynamicSQL")
    int deleteByPrimaryKey(Object key);

    /**
     * 根据主键进行更新,这里最多只会更新一条数据 参数为实体类
     * 
     * @param record
     * @return
     */
    @UpdateProvider(type = SysMapperProvider.class, method = "dynamicSQL")
    int updateByPrimaryKey(T record);

    /**
     * 根据主键进行更新 只会更新不是null的数据
     * 
     * @param record
     * @return
     */
    @UpdateProvider(type = SysMapperProvider.class, method = "dynamicSQL")
    int updateByPrimaryKeySelective(T record);

}

第八步:创建接口UserMapper.xml

继承Mapper接口,在这个通用的接口中定义了常用的方法,如有特殊,在这个接口中配置。

package com.supermapper.mapper;

import com.supermapper.base.mapper.SysMapper;
import com.supermapper.pojo.User;

/*
 * 注意必须继承SysMapper,不能继承Mapper,否则报错:
 *  org.apache.ibatis.binding.BindingException: Type interface com.supermapper.mapper.UserMapper is not known to the MapperRegistry.
 */
public interface UserMapper extends SysMapper<User>{
	
}

 

 

第九步:测试类,查询所有记录

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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 com.github.abel533.mapperhelper.MapperHelper;
import com.supermapper.base.mapper.SysMapper;
import com.supermapper.mapper.UserMapper;
import com.supermapper.pojo.User;


public class TestSuperMapper {
	public static void main(String[] args) throws IOException {
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sessionFactory.openSession(true);

        // 创建一个MapperHelper
        MapperHelper mapperHelper = new MapperHelper();
        // 主键自增回写方法,默认值MYSQL,详细说明请看文档
        mapperHelper.setIDENTITY("MYSQL");
        // 注册通用Mapper接口
        mapperHelper.registerMapper(SysMapper.class);
        // 配置完成后,执行下面的操作
        mapperHelper.processConfiguration(session.getConfiguration());
        // OK - mapperHelper的任务已经完成,可以不管了
        
        UserMapper mapper = session.getMapper(UserMapper.class);
		
		List<User> uList = mapper.select(null);
		for(User u : uList){
			System.out.println(u);
		}
	}
}

 

 

控制台日志

2015-07-02 15:00:12,825 [main] [com.supermapper.mapper.UserMapper.select]-[DEBUG] ==>  Preparing: SELECT UPDATED,BIRTHDAY,NAME,USER_NAME USERNAME,CREATED,SEX,PASSWORD,ID,AGE FROM t_user 
2015-07-02 15:00:12,924 [main] [com.supermapper.mapper.UserMapper.select]-[DEBUG] ==> Parameters: 
2015-07-02 15:00:13,010 [main] [com.supermapper.mapper.UserMapper.select]-[DEBUG] <==      Total: 1
User [id=1, userName=王致和, password=123456, name=纸盒, age=30, sex=false, birthday=Tue Jun 09 00:00:00 CST 2015, created=Wed Jun 10 00:00:00 CST 2015, updated=Thu Jun 11 00:00:00 CST 2015]

从日志中可以看出执行的SQL语句。我们并没有在mybatis映射文件中配置字段,它怎么知道的呢?它是通过分析pojo对象,并通过jpa注解获取了字段的名称。这样开发者的工作量大量减少,并方便维护。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值