项目总结day03

  1. 课程介绍                                     
  • 1.完成删除功能
  • 2.增加数据
  • 3.修改数据
  • 4.数据验证功能
  1. 准备按钮

 

    1. employee.jsp

<div id="tb" style="padding:5px;height:auto">
   
<!-- 这部分是加上增删改的按键:现在没有功能,我们先不管它 -->
   
<div style="margin-bottom:5px">
        <
a href="#"  data-method="add" class="easyui-linkbutton" iconCls="icon-add" plain="true">添加</a>
        <
a href="#"  data-method="edit" class="easyui-linkbutton" iconCls="icon-edit" plain="true">
修改</a>
        <
a href="#"  data-method="del" class="easyui-linkbutton" iconCls="icon-remove" plain="true">
删除</a>
    </div>
   
<!-- 这部门是查询的功能 -->
   
<div>
        <
form id="searchForm" action="/employee/download" method="post">
           
用户名: <input name="username" class="easyui-textbox" style="width:80px;height:32px">
           
邮件: <input name="email" class="easyui-textbox" style="width:80px;height:32px">
           
部门 :
            <
input  class="easyui-combobox" name="departmentId"
                   
data-options="valueField:'id',textField:'name',panelHeight:'auto',url:'/util/departmentList'">
            <
a href="#" data-method="search"  class="easyui-linkbutton" iconCls="icon-search">查找</a>
        </
form>
    </
div>
</
div>

 

    1. employee.js

var itsource={
   
//查询数据
   
search:function () {
       
//需要先引入 jquery.serializejson.js 才可以使用这个方法
       
var params = searchForm.serializeJSON();
       
employeeGrid.datagrid('load',params);
    },
   
add:function () {
     
//添加数据(弹出添加的模态框)
   
},
   
edit:function () {
      
//修改数据(弹出修改的模态框)
   
},
   
del:function () {
      
//删除数据
   
},
   
save:function () {
      
//保存数据
    
}
}

 

  1. 删除功能
    1. employee.js

var itsource={
   
//查询数据
    search:function () {
       
//需要先引入 jquery.serializejson.js 才可以使用这个方法
        var params = searchForm.serializeJSON();
       
employeeGrid.datagrid('load',params);
    },
   
add:function () {
     
//添加数据(弹出添加的模态框)
   
},
   
edit:function () {
      
//修改数据(弹出修改的模态框)
   
},
   
//删除数据
    del:function () {
       
//拿到选中的这条数据
        var row = employeeGrid.datagrid("getSelected");
       
if(row){
           
$.messager.confirm('确认框', '确定要狠心删除我么?', function(r){
               
if (r){
                   
//进行删除
                    $.get("/employee/delete",{id:row.id},function (result) {
                       
if(result.success){
                           
$('#employeeGrid').datagrid('reload');
                        }
else{
                           
//alert("删除失败");
                           
$.messager.alert('提示信息','删除失败!,原因:'+result.msg,"error");
                        }
                    })
                }
            });
        }
else{
            
$.messager.alert('提示信息','请选择一行再进行删除!','info');
        }
    },

    save:function () {
      
//保存数据
    }
}

 

 

 

    1. BaseController

public abstract class BaseController {
   
public static final String SUCCESS = "success";
}

 

    1. EmployeeController

/**
 *
返回的结果:{SUCCESS:true,msg:"原因..."}
 * @param
id
 
* @return
 
*/

@RequestMapping("/delete")
@ResponseBody
public Map delete(Long id){
    Map<String,Object> map = new HashMap<>();
    try {
        employeeService.delete(id);
        map.put(SUCCESS, true);
    } catch (Exception e) {
        e.printStackTrace();
        map.put(SUCCESS, false);
        map.put("msg", e.getMessage());
    }
    return map;
}

 

  1. 完成添加修改
    1. 准备表单
使用Easyui的dialog来完成表单弹出功能

<body>

<div id="employeeDialog" class="easyui-dialog" data-options="closed:true,modal:true" title="员工操作" style="width:400px">
    <
div style="padding:10px 60px 20px 40px">
        <
form id="employeeForm" class="easyui-form" method="post" data-options="">
            <
input type="hidden" id="employeeId" name="id" >
            <
table cellpadding="5">
                <
tr>
                    <
td>用户名:</td>
                    <
td><input class="easyui-validatebox" type="text" name="username" data-options="required:true"
                        validType="checkUsername"
                    ></input></td>
                </
tr>
                <
tr data-save="true">
                    <
td>密码:</td>
                    <
td><input id="password" class="easyui-validatebox" type="password" name="password" data-options="required:true"></input></td>
                </
tr>
                <
tr data-save="true">
                    <
td>重复密码:</td>
                    <
td><input class="easyui-validatebox" type="password" name="repassword" data-options="required:true"
                                validType="equals['password',’id’]"></input></td>
                </
tr>
                <
tr>
                    <
td>邮件:</td>
                    <
td><input class="easyui-validatebox" type="text" name="email" data-options="required:true,validType:'email'"></input></td>
                </
tr>
                <
tr>
                    <
td>年龄:</td>
                    <
td><input class="easyui-validatebox" type="text" name="age" data-options="required:true"></input></td>
                </
tr>
                <
tr>
                    <
td>部门:</td>
                    <
td>
                        <
input class="easyui-combobox" name="department.id"
                                data-options="valueField:'id',textField:'name',panelHeight:'auto',url:'/util/departmentList'">
                    </
td>
                </
tr>
            </
table>
        </
form>
        <
div style="text-align:center;padding:5px">
            <
a href="javascript:void(0)" class="easyui-linkbutton" data-method="save">提交</a>
            <
a href="javascript:void(0)" class="easyui-linkbutton" οnclick="$(‘employeeDialog’).dialog('close')">取消</a>
        </
div>
    </
div>
</
div>

 

</body>

 

 

    1. 修改加上弹出功能

employee.js代码

//验证扩展:两次数据是否一致
$.extend($.fn.validatebox.defaults.rules, {
    equals: {
        validator: function(value,param){
            return value == $(param[0]).val();
        },
        message: '两次密码匹配.'
   
}
});
//验证扩展:用户名是否可以重复使用
$.extend($.fn.validatebox.defaults.rules, {
    checkUsername: {
        validator: function(value,param){
            var employeeId = $("#employeeId").val();
            var result = $.ajax({
                type: "GET",
                url: "/employee/checkUsername",
                data:{username:value,id:employeeId},
                async: false //同步
            
}).responseText;
            return result=="true";
        },
        message: '用户名不能重复.'
   
}
});[Office1] 

var itsource={
    //查询数据
   
search:function () {
        //需要先引入 jquery.serializejson.js 才可以使用这个方法
       
var params = searchForm.serializeJSON();
        employeeGrid.datagrid('load',params);
    },
    //添加数据(弹出添加的模态框)
   
add:function () {
        //如果有data-save属性,我们把它展示出来
       
$("*[data-save]").show();
        //启动有data-save属性的input元素的验证功能
       
$("*[data-save] input").validatebox("enable");
       employeeForm.form("clear");//清除数据
        //
弹出表单窗口
       
employeeDialog.dialog("center").dialog('open');
    },
    //修改数据(弹出修改的模态框)
   
edit:function () {
        //选中了某一条数据才删除
       
var row = employeeGrid.datagrid("getSelected");
        if(row){
            //隐藏有data-save属性的元素
           
$("*[data-save]").hide();
            //禁用有data-save属性的input元素的验证功能
           
$("*[data-save] input").validatebox("disable");

            employeeForm.form("clear");//清除数据
           
employeeDialog.dialog("center").dialog('open');
            //单独解决部门的回显问题
           
if(row.department){
                row["department.id"] = row.department.id;
            }
            //为form加载数据
           
$("#employeeForm").form("load",row);
        }else{
            $.messager.alert('提示信息','请选择一行再进行修改!','info');
        }
    },

save:function () {
   
var url  = "/employee/save";
   
var id = $("#employeeId").val();
   
if(id){
       
url = "/employee/update?cmd=update";
    }
   
employeeForm.form('submit', {
       
url:url,
       
onSubmit: function(){
           
//做验证
            return $("#employeeForm").form("validate");
        },
       
success:function(data){
           
var result = JSON.parse(data);//转成相应的json数据
            if(result.success) {
               
$('#employeeGrid').datagrid('reload');
            }
else{
               
$.messager.alert('提示信息','操作失败!,原因:'+result.msg,"error");
            }

            employeeDialog.dialog('close');
        }
    })
}

    …

}

 

 

 

同步Ajax请求我们也可以用新的方案:

var isSuccess = $.util.requestAjaxBoolean('/employee/checkUsername',{username:value});

 

    1. 后台的功能支持
      1. 用户是否重复验证

EmployeeRepository

public interface EmployeeRepository extends BaseRepository<Employee,Long> {

     @Query("select o from Employee o where o.username=?1")
     Employee findByUsername(String username);
}

 

IEmployeeService

public interface IEmployeeService extends IBaseService<Employee,Long> {

    /**
     *
如果根据用户名查询到了员工 -> 返回false(代表这个用户已经存在)
     * @param username
    
* @return
    
*/
   
boolean checkUsername(String username);

}

 

EmployeeServiceImpl

@Service
public class EmployeeServiceImpl extends BaseServiceImpl<Employee,Long> implements IEmployeeService {

    @Autowired
   
private EmployeeRepository employeeRepository;

    @Override
   
public boolean checkUsername(String username) {
        return employeeRepository.findByUsername(username)==null;
    }
}

 

EmployeeController

@RequestMapping("/checkUsername")
@ResponseBody
public Boolean checkUsername(Long id,String username){
    if(id!=null) {
        //1.根据id拿到对应的员工
       
Employee dbEmp = employeeService.findOne(id);
        //2.判断数据库的员工的username与传过来的username是否相等
       
if(username.equals(dbEmp.getUsername())){
            return true; //相同代表没有修改
       
}
    }
    //正常验证
   
return employeeService.checkUsername(username);
}

 

      1. 完成基本的添加与修改

//添加
@RequestMapping("/save")
@ResponseBody
public Map<String,Object> save(Employee employee){
    return saveOrUpdate(employee);
}

//修改
@RequestMapping("/update")
@ResponseBody
public Map<String,Object> update(Employee employee){
    return saveOrUpdate(employee);
}

//添加或者修改
private Map<String,Object> saveOrUpdate(Employee employee){
    Map<String,Object> map = new HashMap<>();
    try {
        employeeService.save(employee);
        map.put(SUCCESS, true);
    } catch (Exception e) {
        e.printStackTrace();
        map.put(SUCCESS, false);
        map.put("msg", e.getMessage());
    }
    return map;
}

 

 

  1. 数据丢失问题

这里我们出现一个新的问题,当我们完成修改之后,密码就消失不见了,这里咱们有三个解决方案

    1. 三种解决方案

在这里,咱们有三个解决方案:

方案一:隐藏要传递的值(只隐藏,但是数据还是需要传递,这和第一个项目是同相同的方案)

这个方案的优点是简单易理解,缺点是如果字段过多,代码量会比较大,另外这种方案的安全性确实是有一些低!

方案二:在JPA的相应字段上加标签:

@Column(updatable = false)

private String password;

   这个方案也比较简单,但是如果你需要修改这个字段的时候就比较麻烦!

 

方案三:先查询数据库,获取持久状态的对象,然后把页面的数据set到对象里面

(这种方案也是用得比较多的一种方案)

Employee tempEmployee = employeeService.get(employee.getId());

//需要修改的值就从页面里面的employee放入tempEmployee

tempEmployee.setUsername(employee.getUsername());

employeeService.save(tempEmployee);

 

 

    1. SpringMVC之@ModelAttribute

咱们如果自己要完成所有数据查询,再进行相应的字段拷备覆盖,还是比较麻烦的。大家如果反射与JavaBean部分学得比较透彻的话可以去进行相应的尝试(主要就是完成一个属性拷备功能)。

  而在SpringMVC中,有一个ModelAttribute标签,可以助我们完成这个功能!

  接下来,我们就来学习一下这个标签的作用!!!

 

      1. ModelAttribute的作用

运用在方法上,会在每一个@RequestMapping标注的方法前执行,如果有返回值,则自动将该返回值加入到ModelMap中;

运用在参数上,会将客户端传递过来的参数按名称注入到指定对象中,并且会将这个对象自动加入ModelMap中,便于View层使用;

  

   咱们先不管返回值,我们在EmployeeController类中加一个相应的方法,看是否要执行所有代码之前都会先执行这个方法!!!

@ModelAttribute

public void beforeEdit(){

    System.out.println("执行就执行,我不怕的!!!");

}

  

      1. 传参与解决方案

这时候,我们可以看到这个类所有的方法(通过路@RequestMapping)访问之前都会先访问这个方法。接下来,我们可以看一下这个是怎么传值的。

在下面的传值代码中我们也解决了数据丢失的问题。

//这里准备一个方法,所有方法执行前都会执行它

@ModelAttribute("editEmployee")

public Employee beforeEdit(Long id){

    if(id!=null){

        Employee employee = employeeService.findOne(id);

        return employee;

    }

    return  null;

}

 

@RequestMapping("/save")

@ResponseBody

public Map<String,Object> save(Employee employee){

    return saveOrUpdate(employee);

}

 

@RequestMapping("/update")

@ResponseBody

public Map<String,Object> update(@ModelAttribute("editEmployee")Employee employee){

    return saveOrUpdate(employee);

 

}

 

 

      1. 只让修改功能去查询

大家思考一下,咱们的现在所有方法都会进入到beforeEdit中,那么只要传过来id,就会执行这个方法,这个对效率是会有影响的。所以我们可以对代码进行修改,让只有修改功能才去执行这个查询代码!!

employee.js -> 修改时传一个cmd=update

var itsource={
   

    //保存数据
   
save:function () {
       
var url  = "/employee/save";
       
var id = $("#employeeId").val();
       
if(id){
           
url = "/employee/update?cmd=update";
        }
       
employeeForm.form('submit', {
           
url:url,
           
onSubmit: function(){
                
//做验证
               
return $("#employeeForm").form("validate");
            },
           
success:function(data){
               
$('#employeeGrid').datagrid('reload');
               
employeeDialog.dialog('close');
            }
        })
    }
}

 

EmployeeController进行判断

/**
 *
特性:在执行相应方法之前都会先执行这个方法
 */

@ModelAttribute("editEmployee")
public Employee beforeEdit(Long id, String cmd){
    //id的时候-> 修改功能
   
if(id!=null && "update".equals(cmd)) {
        Employee employee = employeeService.findOne(id);
        return employee;
    }
    return null;
}

 

      1. 部门修改的n-to-n

这时候大家继续开发会发现一个问题,在修改部门的时候,会出现n-to-n错误,就是咱们修改的时候也在相应的修改它的部门(这时候部门是一个持久化对象,它的id是不允许进行修改的。)

 报错如下:

 

解决方案(在获到员工的时候把部门设置为空):

/**
 *
特性:在执行相应方法之前都会先执行这个方法
 */

@ModelAttribute("editEmployee")
public Employee beforeEdit(Long id, String cmd){
    //id的时候-> 修改功能
   
if(id!=null && "update".equals(cmd)) {
        Employee employee = employeeService.findOne(id);
        //把这个要修改的关联对象设置为null,可以解决n-to-n的问题
       
employee.setDepartment(null);
        return employee;
    }
    return null;
}

 

转载于:https://my.oschina.net/u/4108101/blog/3070816

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
GeoPandas是一个开源的Python库,旨在简化地理空间数据的处理和分析。它结合了Pandas和Shapely的能力,为Python用户提供了一个强大而灵活的工具来处理地理空间数据。以下是关于GeoPandas的详细介绍: 一、GeoPandas的基本概念 1. 定义 GeoPandas是建立在Pandas和Shapely之上的一个Python库,用于处理和分析地理空间数据。 它扩展了Pandas的DataFrame和Series数据结构,允许在其中存储和操作地理空间几何图形。 2. 核心数据结构 GeoDataFrame:GeoPandas的核心数据结构,是Pandas DataFrame的扩展。它包含一个或多个列,其中至少一列是几何列(geometry column),用于存储地理空间几何图形(如点、线、多边形等)。 GeoSeries:GeoPandas中的另一个重要数据结构,类似于Pandas的Series,但用于存储几何图形序列。 二、GeoPandas的功能特性 1. 读取和写入多种地理空间数据格式 GeoPandas支持读取和写入多种常见的地理空间数据格式,包括Shapefile、GeoJSON、PostGIS、KML等。这使得用户可以轻松地从各种数据源中加载地理空间数据,并将处理后的数据保存为所需的格式。 2. 地理空间几何图形的创建、编辑和分析 GeoPandas允许用户创建、编辑和分析地理空间几何图形,包括点、线、多边形等。它提供了丰富的空间操作函数,如缓冲区分析、交集、并集、差集等,使得用户可以方便地进行地理空间数据分析。 3. 数据可视化 GeoPandas内置了数据可视化功能,可以绘制地理空间数据的地图。用户可以使用matplotlib等库来进一步定制地图的样式和布局。 4. 空间连接和空间索引 GeoPandas支持空间连接操作,可以将两个GeoDataFrame按照空间关系(如相交、包含等)进行连接。此外,它还支持空间索引,可以提高地理空间数据查询的效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值